PR c++/11509
[official-gcc.git] / gcc / ada / s-tasdeb.adb
blobc437117bc47c80d2a2eacfa707e5417edd27d471
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 -- Copyright (C) 1997-2002 Free Software Foundation, Inc. --
10 -- --
11 -- GNARL is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNARL; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- GNARL was developed by the GNARL team at Florida State University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 -- This package encapsulates all direct interfaces to task debugging services
35 -- that are needed by gdb with gnat mode (1.13 and higher)
37 -- Note : This file *must* be compiled with debugging information
39 -- Do not add any dependency to GNARL packages since this package is used
40 -- in both normal and restricted (ravenscar) environments.
42 with System.Task_Info,
43 System.Task_Primitives.Operations,
44 Unchecked_Conversion;
46 package body System.Tasking.Debug is
48 use Interfaces.C;
50 package STPO renames System.Task_Primitives.Operations;
52 type Integer_Address is mod 2 ** Standard'Address_Size;
54 function "+" is new
55 Unchecked_Conversion (Task_ID, Integer_Address);
57 Hex_Address_Width : constant := (Standard'Address_Size / 4);
59 Hex_Digits : constant array (0 .. Integer_Address'(15)) of Character :=
60 "0123456789abcdef";
62 subtype Buf_Range is Integer range 1 .. 80;
63 type Buf_Array is array (Buf_Range) of aliased Character;
65 type Buffer is record
66 Next : Buf_Range := Buf_Range'First;
67 Chars : Buf_Array := (Buf_Range => ' ');
68 end record;
70 type Buffer_Ptr is access all Buffer;
72 type Trace_Flag_Set is array (Character) of Boolean;
74 Trace_On : Trace_Flag_Set := ('A' .. 'Z' => False, others => True);
76 -----------------------
77 -- Local Subprograms --
78 -----------------------
80 procedure Put
81 (T : ST.Task_ID;
82 Width : Integer;
83 Buffer : Buffer_Ptr);
84 -- Put TCB pointer T, (coded in hexadecimal) into Buffer
85 -- right-justified in Width characters.
87 procedure Put
88 (N : Integer_Address;
89 Width : Integer;
90 Buffer : Buffer_Ptr);
91 -- Put N (coded in decimal) into Buf right-justified in Width
92 -- characters starting at Buf (Next).
94 procedure Put
95 (S : String;
96 Width : Integer;
97 Buffer : Buffer_Ptr);
98 -- Put string S into Buf left-justified in Width characters
99 -- starting with space in Buf (Next), truncated as necessary.
101 procedure Put
102 (C : Character;
103 Buffer : Buffer_Ptr);
104 -- Put character C into Buf, left-justified, starting at Buf (Next)
106 procedure Space (Buffer : Buffer_Ptr);
107 -- Increment Next, resulting in a space
109 procedure Space
110 (N : Integer;
111 Buffer : Buffer_Ptr);
112 -- Increment Next by N, resulting in N spaces
114 procedure Clear (Buffer : Buffer_Ptr);
115 -- Clear Buf and reset Next to 1
117 procedure Write_Buf (Buffer : Buffer_Ptr);
118 -- Write contents of Buf (1 .. Next) to standard output
120 -----------
121 -- Clear --
122 -----------
124 procedure Clear (Buffer : Buffer_Ptr) is
125 Next : Buf_Range renames Buffer.Next;
126 Buf : Buf_Array renames Buffer.Chars;
128 begin
129 Buf := (Buf_Range => ' ');
130 Next := 1;
131 end Clear;
133 -----------
134 -- Image --
135 -----------
137 function Image (T : ST.Task_ID) return String is
138 Buf : aliased Buffer;
139 Result : String (1 .. Hex_Address_Width + 21);
141 use type System.Task_Info.Task_Image_Type;
143 begin
144 Clear (Buf'Unchecked_Access);
145 Put (T, Hex_Address_Width, Buf'Unchecked_Access);
146 Put (':', Buf'Unchecked_Access);
147 Put (Integer_Address (T.Serial_Number), 4, Buf'Unchecked_Access);
148 Space (Buf'Unchecked_Access);
150 if T.Common.Task_Image = null then
151 Put ("", 15, Buf'Unchecked_Access);
152 else
153 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
154 end if;
156 for J in Result'Range loop
157 Result (J) := Buf.Chars (J);
158 end loop;
160 return Result;
161 end Image;
163 ----------------
164 -- List_Tasks --
165 ----------------
167 procedure List_Tasks is
168 C : ST.Task_ID;
170 begin
171 Print_Task_Info_Header;
172 C := All_Tasks_List;
174 while C /= null loop
175 Print_Task_Info (C);
176 C := C.Common.All_Tasks_Link;
177 end loop;
178 end List_Tasks;
180 -----------------------
181 -- Print_Accept_Info --
182 -----------------------
184 procedure Print_Accept_Info (T : ST.Task_ID) is
185 Buf : aliased Buffer;
187 begin
188 if T.Open_Accepts = null then
189 return;
190 end if;
192 Clear (Buf'Unchecked_Access);
193 Space (10, Buf'Unchecked_Access);
194 Put ("accepting:", 11, Buf'Unchecked_Access);
196 for J in T.Open_Accepts.all'Range loop
197 Put (Integer_Address (T.Open_Accepts (J).S), 3, Buf'Unchecked_Access);
198 end loop;
200 Write_Buf (Buf'Unchecked_Access);
201 end Print_Accept_Info;
203 ------------------------
204 -- Print_Current_Task --
205 ------------------------
207 procedure Print_Current_Task is
208 begin
209 Print_Task_Info (STPO.Self);
210 end Print_Current_Task;
212 ---------------------
213 -- Print_Task_Info --
214 ---------------------
216 procedure Print_Task_Info (T : ST.Task_ID) is
217 Entry_Call : Entry_Call_Link;
218 Buf : aliased Buffer;
220 use type System.Task_Info.Task_Image_Type;
222 begin
223 Clear (Buf'Unchecked_Access);
224 Put (T, Hex_Address_Width, Buf'Unchecked_Access);
225 Put (':', Buf'Unchecked_Access);
226 Put (' ', Buf'Unchecked_Access);
227 Put (':', Buf'Unchecked_Access);
229 if T = null then
230 Put (" null task", 10, Buf'Unchecked_Access);
231 Write_Buf (Buf'Unchecked_Access);
232 return;
233 end if;
235 Put (Integer_Address (T.Serial_Number), 4, Buf'Unchecked_Access);
236 Space (Buf'Unchecked_Access);
238 if T.Common.Task_Image = null then
239 Put ("", 15, Buf'Unchecked_Access);
240 else
241 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
242 end if;
244 Space (Buf'Unchecked_Access);
245 Put (Task_States'Image (T.Common.State), 10, Buf'Unchecked_Access);
246 Space (Buf'Unchecked_Access);
248 if T.Callable then
249 Put ('C', Buf'Unchecked_Access);
250 else
251 Space (Buf'Unchecked_Access);
252 end if;
254 if T.Open_Accepts /= null then
255 Put ('A', Buf'Unchecked_Access);
256 else
257 Space (Buf'Unchecked_Access);
258 end if;
260 if T.Common.Call /= null then
261 Put ('C', Buf'Unchecked_Access);
262 else
263 Space (Buf'Unchecked_Access);
264 end if;
266 if T.Terminate_Alternative then
267 Put ('T', Buf'Unchecked_Access);
268 else
269 Space (Buf'Unchecked_Access);
270 end if;
272 if T.Aborting then
273 Put ('A', Buf'Unchecked_Access);
274 else
275 Space (Buf'Unchecked_Access);
276 end if;
278 if T.Deferral_Level = 0 then
279 Space (3, Buf'Unchecked_Access);
280 else
281 Put ('D', Buf'Unchecked_Access);
282 if T.Deferral_Level < 0 then
283 Put ("<0", 2, Buf'Unchecked_Access);
284 elsif T.Deferral_Level > 1 then
285 Put (Integer_Address (T.Deferral_Level), 2, Buf'Unchecked_Access);
286 else
287 Space (2, Buf'Unchecked_Access);
288 end if;
289 end if;
291 Space (Buf'Unchecked_Access);
292 Put (Integer_Address (T.Master_of_Task), 1, Buf'Unchecked_Access);
293 Space (Buf'Unchecked_Access);
294 Put (Integer_Address (T.Master_Within), 1, Buf'Unchecked_Access);
295 Put (',', Buf'Unchecked_Access);
296 Space (Buf'Unchecked_Access);
297 Put (Integer_Address (T.Awake_Count), 1, Buf'Unchecked_Access);
298 Space (Buf'Unchecked_Access);
299 Put (Integer_Address (T.Alive_Count), 1, Buf'Unchecked_Access);
300 Put (',', Buf'Unchecked_Access);
301 Space (Buf'Unchecked_Access);
302 Put (Integer_Address (T.ATC_Nesting_Level), 1, Buf'Unchecked_Access);
303 Space (Buf'Unchecked_Access);
304 Put (Integer_Address (T.Pending_ATC_Level), 1, Buf'Unchecked_Access);
305 Put (',', Buf'Unchecked_Access);
306 Space (Buf'Unchecked_Access);
307 Put (Integer_Address (T.Common.Wait_Count), 1, Buf'Unchecked_Access);
308 Put (',', Buf'Unchecked_Access);
309 Space (Buf'Unchecked_Access);
310 Put (Integer_Address (T.User_State), 1, Buf'Unchecked_Access);
311 Write_Buf (Buf'Unchecked_Access);
313 if T.Common.Call /= null then
314 Entry_Call := T.Common.Call;
315 Clear (Buf'Unchecked_Access);
316 Space (10, Buf'Unchecked_Access);
317 Put ("serving:", 8, Buf'Unchecked_Access);
319 while Entry_Call /= null loop
320 Put (Integer_Address
321 (Entry_Call.Self.Serial_Number), 5, Buf'Unchecked_Access);
322 Entry_Call := Entry_Call.Acceptor_Prev_Call;
323 end loop;
325 Write_Buf (Buf'Unchecked_Access);
326 end if;
328 Print_Accept_Info (T);
329 end Print_Task_Info;
331 ----------------------------
332 -- Print_Task_Info_Header --
333 ----------------------------
335 procedure Print_Task_Info_Header is
336 Buf : aliased Buffer;
338 begin
339 Clear (Buf'Unchecked_Access);
340 Put ("TASK_ID", Hex_Address_Width, Buf'Unchecked_Access);
341 Put (':', Buf'Unchecked_Access);
342 Put ('F', Buf'Unchecked_Access);
343 Put (':', Buf'Unchecked_Access);
344 Put ("SERIAL_NUMBER", 4, Buf'Unchecked_Access);
345 Space (Buf'Unchecked_Access);
346 Put (" NAME", 15, Buf'Unchecked_Access);
347 Put (" STATE", 10, Buf'Unchecked_Access);
348 Space (11, Buf'Unchecked_Access);
349 Put ("MAST", 5, Buf'Unchecked_Access);
350 Put ("AWAK", 5, Buf'Unchecked_Access);
351 Put ("ATC", 5, Buf'Unchecked_Access);
352 Put ("WT", 3, Buf'Unchecked_Access);
353 Put ("DBG", 3, Buf'Unchecked_Access);
354 Write_Buf (Buf'Unchecked_Access);
355 end Print_Task_Info_Header;
357 ---------
358 -- Put --
359 ---------
361 procedure Put
362 (T : ST.Task_ID;
363 Width : Integer;
364 Buffer : Buffer_Ptr)
366 J : Integer;
367 X : Integer_Address := +T;
368 Next : Buf_Range renames Buffer.Next;
369 Buf : Buf_Array renames Buffer.Chars;
370 First : constant Integer := Next;
371 Wdth : Integer := Width;
373 begin
374 if Wdth > Buf'Last - Next then
375 Wdth := Buf'Last - Next;
376 end if;
378 J := Next + (Wdth - 1);
380 if X = 0 then
381 Buf (J) := '0';
383 else
384 while X > 0 loop
385 Buf (J) := Hex_Digits (X rem 16);
386 J := J - 1;
387 X := X / 16;
389 -- Check for overflow
391 if J < First and then X > 0 then
392 Buf (J + 1) := '*';
393 exit;
394 end if;
396 end loop;
397 end if;
399 Next := Next + Wdth;
400 end Put;
402 procedure Put
403 (N : Integer_Address;
404 Width : Integer;
405 Buffer : Buffer_Ptr)
407 J : Integer;
408 X : Integer_Address := N;
409 Next : Buf_Range renames Buffer.Next;
410 Buf : Buf_Array renames Buffer.Chars;
411 First : constant Integer := Next;
412 Wdth : Integer := Width;
414 begin
415 if Wdth > Buf'Last - Next then
416 Wdth := Buf'Last - Next;
417 end if;
419 J := Next + (Wdth - 1);
421 if N = 0 then
422 Buf (J) := '0';
424 else
425 while X > 0 loop
426 Buf (J) := Hex_Digits (X rem 10);
427 J := J - 1;
428 X := X / 10;
430 -- Check for overflow
432 if J < First and then X > 0 then
433 Buf (J + 1) := '*';
434 exit;
435 end if;
436 end loop;
437 end if;
439 Next := Next + Wdth;
440 end Put;
442 procedure Put
443 (S : String;
444 Width : Integer;
445 Buffer : Buffer_Ptr)
447 Next : Buf_Range renames Buffer.Next;
448 Buf : Buf_Array renames Buffer.Chars;
449 Bound : constant Integer := Integer'Min (Next + Width, Buf'Last);
450 J : Integer := Next;
452 begin
453 for K in S'Range loop
455 -- Check overflow
457 if J >= Bound then
458 Buf (J - 1) := '*';
459 exit;
460 end if;
462 Buf (J) := S (K);
463 J := J + 1;
464 end loop;
466 Next := Bound;
467 end Put;
469 procedure Put
470 (C : Character;
471 Buffer : Buffer_Ptr)
473 Next : Buf_Range renames Buffer.Next;
474 Buf : Buf_Array renames Buffer.Chars;
476 begin
477 if Next >= Buf'Last then
478 Buf (Next) := '*';
479 else Buf (Next) := C;
480 Next := Next + 1;
481 end if;
482 end Put;
484 ----------------------
485 -- Resume_All_Tasks --
486 ----------------------
488 procedure Resume_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
489 C : ST.Task_ID;
490 R : Boolean;
492 begin
493 STPO.Lock_RTS;
494 C := All_Tasks_List;
496 while C /= null loop
497 R := STPO.Resume_Task (C, Thread_Self);
498 C := C.Common.All_Tasks_Link;
499 end loop;
501 STPO.Unlock_RTS;
502 end Resume_All_Tasks;
504 ----------
505 -- Self --
506 ----------
508 function Self return Task_ID is
509 begin
510 return STPO.Self;
511 end Self;
513 ---------------
514 -- Set_Trace --
515 ---------------
517 procedure Set_Trace
518 (Flag : Character;
519 Value : Boolean := True)
521 begin
522 Trace_On (Flag) := Value;
523 end Set_Trace;
525 --------------------
526 -- Set_User_State --
527 --------------------
529 procedure Set_User_State (Value : Integer) is
530 begin
531 STPO.Self.User_State := Value;
532 end Set_User_State;
534 -----------
535 -- Space --
536 -----------
538 procedure Space (Buffer : Buffer_Ptr) is
539 Next : Buf_Range renames Buffer.Next;
540 Buf : Buf_Array renames Buffer.Chars;
542 begin
543 if Next >= Buf'Last then
544 Buf (Next) := '*';
545 else
546 Next := Next + 1;
547 end if;
548 end Space;
550 procedure Space
551 (N : Integer;
552 Buffer : Buffer_Ptr)
554 Next : Buf_Range renames Buffer.Next;
555 Buf : Buf_Array renames Buffer.Chars;
557 begin
558 if Next + N > Buf'Last then
559 Buf (Next) := '*';
560 else
561 Next := Next + N;
562 end if;
563 end Space;
565 -----------------------
566 -- Suspend_All_Tasks --
567 -----------------------
569 procedure Suspend_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
570 C : ST.Task_ID;
571 R : Boolean;
573 begin
574 STPO.Lock_RTS;
575 C := All_Tasks_List;
577 while C /= null loop
578 R := STPO.Suspend_Task (C, Thread_Self);
579 C := C.Common.All_Tasks_Link;
580 end loop;
582 STPO.Unlock_RTS;
583 end Suspend_All_Tasks;
585 ------------------------
586 -- Task_Creation_Hook --
587 ------------------------
589 procedure Task_Creation_Hook (Thread : OS_Interface.Thread_Id) is
590 pragma Inspection_Point (Thread);
591 -- gdb needs to access the thread parameter in order to implement
592 -- the multitask mode under VxWorks.
594 begin
595 null;
596 end Task_Creation_Hook;
598 ---------------------------
599 -- Task_Termination_Hook --
600 ---------------------------
602 procedure Task_Termination_Hook is
603 begin
604 null;
605 end Task_Termination_Hook;
607 -----------
608 -- Trace --
609 -----------
611 procedure Trace
612 (Self_ID : ST.Task_ID;
613 Msg : String;
614 Other_ID : ST.Task_ID;
615 Flag : Character)
617 Buf : aliased Buffer;
618 use type System.Task_Info.Task_Image_Type;
620 begin
621 if Trace_On (Flag) then
622 Clear (Buf'Unchecked_Access);
623 Put (Self_ID, Hex_Address_Width, Buf'Unchecked_Access);
624 Put (':', Buf'Unchecked_Access);
625 Put (Flag, Buf'Unchecked_Access);
626 Put (':', Buf'Unchecked_Access);
628 (Integer_Address (Self_ID.Serial_Number),
629 4, Buf'Unchecked_Access);
630 Space (Buf'Unchecked_Access);
632 if Self_ID.Common.Task_Image = null then
633 Put ("", 15, Buf'Unchecked_Access);
634 else
635 Put (Self_ID.Common.Task_Image.all, 15, Buf'Unchecked_Access);
636 end if;
638 Space (Buf'Unchecked_Access);
640 if Other_ID /= null then
642 (Integer_Address (Other_ID.Serial_Number),
643 4, Buf'Unchecked_Access);
644 Space (Buf'Unchecked_Access);
645 end if;
647 Put (Msg, Buf.Chars'Last - Buf.Next + 1, Buf'Unchecked_Access);
648 Write_Buf (Buf'Unchecked_Access);
649 end if;
650 end Trace;
652 procedure Trace
653 (Self_ID : ST.Task_ID;
654 Msg : String;
655 Flag : Character)
657 begin
658 Trace (Self_ID, Msg, null, Flag);
659 end Trace;
661 procedure Trace
662 (Msg : String;
663 Flag : Character)
665 Self_ID : constant ST.Task_ID := STPO.Self;
667 begin
668 Trace (Self_ID, Msg, null, Flag);
669 end Trace;
671 procedure Trace
672 (Msg : String;
673 Other_ID : ST.Task_ID;
674 Flag : Character)
676 pragma Warnings (Off, Other_ID);
678 Self_ID : constant ST.Task_ID := STPO.Self;
680 begin
681 Trace (Self_ID, Msg, null, Flag);
682 end Trace;
684 ---------------
685 -- Write_Buf --
686 ---------------
688 procedure Write_Buf (Buffer : Buffer_Ptr) is
689 Next : Buf_Range renames Buffer.Next;
690 Buf : Buf_Array renames Buffer.Chars;
692 procedure put_char (C : Integer);
693 pragma Import (C, put_char, "put_char");
695 begin
696 for J in 1 .. Next - 1 loop
697 put_char (Character'Pos (Buf (J)));
698 end loop;
700 put_char (Character'Pos (ASCII.LF));
701 end Write_Buf;
703 end System.Tasking.Debug;