Daily bump.
[official-gcc.git] / gcc / ada / s-tasdeb.adb
blob9709e341922e5bf83a4d8c75256426e510dcf14e
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
4 -- --
5 -- S Y S T E M . T A S K I N G . D E B U G --
6 -- --
7 -- B o d y --
8 -- --
9 -- $Revision: 1.3 $
10 -- --
11 -- Copyright (C) 1997-2001 Free Software Foundation, Inc. --
12 -- --
13 -- GNARL is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNARL; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
23 -- --
24 -- As a special exception, if other files instantiate generics from this --
25 -- unit, or you link this unit with other files to produce an executable, --
26 -- this unit does not by itself cause the resulting executable to be --
27 -- covered by the GNU General Public License. This exception does not --
28 -- however invalidate any other reasons why the executable file might be --
29 -- covered by the GNU Public License. --
30 -- --
31 -- GNARL was developed by the GNARL team at Florida State University. --
32 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 -- --
34 ------------------------------------------------------------------------------
36 -- This package encapsulates all direct interfaces to task debugging services
37 -- that are needed by gdb with gnat mode (1.13 and higher)
39 -- Note : This file *must* be compiled with debugging information
41 -- Do not add any dependency to GNARL packages since this package is used
42 -- in both normal and resticted (ravenscar) environments.
44 with System.Task_Info,
45 System.Task_Primitives.Operations,
46 Unchecked_Conversion;
48 package body System.Tasking.Debug is
50 use Interfaces.C;
52 package STPO renames System.Task_Primitives.Operations;
54 type Integer_Address is mod 2 ** Standard'Address_Size;
55 type Integer_Address_Ptr is access all Integer_Address;
57 function "+" is new
58 Unchecked_Conversion (System.Address, Integer_Address_Ptr);
60 function "+" is new
61 Unchecked_Conversion (Task_ID, Integer_Address);
63 Hex_Address_Width : constant := (Standard'Address_Size / 4);
65 Zero_Pos : constant := Character'Pos ('0');
67 Hex_Digits : constant array (0 .. Integer_Address'(15)) of Character :=
68 "0123456789abcdef";
70 subtype Buf_Range is Integer range 1 .. 80;
71 type Buf_Array is array (Buf_Range) of aliased Character;
73 type Buffer is record
74 Next : Buf_Range := Buf_Range'First;
75 Chars : Buf_Array := (Buf_Range => ' ');
76 end record;
78 type Buffer_Ptr is access all Buffer;
80 type Trace_Flag_Set is array (Character) of Boolean;
82 Trace_On : Trace_Flag_Set := ('A' .. 'Z' => False, others => True);
84 -----------------------
85 -- Local Subprograms --
86 -----------------------
88 procedure Put
89 (T : ST.Task_ID;
90 Width : Integer;
91 Buffer : Buffer_Ptr);
92 -- Put TCB pointer T, (coded in hexadecimal) into Buffer
93 -- right-justified in Width characters.
95 procedure Put
96 (N : Integer_Address;
97 Width : Integer;
98 Buffer : Buffer_Ptr);
99 -- Put N (coded in decimal) into Buf right-justified in Width
100 -- characters starting at Buf (Next).
102 procedure Put
103 (S : String;
104 Width : Integer;
105 Buffer : Buffer_Ptr);
106 -- Put string S into Buf left-justified in Width characters
107 -- starting with space in Buf (Next), truncated as necessary.
109 procedure Put
110 (C : Character;
111 Buffer : Buffer_Ptr);
112 -- Put character C into Buf, left-justified, starting at Buf (Next)
114 procedure Space (Buffer : Buffer_Ptr);
115 -- Increment Next, resulting in a space
117 procedure Space
118 (N : Integer;
119 Buffer : Buffer_Ptr);
120 -- Increment Next by N, resulting in N spaces
122 procedure Clear (Buffer : Buffer_Ptr);
123 -- Clear Buf and reset Next to 1
125 procedure Write_Buf (Buffer : Buffer_Ptr);
126 -- Write contents of Buf (1 .. Next) to standard output
128 -----------
129 -- Clear --
130 -----------
132 procedure Clear (Buffer : Buffer_Ptr) is
133 Next : Buf_Range renames Buffer.Next;
134 Buf : Buf_Array renames Buffer.Chars;
136 begin
137 Buf := (Buf_Range => ' ');
138 Next := 1;
139 end Clear;
141 -----------
142 -- Image --
143 -----------
145 function Image (T : ST.Task_ID) return String is
146 Buf : aliased Buffer;
147 Result : String (1 .. Hex_Address_Width + 21);
149 use type System.Task_Info.Task_Image_Type;
151 begin
152 Clear (Buf'Unchecked_Access);
153 Put (T, Hex_Address_Width, Buf'Unchecked_Access);
154 Put (':', Buf'Unchecked_Access);
155 Put (Integer_Address (T.Serial_Number), 4, Buf'Unchecked_Access);
156 Space (Buf'Unchecked_Access);
158 if T.Common.Task_Image = null then
159 Put ("", 15, Buf'Unchecked_Access);
160 else
161 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
162 end if;
164 for J in Result'Range loop
165 Result (J) := Buf.Chars (J);
166 end loop;
168 return Result;
169 end Image;
171 ----------------
172 -- List_Tasks --
173 ----------------
175 procedure List_Tasks is
176 C : ST.Task_ID;
178 begin
179 Print_Task_Info_Header;
180 C := All_Tasks_List;
182 while C /= null loop
183 Print_Task_Info (C);
184 C := C.Common.All_Tasks_Link;
185 end loop;
186 end List_Tasks;
188 -----------------------
189 -- Print_Accept_Info --
190 -----------------------
192 procedure Print_Accept_Info (T : ST.Task_ID) is
193 Buf : aliased Buffer;
195 begin
196 if T.Open_Accepts = null then
197 return;
198 end if;
200 Clear (Buf'Unchecked_Access);
201 Space (10, Buf'Unchecked_Access);
202 Put ("accepting:", 11, Buf'Unchecked_Access);
204 for J in T.Open_Accepts.all'Range loop
205 Put (Integer_Address (T.Open_Accepts (J).S), 3, Buf'Unchecked_Access);
206 end loop;
208 Write_Buf (Buf'Unchecked_Access);
209 end Print_Accept_Info;
211 ------------------------
212 -- Print_Current_Task --
213 ------------------------
215 procedure Print_Current_Task is
216 begin
217 Print_Task_Info (STPO.Self);
218 end Print_Current_Task;
220 ---------------------
221 -- Print_Task_Info --
222 ---------------------
224 procedure Print_Task_Info (T : ST.Task_ID) is
225 Entry_Call : Entry_Call_Link;
226 Buf : aliased Buffer;
228 use type System.Task_Info.Task_Image_Type;
230 begin
231 Clear (Buf'Unchecked_Access);
232 Put (T, Hex_Address_Width, Buf'Unchecked_Access);
233 Put (':', Buf'Unchecked_Access);
234 Put (' ', Buf'Unchecked_Access);
235 Put (':', Buf'Unchecked_Access);
237 if T = null then
238 Put (" null task", 10, Buf'Unchecked_Access);
239 Write_Buf (Buf'Unchecked_Access);
240 return;
241 end if;
243 Put (Integer_Address (T.Serial_Number), 4, Buf'Unchecked_Access);
244 Space (Buf'Unchecked_Access);
246 if T.Common.Task_Image = null then
247 Put ("", 15, Buf'Unchecked_Access);
248 else
249 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
250 end if;
252 Space (Buf'Unchecked_Access);
253 Put (Task_States'Image (T.Common.State), 10, Buf'Unchecked_Access);
254 Space (Buf'Unchecked_Access);
256 if T.Callable then
257 Put ('C', Buf'Unchecked_Access);
258 else
259 Space (Buf'Unchecked_Access);
260 end if;
262 if T.Open_Accepts /= null then
263 Put ('A', Buf'Unchecked_Access);
264 else
265 Space (Buf'Unchecked_Access);
266 end if;
268 if T.Common.Call /= null then
269 Put ('C', Buf'Unchecked_Access);
270 else
271 Space (Buf'Unchecked_Access);
272 end if;
274 if T.Terminate_Alternative then
275 Put ('T', Buf'Unchecked_Access);
276 else
277 Space (Buf'Unchecked_Access);
278 end if;
280 if T.Aborting then
281 Put ('A', Buf'Unchecked_Access);
282 else
283 Space (Buf'Unchecked_Access);
284 end if;
286 if T.Deferral_Level = 0 then
287 Space (3, Buf'Unchecked_Access);
288 else
289 Put ('D', Buf'Unchecked_Access);
290 if T.Deferral_Level < 0 then
291 Put ("<0", 2, Buf'Unchecked_Access);
292 elsif T.Deferral_Level > 1 then
293 Put (Integer_Address (T.Deferral_Level), 2, Buf'Unchecked_Access);
294 else
295 Space (2, Buf'Unchecked_Access);
296 end if;
297 end if;
299 Space (Buf'Unchecked_Access);
300 Put (Integer_Address (T.Master_of_Task), 1, Buf'Unchecked_Access);
301 Space (Buf'Unchecked_Access);
302 Put (Integer_Address (T.Master_Within), 1, Buf'Unchecked_Access);
303 Put (',', Buf'Unchecked_Access);
304 Space (Buf'Unchecked_Access);
305 Put (Integer_Address (T.Awake_Count), 1, Buf'Unchecked_Access);
306 Space (Buf'Unchecked_Access);
307 Put (Integer_Address (T.Alive_Count), 1, Buf'Unchecked_Access);
308 Put (',', Buf'Unchecked_Access);
309 Space (Buf'Unchecked_Access);
310 Put (Integer_Address (T.ATC_Nesting_Level), 1, Buf'Unchecked_Access);
311 Space (Buf'Unchecked_Access);
312 Put (Integer_Address (T.Pending_ATC_Level), 1, Buf'Unchecked_Access);
313 Put (',', Buf'Unchecked_Access);
314 Space (Buf'Unchecked_Access);
315 Put (Integer_Address (T.Common.Wait_Count), 1, Buf'Unchecked_Access);
316 Put (',', Buf'Unchecked_Access);
317 Space (Buf'Unchecked_Access);
318 Put (Integer_Address (T.User_State), 1, Buf'Unchecked_Access);
319 Write_Buf (Buf'Unchecked_Access);
321 if T.Common.Call /= null then
322 Entry_Call := T.Common.Call;
323 Clear (Buf'Unchecked_Access);
324 Space (10, Buf'Unchecked_Access);
325 Put ("serving:", 8, Buf'Unchecked_Access);
327 while Entry_Call /= null loop
328 Put (Integer_Address
329 (Entry_Call.Self.Serial_Number), 5, Buf'Unchecked_Access);
330 Entry_Call := Entry_Call.Acceptor_Prev_Call;
331 end loop;
333 Write_Buf (Buf'Unchecked_Access);
334 end if;
336 Print_Accept_Info (T);
337 end Print_Task_Info;
339 ----------------------------
340 -- Print_Task_Info_Header --
341 ----------------------------
343 procedure Print_Task_Info_Header is
344 Buf : aliased Buffer;
346 begin
347 Clear (Buf'Unchecked_Access);
348 Put ("TASK_ID", Hex_Address_Width, Buf'Unchecked_Access);
349 Put (':', Buf'Unchecked_Access);
350 Put ('F', Buf'Unchecked_Access);
351 Put (':', Buf'Unchecked_Access);
352 Put ("SERIAL_NUMBER", 4, Buf'Unchecked_Access);
353 Space (Buf'Unchecked_Access);
354 Put (" NAME", 15, Buf'Unchecked_Access);
355 Put (" STATE", 10, Buf'Unchecked_Access);
356 Space (11, Buf'Unchecked_Access);
357 Put ("MAST", 5, Buf'Unchecked_Access);
358 Put ("AWAK", 5, Buf'Unchecked_Access);
359 Put ("ATC", 5, Buf'Unchecked_Access);
360 Put ("WT", 3, Buf'Unchecked_Access);
361 Put ("DBG", 3, Buf'Unchecked_Access);
362 Write_Buf (Buf'Unchecked_Access);
363 end Print_Task_Info_Header;
365 ---------
366 -- Put --
367 ---------
369 procedure Put
370 (T : ST.Task_ID;
371 Width : Integer;
372 Buffer : Buffer_Ptr)
374 J : Integer;
375 X : Integer_Address := +T;
376 Next : Buf_Range renames Buffer.Next;
377 Buf : Buf_Array renames Buffer.Chars;
378 First : constant Integer := Next;
379 Wdth : Integer := Width;
381 begin
382 if Wdth > Buf'Last - Next then
383 Wdth := Buf'Last - Next;
384 end if;
386 J := Next + (Wdth - 1);
388 if X = 0 then
389 Buf (J) := '0';
391 else
392 while X > 0 loop
393 Buf (J) := Hex_Digits (X rem 16);
394 J := J - 1;
395 X := X / 16;
397 -- Check for overflow
399 if J < First and then X > 0 then
400 Buf (J + 1) := '*';
401 exit;
402 end if;
404 end loop;
405 end if;
407 Next := Next + Wdth;
408 end Put;
410 procedure Put
411 (N : Integer_Address;
412 Width : Integer;
413 Buffer : Buffer_Ptr)
415 J : Integer;
416 X : Integer_Address := N;
417 Next : Buf_Range renames Buffer.Next;
418 Buf : Buf_Array renames Buffer.Chars;
419 First : constant Integer := Next;
420 Wdth : Integer := Width;
422 begin
423 if Wdth > Buf'Last - Next then
424 Wdth := Buf'Last - Next;
425 end if;
427 J := Next + (Wdth - 1);
429 if N = 0 then
430 Buf (J) := '0';
432 else
433 while X > 0 loop
434 Buf (J) := Hex_Digits (X rem 10);
435 J := J - 1;
436 X := X / 10;
438 -- Check for overflow
440 if J < First and then X > 0 then
441 Buf (J + 1) := '*';
442 exit;
443 end if;
444 end loop;
445 end if;
447 Next := Next + Wdth;
448 end Put;
450 procedure Put
451 (S : String;
452 Width : Integer;
453 Buffer : Buffer_Ptr)
455 Next : Buf_Range renames Buffer.Next;
456 Buf : Buf_Array renames Buffer.Chars;
457 Bound : constant Integer := Integer'Min (Next + Width, Buf'Last);
458 J : Integer := Next;
460 begin
461 for K in S'Range loop
463 -- Check overflow
465 if J >= Bound then
466 Buf (J - 1) := '*';
467 exit;
468 end if;
470 Buf (J) := S (K);
471 J := J + 1;
472 end loop;
474 Next := Bound;
475 end Put;
477 procedure Put
478 (C : Character;
479 Buffer : Buffer_Ptr)
481 Next : Buf_Range renames Buffer.Next;
482 Buf : Buf_Array renames Buffer.Chars;
484 begin
485 if Next >= Buf'Last then
486 Buf (Next) := '*';
487 else Buf (Next) := C;
488 Next := Next + 1;
489 end if;
490 end Put;
492 ----------------------
493 -- Resume_All_Tasks --
494 ----------------------
496 procedure Resume_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
497 C : ST.Task_ID;
498 R : Boolean;
500 begin
501 STPO.Lock_All_Tasks_List;
502 C := All_Tasks_List;
504 while C /= null loop
505 R := STPO.Resume_Task (C, Thread_Self);
506 C := C.Common.All_Tasks_Link;
507 end loop;
509 STPO.Unlock_All_Tasks_List;
510 end Resume_All_Tasks;
512 ----------
513 -- Self --
514 ----------
516 function Self return Task_ID is
517 begin
518 return STPO.Self;
519 end Self;
521 ---------------
522 -- Set_Trace --
523 ---------------
525 procedure Set_Trace
526 (Flag : Character;
527 Value : Boolean := True)
529 begin
530 Trace_On (Flag) := Value;
531 end Set_Trace;
533 --------------------
534 -- Set_User_State --
535 --------------------
537 procedure Set_User_State (Value : Integer) is
538 begin
539 STPO.Self.User_State := Value;
540 end Set_User_State;
542 -----------
543 -- Space --
544 -----------
546 procedure Space (Buffer : Buffer_Ptr) is
547 Next : Buf_Range renames Buffer.Next;
548 Buf : Buf_Array renames Buffer.Chars;
550 begin
551 if Next >= Buf'Last then
552 Buf (Next) := '*';
553 else
554 Next := Next + 1;
555 end if;
556 end Space;
558 procedure Space
559 (N : Integer;
560 Buffer : Buffer_Ptr)
562 Next : Buf_Range renames Buffer.Next;
563 Buf : Buf_Array renames Buffer.Chars;
565 begin
566 if Next + N > Buf'Last then
567 Buf (Next) := '*';
568 else
569 Next := Next + N;
570 end if;
571 end Space;
573 -----------------------
574 -- Suspend_All_Tasks --
575 -----------------------
577 procedure Suspend_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
578 C : ST.Task_ID;
579 R : Boolean;
581 begin
582 STPO.Lock_All_Tasks_List;
583 C := All_Tasks_List;
585 while C /= null loop
586 R := STPO.Suspend_Task (C, Thread_Self);
587 C := C.Common.All_Tasks_Link;
588 end loop;
590 STPO.Unlock_All_Tasks_List;
591 end Suspend_All_Tasks;
593 ------------------------
594 -- Task_Creation_Hook --
595 ------------------------
597 procedure Task_Creation_Hook (Thread : OS_Interface.Thread_Id) is
598 pragma Inspection_Point (Thread);
599 -- gdb needs to access the thread parameter in order to implement
600 -- the multitask mode under VxWorks.
602 begin
603 null;
604 end Task_Creation_Hook;
606 ---------------------------
607 -- Task_Termination_Hook --
608 ---------------------------
610 procedure Task_Termination_Hook is
611 begin
612 null;
613 end Task_Termination_Hook;
615 -----------
616 -- Trace --
617 -----------
619 procedure Trace
620 (Self_ID : ST.Task_ID;
621 Msg : String;
622 Other_ID : ST.Task_ID;
623 Flag : Character)
625 Buf : aliased Buffer;
626 use type System.Task_Info.Task_Image_Type;
628 begin
629 if Trace_On (Flag) then
630 Clear (Buf'Unchecked_Access);
631 Put (Self_ID, Hex_Address_Width, Buf'Unchecked_Access);
632 Put (':', Buf'Unchecked_Access);
633 Put (Flag, Buf'Unchecked_Access);
634 Put (':', Buf'Unchecked_Access);
636 (Integer_Address (Self_ID.Serial_Number),
637 4, Buf'Unchecked_Access);
638 Space (Buf'Unchecked_Access);
640 if Self_ID.Common.Task_Image = null then
641 Put ("", 15, Buf'Unchecked_Access);
642 else
643 Put (Self_ID.Common.Task_Image.all, 15, Buf'Unchecked_Access);
644 end if;
646 Space (Buf'Unchecked_Access);
648 if Other_ID /= null then
650 (Integer_Address (Other_ID.Serial_Number),
651 4, Buf'Unchecked_Access);
652 Space (Buf'Unchecked_Access);
653 end if;
655 Put (Msg, Buf.Chars'Last - Buf.Next + 1, Buf'Unchecked_Access);
656 Write_Buf (Buf'Unchecked_Access);
657 end if;
658 end Trace;
660 procedure Trace
661 (Self_ID : ST.Task_ID;
662 Msg : String;
663 Flag : Character)
665 begin
666 Trace (Self_ID, Msg, null, Flag);
667 end Trace;
669 procedure Trace
670 (Msg : String;
671 Flag : Character)
673 Self_ID : constant ST.Task_ID := STPO.Self;
675 begin
676 Trace (Self_ID, Msg, null, Flag);
677 end Trace;
679 procedure Trace
680 (Msg : String;
681 Other_ID : ST.Task_ID;
682 Flag : Character)
684 Self_ID : constant ST.Task_ID := STPO.Self;
686 begin
687 Trace (Self_ID, Msg, null, Flag);
688 end Trace;
690 ---------------
691 -- Write_Buf --
692 ---------------
694 procedure Write_Buf (Buffer : Buffer_Ptr) is
695 Next : Buf_Range renames Buffer.Next;
696 Buf : Buf_Array renames Buffer.Chars;
698 procedure put_char (C : Integer);
699 pragma Import (C, put_char, "put_char");
701 begin
702 for J in 1 .. Next - 1 loop
703 put_char (Character'Pos (Buf (J)));
704 end loop;
706 put_char (Character'Pos (ASCII.LF));
707 end Write_Buf;
709 end System.Tasking.Debug;