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 --
11 -- Copyright (C) 1997-2001 Free Software Foundation, Inc. --
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. --
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. --
31 -- GNARL was developed by the GNARL team at Florida State University. It is --
32 -- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
33 -- State University (http://www.gnat.com). --
35 ------------------------------------------------------------------------------
37 -- This package encapsulates all direct interfaces to task debugging services
38 -- that are needed by gdb with gnat mode (1.13 and higher)
40 -- Note : This file *must* be compiled with debugging information
42 -- Do not add any dependency to GNARL packages since this package is used
43 -- in both normal and resticted (ravenscar) environments.
45 with System
.Task_Info
,
46 System
.Task_Primitives
.Operations
,
49 package body System
.Tasking
.Debug
is
53 package STPO
renames System
.Task_Primitives
.Operations
;
55 type Integer_Address
is mod 2 ** Standard
'Address_Size;
56 type Integer_Address_Ptr
is access all Integer_Address
;
59 Unchecked_Conversion
(System
.Address
, Integer_Address_Ptr
);
62 Unchecked_Conversion
(Task_ID
, Integer_Address
);
64 Hex_Address_Width
: constant := (Standard
'Address_Size / 4);
66 Zero_Pos
: constant := Character'Pos ('0');
68 Hex_Digits
: constant array (0 .. Integer_Address
'(15)) of Character :=
71 subtype Buf_Range is Integer range 1 .. 80;
72 type Buf_Array is array (Buf_Range) of aliased Character;
75 Next : Buf_Range := Buf_Range'First;
76 Chars : Buf_Array := (Buf_Range => ' ');
79 type Buffer_Ptr is access all Buffer;
81 type Trace_Flag_Set is array (Character) of Boolean;
83 Trace_On : Trace_Flag_Set := ('A
' .. 'Z
' => False, others => True);
85 -----------------------
86 -- Local Subprograms --
87 -----------------------
93 -- Put TCB pointer T, (coded in hexadecimal) into Buffer
94 -- right-justified in Width characters.
100 -- Put N (coded in decimal) into Buf right-justified in Width
101 -- characters starting at Buf (Next).
106 Buffer : Buffer_Ptr);
107 -- Put string S into Buf left-justified in Width characters
108 -- starting with space in Buf (Next), truncated as necessary.
112 Buffer : Buffer_Ptr);
113 -- Put character C into Buf, left-justified, starting at Buf (Next)
115 procedure Space (Buffer : Buffer_Ptr);
116 -- Increment Next, resulting in a space
120 Buffer : Buffer_Ptr);
121 -- Increment Next by N, resulting in N spaces
123 procedure Clear (Buffer : Buffer_Ptr);
124 -- Clear Buf and reset Next to 1
126 procedure Write_Buf (Buffer : Buffer_Ptr);
127 -- Write contents of Buf (1 .. Next) to standard output
133 procedure Clear (Buffer : Buffer_Ptr) is
134 Next : Buf_Range renames Buffer.Next;
135 Buf : Buf_Array renames Buffer.Chars;
138 Buf := (Buf_Range => ' ');
146 function Image (T : ST.Task_ID) return String is
147 Buf : aliased Buffer;
148 Result : String (1 .. Hex_Address_Width + 21);
150 use type System.Task_Info.Task_Image_Type;
153 Clear (Buf'Unchecked_Access);
154 Put (T, Hex_Address_Width, Buf'Unchecked_Access);
155 Put (':', Buf'Unchecked_Access);
156 Put (Integer_Address (T.Serial_Number), 4, Buf'Unchecked_Access);
157 Space (Buf'Unchecked_Access);
159 if T.Common.Task_Image = null then
160 Put ("", 15, Buf'Unchecked_Access);
162 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
165 for J in Result'Range loop
166 Result (J) := Buf.Chars (J);
176 procedure List_Tasks is
180 Print_Task_Info_Header;
185 C := C.Common.All_Tasks_Link;
189 -----------------------
190 -- Print_Accept_Info --
191 -----------------------
193 procedure Print_Accept_Info (T : ST.Task_ID) is
194 Buf : aliased Buffer;
197 if T.Open_Accepts = null then
201 Clear (Buf'Unchecked_Access);
202 Space (10, Buf'Unchecked_Access);
203 Put ("accepting:", 11, Buf'Unchecked_Access);
205 for J in T.Open_Accepts.all'Range loop
206 Put (Integer_Address (T.Open_Accepts (J).S), 3, Buf'Unchecked_Access);
209 Write_Buf (Buf'Unchecked_Access);
210 end Print_Accept_Info;
212 ------------------------
213 -- Print_Current_Task --
214 ------------------------
216 procedure Print_Current_Task is
218 Print_Task_Info (STPO.Self);
219 end Print_Current_Task;
221 ---------------------
222 -- Print_Task_Info --
223 ---------------------
225 procedure Print_Task_Info (T : ST.Task_ID) is
226 Entry_Call : Entry_Call_Link;
227 Buf : aliased Buffer;
229 use type System.Task_Info.Task_Image_Type;
232 Clear (Buf'Unchecked_Access);
233 Put (T, Hex_Address_Width, Buf'Unchecked_Access);
234 Put (':', Buf'Unchecked_Access);
235 Put (' ', Buf'Unchecked_Access);
236 Put (':', Buf'Unchecked_Access);
239 Put (" null task", 10, Buf'Unchecked_Access);
240 Write_Buf (Buf'Unchecked_Access);
244 Put (Integer_Address (T.Serial_Number), 4, Buf'Unchecked_Access);
245 Space (Buf'Unchecked_Access);
247 if T.Common.Task_Image = null then
248 Put ("", 15, Buf'Unchecked_Access);
250 Put (T.Common.Task_Image.all, 15, Buf'Unchecked_Access);
253 Space (Buf'Unchecked_Access);
254 Put (Task_States'Image (T.Common.State), 10, Buf'Unchecked_Access);
255 Space (Buf'Unchecked_Access);
258 Put ('C
', Buf'Unchecked_Access);
260 Space (Buf'Unchecked_Access);
263 if T.Open_Accepts /= null then
264 Put ('A
', Buf'Unchecked_Access);
266 Space (Buf'Unchecked_Access);
269 if T.Common.Call /= null then
270 Put ('C
', Buf'Unchecked_Access);
272 Space (Buf'Unchecked_Access);
275 if T.Terminate_Alternative then
276 Put ('T
', Buf'Unchecked_Access);
278 Space (Buf'Unchecked_Access);
282 Put ('A
', Buf'Unchecked_Access);
284 Space (Buf'Unchecked_Access);
287 if T.Deferral_Level = 0 then
288 Space (3, Buf'Unchecked_Access);
290 Put ('D
', Buf'Unchecked_Access);
291 if T.Deferral_Level < 0 then
292 Put ("<0", 2, Buf'Unchecked_Access);
293 elsif T.Deferral_Level > 1 then
294 Put (Integer_Address (T.Deferral_Level), 2, Buf'Unchecked_Access);
296 Space (2, Buf'Unchecked_Access);
300 Space (Buf'Unchecked_Access);
301 Put (Integer_Address (T.Master_of_Task), 1, Buf'Unchecked_Access);
302 Space (Buf'Unchecked_Access);
303 Put (Integer_Address (T.Master_Within), 1, Buf'Unchecked_Access);
304 Put (',', Buf'Unchecked_Access);
305 Space (Buf'Unchecked_Access);
306 Put (Integer_Address (T.Awake_Count), 1, Buf'Unchecked_Access);
307 Space (Buf'Unchecked_Access);
308 Put (Integer_Address (T.Alive_Count), 1, Buf'Unchecked_Access);
309 Put (',', Buf'Unchecked_Access);
310 Space (Buf'Unchecked_Access);
311 Put (Integer_Address (T.ATC_Nesting_Level), 1, Buf'Unchecked_Access);
312 Space (Buf'Unchecked_Access);
313 Put (Integer_Address (T.Pending_ATC_Level), 1, Buf'Unchecked_Access);
314 Put (',', Buf'Unchecked_Access);
315 Space (Buf'Unchecked_Access);
316 Put (Integer_Address (T.Common.Wait_Count), 1, Buf'Unchecked_Access);
317 Put (',', Buf'Unchecked_Access);
318 Space (Buf'Unchecked_Access);
319 Put (Integer_Address (T.User_State), 1, Buf'Unchecked_Access);
320 Write_Buf (Buf'Unchecked_Access);
322 if T.Common.Call /= null then
323 Entry_Call := T.Common.Call;
324 Clear (Buf'Unchecked_Access);
325 Space (10, Buf'Unchecked_Access);
326 Put ("serving:", 8, Buf'Unchecked_Access);
328 while Entry_Call /= null loop
330 (Entry_Call.Self.Serial_Number), 5, Buf'Unchecked_Access);
331 Entry_Call := Entry_Call.Acceptor_Prev_Call;
334 Write_Buf (Buf'Unchecked_Access);
337 Print_Accept_Info (T);
340 ----------------------------
341 -- Print_Task_Info_Header --
342 ----------------------------
344 procedure Print_Task_Info_Header is
345 Buf : aliased Buffer;
348 Clear (Buf'Unchecked_Access);
349 Put ("TASK_ID", Hex_Address_Width, Buf'Unchecked_Access);
350 Put (':', Buf'Unchecked_Access);
351 Put ('F
', Buf'Unchecked_Access);
352 Put (':', Buf'Unchecked_Access);
353 Put ("SERIAL_NUMBER", 4, Buf'Unchecked_Access);
354 Space (Buf'Unchecked_Access);
355 Put (" NAME", 15, Buf'Unchecked_Access);
356 Put (" STATE", 10, Buf'Unchecked_Access);
357 Space (11, Buf'Unchecked_Access);
358 Put ("MAST", 5, Buf'Unchecked_Access);
359 Put ("AWAK", 5, Buf'Unchecked_Access);
360 Put ("ATC", 5, Buf'Unchecked_Access);
361 Put ("WT", 3, Buf'Unchecked_Access);
362 Put ("DBG", 3, Buf'Unchecked_Access);
363 Write_Buf (Buf'Unchecked_Access);
364 end Print_Task_Info_Header;
376 X : Integer_Address := +T;
377 Next : Buf_Range renames Buffer.Next;
378 Buf : Buf_Array renames Buffer.Chars;
379 First : constant Integer := Next;
380 Wdth : Integer := Width;
383 if Wdth > Buf'Last - Next then
384 Wdth := Buf'Last - Next;
387 J := Next + (Wdth - 1);
394 Buf (J) := Hex_Digits (X rem 16);
398 -- Check for overflow
400 if J < First and then X > 0 then
412 (N : Integer_Address;
417 X : Integer_Address := N;
418 Next : Buf_Range renames Buffer.Next;
419 Buf : Buf_Array renames Buffer.Chars;
420 First : constant Integer := Next;
421 Wdth : Integer := Width;
424 if Wdth > Buf'Last - Next then
425 Wdth := Buf'Last - Next;
428 J := Next + (Wdth - 1);
435 Buf (J) := Hex_Digits (X rem 10);
439 -- Check for overflow
441 if J < First and then X > 0 then
456 Next : Buf_Range renames Buffer.Next;
457 Buf : Buf_Array renames Buffer.Chars;
458 Bound : constant Integer := Integer'Min (Next + Width, Buf'Last);
462 for K in S'Range loop
482 Next : Buf_Range renames Buffer.Next;
483 Buf : Buf_Array renames Buffer.Chars;
486 if Next >= Buf'Last then
488 else Buf (Next) := C;
493 ----------------------
494 -- Resume_All_Tasks --
495 ----------------------
497 procedure Resume_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
502 STPO.Lock_All_Tasks_List;
506 R := STPO.Resume_Task (C, Thread_Self);
507 C := C.Common.All_Tasks_Link;
510 STPO.Unlock_All_Tasks_List;
511 end Resume_All_Tasks;
517 function Self return Task_ID is
528 Value : Boolean := True)
531 Trace_On (Flag) := Value;
538 procedure Set_User_State (Value : Integer) is
540 STPO.Self.User_State := Value;
547 procedure Space (Buffer : Buffer_Ptr) is
548 Next : Buf_Range renames Buffer.Next;
549 Buf : Buf_Array renames Buffer.Chars;
552 if Next >= Buf'Last then
563 Next : Buf_Range renames Buffer.Next;
564 Buf : Buf_Array renames Buffer.Chars;
567 if Next + N > Buf'Last then
574 -----------------------
575 -- Suspend_All_Tasks --
576 -----------------------
578 procedure Suspend_All_Tasks (Thread_Self : OS_Interface.Thread_Id) is
583 STPO.Lock_All_Tasks_List;
587 R := STPO.Suspend_Task (C, Thread_Self);
588 C := C.Common.All_Tasks_Link;
591 STPO.Unlock_All_Tasks_List;
592 end Suspend_All_Tasks;
594 ------------------------
595 -- Task_Creation_Hook --
596 ------------------------
598 procedure Task_Creation_Hook (Thread : OS_Interface.Thread_Id) is
599 pragma Inspection_Point (Thread);
600 -- gdb needs to access the thread parameter in order to implement
601 -- the multitask mode under VxWorks.
605 end Task_Creation_Hook;
607 ---------------------------
608 -- Task_Termination_Hook --
609 ---------------------------
611 procedure Task_Termination_Hook is
614 end Task_Termination_Hook;
621 (Self_ID : ST.Task_ID;
623 Other_ID : ST.Task_ID;
626 Buf : aliased Buffer;
627 use type System.Task_Info.Task_Image_Type;
630 if Trace_On (Flag) then
631 Clear (Buf'Unchecked_Access);
632 Put (Self_ID, Hex_Address_Width, Buf'Unchecked_Access);
633 Put (':', Buf'Unchecked_Access);
634 Put (Flag, Buf'Unchecked_Access);
635 Put (':', Buf'Unchecked_Access);
637 (Integer_Address (Self_ID.Serial_Number),
638 4, Buf'Unchecked_Access);
639 Space (Buf'Unchecked_Access);
641 if Self_ID.Common.Task_Image = null then
642 Put ("", 15, Buf'Unchecked_Access);
644 Put (Self_ID.Common.Task_Image.all, 15, Buf'Unchecked_Access);
647 Space (Buf'Unchecked_Access);
649 if Other_ID /= null then
651 (Integer_Address (Other_ID.Serial_Number),
652 4, Buf'Unchecked_Access);
653 Space (Buf'Unchecked_Access);
656 Put (Msg, Buf.Chars'Last - Buf.Next + 1, Buf'Unchecked_Access);
657 Write_Buf (Buf'Unchecked_Access);
662 (Self_ID : ST.Task_ID;
667 Trace (Self_ID, Msg, null, Flag);
674 Self_ID : constant ST.Task_ID := STPO.Self;
677 Trace (Self_ID, Msg, null, Flag);
682 Other_ID : ST.Task_ID;
685 Self_ID : constant ST.Task_ID := STPO.Self;
688 Trace (Self_ID, Msg, null, Flag);
695 procedure Write_Buf (Buffer : Buffer_Ptr) is
696 Next : Buf_Range renames Buffer.Next;
697 Buf : Buf_Array renames Buffer.Chars;
699 procedure put_char (C : Integer);
700 pragma Import (C, put_char, "put_char");
703 for J in 1 .. Next - 1 loop
704 put_char (Character'Pos (Buf (J)));
707 put_char (Character'Pos (ASCII.LF));
710 end System.Tasking.Debug;