1 ------------------------------------------------------------------------------
3 -- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
5 -- S Y S T E M . T A S K I N G . D E B U G --
9 -- Copyright (C) 1997-2002 Free Software Foundation, Inc. --
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. --
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. --
29 -- GNARL was developed by the GNARL team at Florida State University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
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
,
46 package body System
.Tasking
.Debug
is
50 package STPO
renames System
.Task_Primitives
.Operations
;
52 type Integer_Address
is mod 2 ** Standard
'Address_Size;
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 :=
62 subtype Buf_Range is Integer range 1 .. 80;
63 type Buf_Array is array (Buf_Range) of aliased Character;
66 Next : Buf_Range := Buf_Range'First;
67 Chars : Buf_Array := (Buf_Range => ' ');
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 -----------------------
84 -- Put TCB pointer T, (coded in hexadecimal) into Buffer
85 -- right-justified in Width characters.
91 -- Put N (coded in decimal) into Buf right-justified in Width
92 -- characters starting at Buf (Next).
98 -- Put string S into Buf left-justified in Width characters
99 -- starting with space in Buf (Next), truncated as necessary.
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
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
124 procedure Clear (Buffer : Buffer_Ptr) is
125 Next : Buf_Range renames Buffer.Next;
126 Buf : Buf_Array renames Buffer.Chars;
129 Buf := (Buf_Range => ' ');
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;
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);
153 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
156 for J in Result'Range loop
157 Result (J) := Buf.Chars (J);
167 procedure List_Tasks is
171 Print_Task_Info_Header;
176 C := C.Common.All_Tasks_Link;
180 -----------------------
181 -- Print_Accept_Info --
182 -----------------------
184 procedure Print_Accept_Info (T : ST.Task_ID) is
185 Buf : aliased Buffer;
188 if T.Open_Accepts = null then
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);
200 Write_Buf (Buf'Unchecked_Access);
201 end Print_Accept_Info;
203 ------------------------
204 -- Print_Current_Task --
205 ------------------------
207 procedure Print_Current_Task is
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;
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);
230 Put (" null task", 10, Buf'Unchecked_Access);
231 Write_Buf (Buf'Unchecked_Access);
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);
241 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
244 Space (Buf'Unchecked_Access);
245 Put (Task_States'Image (T.Common.State), 10, Buf'Unchecked_Access);
246 Space (Buf'Unchecked_Access);
249 Put ('C
', Buf'Unchecked_Access);
251 Space (Buf'Unchecked_Access);
254 if T.Open_Accepts /= null then
255 Put ('A
', Buf'Unchecked_Access);
257 Space (Buf'Unchecked_Access);
260 if T.Common.Call /= null then
261 Put ('C
', Buf'Unchecked_Access);
263 Space (Buf'Unchecked_Access);
266 if T.Terminate_Alternative then
267 Put ('T
', Buf'Unchecked_Access);
269 Space (Buf'Unchecked_Access);
273 Put ('A
', Buf'Unchecked_Access);
275 Space (Buf'Unchecked_Access);
278 if T.Deferral_Level = 0 then
279 Space (3, Buf'Unchecked_Access);
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);
287 Space (2, Buf'Unchecked_Access);
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
321 (Entry_Call.Self.Serial_Number), 5, Buf'Unchecked_Access);
322 Entry_Call := Entry_Call.Acceptor_Prev_Call;
325 Write_Buf (Buf'Unchecked_Access);
328 Print_Accept_Info (T);
331 ----------------------------
332 -- Print_Task_Info_Header --
333 ----------------------------
335 procedure Print_Task_Info_Header is
336 Buf : aliased Buffer;
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;
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;
374 if Wdth > Buf'Last - Next then
375 Wdth := Buf'Last - Next;
378 J := Next + (Wdth - 1);
385 Buf (J) := Hex_Digits (X rem 16);
389 -- Check for overflow
391 if J < First and then X > 0 then
403 (N : Integer_Address;
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;
415 if Wdth > Buf'Last - Next then
416 Wdth := Buf'Last - Next;
419 J := Next + (Wdth - 1);
426 Buf (J) := Hex_Digits (X rem 10);
430 -- Check for overflow
432 if J < First and then X > 0 then
447 Next : Buf_Range renames Buffer.Next;
448 Buf : Buf_Array renames Buffer.Chars;
449 Bound : constant Integer := Integer'Min (Next + Width, Buf'Last);
453 for K in S'Range loop
473 Next : Buf_Range renames Buffer.Next;
474 Buf : Buf_Array renames Buffer.Chars;
477 if Next >= Buf'Last then
479 else Buf (Next) := C;
484 ----------------------
485 -- Resume_All_Tasks --
486 ----------------------
488 procedure Resume_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
497 R := STPO.Resume_Task (C, Thread_Self);
498 C := C.Common.All_Tasks_Link;
502 end Resume_All_Tasks;
508 function Self return Task_ID is
519 Value : Boolean := True)
522 Trace_On (Flag) := Value;
529 procedure Set_User_State (Value : Integer) is
531 STPO.Self.User_State := Value;
538 procedure Space (Buffer : Buffer_Ptr) is
539 Next : Buf_Range renames Buffer.Next;
540 Buf : Buf_Array renames Buffer.Chars;
543 if Next >= Buf'Last then
554 Next : Buf_Range renames Buffer.Next;
555 Buf : Buf_Array renames Buffer.Chars;
558 if Next + N > Buf'Last then
565 -----------------------
566 -- Suspend_All_Tasks --
567 -----------------------
569 procedure Suspend_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
578 R := STPO.Suspend_Task (C, Thread_Self);
579 C := C.Common.All_Tasks_Link;
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.
596 end Task_Creation_Hook;
598 ---------------------------
599 -- Task_Termination_Hook --
600 ---------------------------
602 procedure Task_Termination_Hook is
605 end Task_Termination_Hook;
612 (Self_ID : ST.Task_ID;
614 Other_ID : ST.Task_ID;
617 Buf : aliased Buffer;
618 use type System.Task_Info.Task_Image_Type;
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);
635 Put (Self_ID.Common.Task_Image.all, 15, Buf'Unchecked_Access);
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);
647 Put (Msg, Buf.Chars'Last - Buf.Next + 1, Buf'Unchecked_Access);
648 Write_Buf (Buf'Unchecked_Access);
653 (Self_ID : ST.Task_ID;
658 Trace (Self_ID, Msg, null, Flag);
665 Self_ID : constant ST.Task_ID := STPO.Self;
668 Trace (Self_ID, Msg, null, Flag);
673 Other_ID : ST.Task_ID;
676 pragma Warnings (Off, Other_ID);
678 Self_ID : constant ST.Task_ID := STPO.Self;
681 Trace (Self_ID, Msg, null, Flag);
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");
696 for J in 1 .. Next - 1 loop
697 put_char (Character'Pos (Buf (J)));
700 put_char (Character'Pos (ASCII.LF));
703 end System.Tasking.Debug;