Mercurial > hg > CbC > CbC_gcc
comparison gcc/ada/libgnat/s-trasym__dwarf.adb @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 ------------------------------------------------------------------------------ | |
2 -- -- | |
3 -- GNAT RUN-TIME COMPONENTS -- | |
4 -- -- | |
5 -- S Y S T E M . T R A C E B A C K . S Y M B O L I C -- | |
6 -- -- | |
7 -- B o d y -- | |
8 -- -- | |
9 -- Copyright (C) 1999-2017, AdaCore -- | |
10 -- -- | |
11 -- GNAT 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 3, or (at your option) any later ver- -- | |
14 -- sion. GNAT 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. -- | |
17 -- -- | |
18 -- As a special exception under Section 7 of GPL version 3, you are granted -- | |
19 -- additional permissions described in the GCC Runtime Library Exception, -- | |
20 -- version 3.1, as published by the Free Software Foundation. -- | |
21 -- -- | |
22 -- You should have received a copy of the GNU General Public License and -- | |
23 -- a copy of the GCC Runtime Library Exception along with this program; -- | |
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- | |
25 -- <http://www.gnu.org/licenses/>. -- | |
26 -- -- | |
27 -- GNAT was originally developed by the GNAT team at New York University. -- | |
28 -- Extensive contributions were provided by Ada Core Technologies Inc. -- | |
29 -- -- | |
30 ------------------------------------------------------------------------------ | |
31 | |
32 -- Run-time symbolic traceback support for targets using DWARF debug data | |
33 | |
34 pragma Polling (Off); | |
35 -- We must turn polling off for this unit, because otherwise we can get | |
36 -- elaboration circularities when polling is turned on. | |
37 | |
38 with Ada.Unchecked_Deallocation; | |
39 | |
40 with Ada.Exceptions.Traceback; use Ada.Exceptions.Traceback; | |
41 with Ada.Containers.Generic_Array_Sort; | |
42 | |
43 with System.Address_To_Access_Conversions; | |
44 with System.Soft_Links; | |
45 with System.CRTL; | |
46 with System.Dwarf_Lines; | |
47 with System.Exception_Traces; | |
48 with System.Standard_Library; | |
49 with System.Traceback_Entries; | |
50 with System.Strings; | |
51 with System.Bounded_Strings; | |
52 | |
53 package body System.Traceback.Symbolic is | |
54 | |
55 use System.Bounded_Strings; | |
56 use System.Dwarf_Lines; | |
57 | |
58 subtype Big_String is String (Positive); | |
59 -- To deal with C strings | |
60 | |
61 package Big_String_Conv is new System.Address_To_Access_Conversions | |
62 (Big_String); | |
63 | |
64 type Module_Cache; | |
65 type Module_Cache_Acc is access all Module_Cache; | |
66 | |
67 type Module_Cache is record | |
68 Name : Strings.String_Access; | |
69 -- Name of the module | |
70 | |
71 C : Dwarf_Context (In_Exception => True); | |
72 -- Context to symbolize an address within this module | |
73 | |
74 Chain : Module_Cache_Acc; | |
75 end record; | |
76 | |
77 procedure Free is new Ada.Unchecked_Deallocation | |
78 (Module_Cache, | |
79 Module_Cache_Acc); | |
80 | |
81 Cache_Chain : Module_Cache_Acc; | |
82 -- Simply linked list of modules | |
83 | |
84 type Module_Array is array (Natural range <>) of Module_Cache_Acc; | |
85 type Module_Array_Acc is access Module_Array; | |
86 | |
87 Modules_Cache : Module_Array_Acc; | |
88 -- Sorted array of cached modules (if not null) | |
89 | |
90 Exec_Module : aliased Module_Cache; | |
91 -- Context for the executable | |
92 | |
93 type Init_State is (Uninitialized, Initialized, Failed); | |
94 Exec_Module_State : Init_State := Uninitialized; | |
95 -- How Exec_Module is initialized | |
96 | |
97 procedure Init_Exec_Module; | |
98 -- Initialize Exec_Module if not already initialized | |
99 | |
100 function Symbolic_Traceback | |
101 (Traceback : System.Traceback_Entries.Tracebacks_Array; | |
102 Suppress_Hex : Boolean) return String; | |
103 function Symbolic_Traceback | |
104 (E : Ada.Exceptions.Exception_Occurrence; | |
105 Suppress_Hex : Boolean) return String; | |
106 -- Suppress_Hex means do not print any hexadecimal addresses, even if the | |
107 -- symbol is not available. | |
108 | |
109 function Lt (Left, Right : Module_Cache_Acc) return Boolean; | |
110 -- Sort function for Module_Cache | |
111 | |
112 procedure Init_Module | |
113 (Module : out Module_Cache; | |
114 Success : out Boolean; | |
115 Module_Name : String; | |
116 Load_Address : Address := Null_Address); | |
117 -- Initialize Module | |
118 | |
119 procedure Close_Module (Module : in out Module_Cache); | |
120 -- Finalize Module | |
121 | |
122 function Value (Item : System.Address) return String; | |
123 -- Return the String contained in Item, up until the first NUL character | |
124 | |
125 pragma Warnings (Off, "*Add_Module_To_Cache*"); | |
126 procedure Add_Module_To_Cache (Module_Name : String); | |
127 -- To be called by Build_Cache_For_All_Modules to add a new module to the | |
128 -- list. May not be referenced. | |
129 | |
130 package Module_Name is | |
131 | |
132 procedure Build_Cache_For_All_Modules; | |
133 -- Create the cache for all current modules | |
134 | |
135 function Get (Addr : access System.Address) return String; | |
136 -- Returns the module name for the given address, Addr may be updated | |
137 -- to be set relative to a shared library. This depends on the platform. | |
138 -- Returns an empty string for the main executable. | |
139 | |
140 function Is_Supported return Boolean; | |
141 pragma Inline (Is_Supported); | |
142 -- Returns True if Module_Name is supported, so if the traceback is | |
143 -- supported for shared libraries. | |
144 | |
145 end Module_Name; | |
146 | |
147 package body Module_Name is separate; | |
148 | |
149 function Executable_Name return String; | |
150 -- Returns the executable name as reported by argv[0]. If gnat_argv not | |
151 -- initialized or if argv[0] executable not found in path, function returns | |
152 -- an empty string. | |
153 | |
154 function Get_Executable_Load_Address return System.Address; | |
155 pragma Import | |
156 (C, | |
157 Get_Executable_Load_Address, | |
158 "__gnat_get_executable_load_address"); | |
159 -- Get the load address of the executable, or Null_Address if not known | |
160 | |
161 procedure Hexa_Traceback | |
162 (Traceback : Tracebacks_Array; | |
163 Suppress_Hex : Boolean; | |
164 Res : in out Bounded_String); | |
165 -- Non-symbolic traceback (simply write addresses in hexa) | |
166 | |
167 procedure Symbolic_Traceback_No_Lock | |
168 (Traceback : Tracebacks_Array; | |
169 Suppress_Hex : Boolean; | |
170 Res : in out Bounded_String); | |
171 -- Like the public Symbolic_Traceback_No_Lock except there is no provision | |
172 -- against concurrent accesses. | |
173 | |
174 procedure Module_Symbolic_Traceback | |
175 (Traceback : Tracebacks_Array; | |
176 Module : Module_Cache; | |
177 Suppress_Hex : Boolean; | |
178 Res : in out Bounded_String); | |
179 -- Returns the Traceback for a given module | |
180 | |
181 procedure Multi_Module_Symbolic_Traceback | |
182 (Traceback : Tracebacks_Array; | |
183 Suppress_Hex : Boolean; | |
184 Res : in out Bounded_String); | |
185 -- Build string containing symbolic traceback for the given call chain | |
186 | |
187 procedure Multi_Module_Symbolic_Traceback | |
188 (Traceback : Tracebacks_Array; | |
189 Module : Module_Cache; | |
190 Suppress_Hex : Boolean; | |
191 Res : in out Bounded_String); | |
192 -- Likewise but using Module | |
193 | |
194 Max_String_Length : constant := 4096; | |
195 -- Arbitrary limit on Bounded_Str length | |
196 | |
197 ----------- | |
198 -- Value -- | |
199 ----------- | |
200 | |
201 function Value (Item : System.Address) return String is | |
202 begin | |
203 if Item /= Null_Address then | |
204 for J in Big_String'Range loop | |
205 if Big_String_Conv.To_Pointer (Item) (J) = ASCII.NUL then | |
206 return Big_String_Conv.To_Pointer (Item) (1 .. J - 1); | |
207 end if; | |
208 end loop; | |
209 end if; | |
210 | |
211 return ""; | |
212 end Value; | |
213 | |
214 ------------------------- | |
215 -- Add_Module_To_Cache -- | |
216 ------------------------- | |
217 | |
218 procedure Add_Module_To_Cache (Module_Name : String) is | |
219 Module : Module_Cache_Acc; | |
220 Success : Boolean; | |
221 begin | |
222 Module := new Module_Cache; | |
223 Init_Module (Module.all, Success, Module_Name); | |
224 if not Success then | |
225 Free (Module); | |
226 return; | |
227 end if; | |
228 Module.Chain := Cache_Chain; | |
229 Cache_Chain := Module; | |
230 end Add_Module_To_Cache; | |
231 | |
232 ---------------------- | |
233 -- Init_Exec_Module -- | |
234 ---------------------- | |
235 | |
236 procedure Init_Exec_Module is | |
237 begin | |
238 if Exec_Module_State = Uninitialized then | |
239 declare | |
240 Exec_Path : constant String := Executable_Name; | |
241 Exec_Load : constant Address := Get_Executable_Load_Address; | |
242 Success : Boolean; | |
243 begin | |
244 Init_Module (Exec_Module, Success, Exec_Path, Exec_Load); | |
245 | |
246 if Success then | |
247 Exec_Module_State := Initialized; | |
248 else | |
249 Exec_Module_State := Failed; | |
250 end if; | |
251 end; | |
252 end if; | |
253 end Init_Exec_Module; | |
254 | |
255 -------- | |
256 -- Lt -- | |
257 -------- | |
258 | |
259 function Lt (Left, Right : Module_Cache_Acc) return Boolean is | |
260 begin | |
261 return Low (Left.C) < Low (Right.C); | |
262 end Lt; | |
263 | |
264 ----------------------------- | |
265 -- Module_Cache_Array_Sort -- | |
266 ----------------------------- | |
267 | |
268 procedure Module_Cache_Array_Sort is new Ada.Containers.Generic_Array_Sort | |
269 (Natural, | |
270 Module_Cache_Acc, | |
271 Module_Array, | |
272 Lt); | |
273 | |
274 ------------------ | |
275 -- Enable_Cache -- | |
276 ------------------ | |
277 | |
278 procedure Enable_Cache (Include_Modules : Boolean := False) is | |
279 begin | |
280 -- Can be called at most once | |
281 if Cache_Chain /= null then | |
282 return; | |
283 end if; | |
284 | |
285 -- Add all modules | |
286 Init_Exec_Module; | |
287 Cache_Chain := Exec_Module'Access; | |
288 | |
289 if Include_Modules then | |
290 Module_Name.Build_Cache_For_All_Modules; | |
291 end if; | |
292 | |
293 -- Build and fill the array of modules | |
294 declare | |
295 Count : Natural; | |
296 Module : Module_Cache_Acc; | |
297 begin | |
298 for Phase in 1 .. 2 loop | |
299 Count := 0; | |
300 Module := Cache_Chain; | |
301 while Module /= null loop | |
302 Count := Count + 1; | |
303 | |
304 if Phase = 1 then | |
305 Enable_Cache (Module.C); | |
306 else | |
307 Modules_Cache (Count) := Module; | |
308 end if; | |
309 Module := Module.Chain; | |
310 end loop; | |
311 | |
312 if Phase = 1 then | |
313 Modules_Cache := new Module_Array (1 .. Count); | |
314 end if; | |
315 end loop; | |
316 end; | |
317 | |
318 -- Sort the array | |
319 Module_Cache_Array_Sort (Modules_Cache.all); | |
320 end Enable_Cache; | |
321 | |
322 --------------------- | |
323 -- Executable_Name -- | |
324 --------------------- | |
325 | |
326 function Executable_Name return String is | |
327 -- We have to import gnat_argv as an Address to match the type of | |
328 -- gnat_argv in the binder generated file. Otherwise, we get spurious | |
329 -- warnings about type mismatch when LTO is turned on. | |
330 | |
331 Gnat_Argv : System.Address; | |
332 pragma Import (C, Gnat_Argv, "gnat_argv"); | |
333 | |
334 type Argv_Array is array (0 .. 0) of System.Address; | |
335 package Conv is new System.Address_To_Access_Conversions (Argv_Array); | |
336 | |
337 function locate_exec_on_path (A : System.Address) return System.Address; | |
338 pragma Import (C, locate_exec_on_path, "__gnat_locate_exec_on_path"); | |
339 | |
340 begin | |
341 if Gnat_Argv = Null_Address then | |
342 return ""; | |
343 end if; | |
344 | |
345 declare | |
346 Addr : constant System.Address := | |
347 locate_exec_on_path (Conv.To_Pointer (Gnat_Argv) (0)); | |
348 Result : constant String := Value (Addr); | |
349 | |
350 begin | |
351 -- The buffer returned by locate_exec_on_path was allocated using | |
352 -- malloc, so we should use free to release the memory. | |
353 | |
354 if Addr /= Null_Address then | |
355 System.CRTL.free (Addr); | |
356 end if; | |
357 | |
358 return Result; | |
359 end; | |
360 end Executable_Name; | |
361 | |
362 ------------------ | |
363 -- Close_Module -- | |
364 ------------------ | |
365 | |
366 procedure Close_Module (Module : in out Module_Cache) is | |
367 begin | |
368 Close (Module.C); | |
369 Strings.Free (Module.Name); | |
370 end Close_Module; | |
371 | |
372 ----------------- | |
373 -- Init_Module -- | |
374 ----------------- | |
375 | |
376 procedure Init_Module | |
377 (Module : out Module_Cache; | |
378 Success : out Boolean; | |
379 Module_Name : String; | |
380 Load_Address : Address := Null_Address) | |
381 is | |
382 begin | |
383 -- Early return if the module is not known | |
384 | |
385 if Module_Name = "" then | |
386 Success := False; | |
387 return; | |
388 end if; | |
389 | |
390 Open (Module_Name, Module.C, Success); | |
391 | |
392 -- If a module can't be opened just return now, we just cannot give more | |
393 -- information in this case. | |
394 | |
395 if not Success then | |
396 return; | |
397 end if; | |
398 | |
399 Set_Load_Address (Module.C, Load_Address); | |
400 | |
401 Module.Name := new String'(Module_Name); | |
402 end Init_Module; | |
403 | |
404 ------------------------------- | |
405 -- Module_Symbolic_Traceback -- | |
406 ------------------------------- | |
407 | |
408 procedure Module_Symbolic_Traceback | |
409 (Traceback : Tracebacks_Array; | |
410 Module : Module_Cache; | |
411 Suppress_Hex : Boolean; | |
412 Res : in out Bounded_String) | |
413 is | |
414 Success : Boolean := False; | |
415 begin | |
416 if Symbolic.Module_Name.Is_Supported then | |
417 Append (Res, '['); | |
418 Append (Res, Module.Name.all); | |
419 Append (Res, ']' & ASCII.LF); | |
420 end if; | |
421 | |
422 Dwarf_Lines.Symbolic_Traceback | |
423 (Module.C, | |
424 Traceback, | |
425 Suppress_Hex, | |
426 Success, | |
427 Res); | |
428 | |
429 if not Success then | |
430 Hexa_Traceback (Traceback, Suppress_Hex, Res); | |
431 end if; | |
432 | |
433 -- We must not allow an unhandled exception here, since this function | |
434 -- may be installed as a decorator for all automatic exceptions. | |
435 | |
436 exception | |
437 when others => | |
438 return; | |
439 end Module_Symbolic_Traceback; | |
440 | |
441 ------------------------------------- | |
442 -- Multi_Module_Symbolic_Traceback -- | |
443 ------------------------------------- | |
444 | |
445 procedure Multi_Module_Symbolic_Traceback | |
446 (Traceback : Tracebacks_Array; | |
447 Suppress_Hex : Boolean; | |
448 Res : in out Bounded_String) | |
449 is | |
450 F : constant Natural := Traceback'First; | |
451 begin | |
452 if Traceback'Length = 0 or else Is_Full (Res) then | |
453 return; | |
454 end if; | |
455 | |
456 if Modules_Cache /= null then | |
457 -- Search in the cache | |
458 | |
459 declare | |
460 Addr : constant Address := Traceback (F); | |
461 Hi, Lo, Mid : Natural; | |
462 begin | |
463 Lo := Modules_Cache'First; | |
464 Hi := Modules_Cache'Last; | |
465 while Lo <= Hi loop | |
466 Mid := (Lo + Hi) / 2; | |
467 if Addr < Low (Modules_Cache (Mid).C) then | |
468 Hi := Mid - 1; | |
469 elsif Is_Inside (Modules_Cache (Mid).C, Addr) then | |
470 Multi_Module_Symbolic_Traceback | |
471 (Traceback, | |
472 Modules_Cache (Mid).all, | |
473 Suppress_Hex, | |
474 Res); | |
475 return; | |
476 else | |
477 Lo := Mid + 1; | |
478 end if; | |
479 end loop; | |
480 | |
481 -- Not found | |
482 Hexa_Traceback (Traceback (F .. F), Suppress_Hex, Res); | |
483 Multi_Module_Symbolic_Traceback | |
484 (Traceback (F + 1 .. Traceback'Last), | |
485 Suppress_Hex, | |
486 Res); | |
487 end; | |
488 else | |
489 | |
490 -- First try the executable | |
491 if Is_Inside (Exec_Module.C, Traceback (F)) then | |
492 Multi_Module_Symbolic_Traceback | |
493 (Traceback, | |
494 Exec_Module, | |
495 Suppress_Hex, | |
496 Res); | |
497 return; | |
498 end if; | |
499 | |
500 -- Otherwise, try a shared library | |
501 declare | |
502 Addr : aliased System.Address := Traceback (F); | |
503 M_Name : constant String := Module_Name.Get (Addr'Access); | |
504 Module : Module_Cache; | |
505 Success : Boolean; | |
506 begin | |
507 Init_Module (Module, Success, M_Name, System.Null_Address); | |
508 if Success then | |
509 Multi_Module_Symbolic_Traceback | |
510 (Traceback, | |
511 Module, | |
512 Suppress_Hex, | |
513 Res); | |
514 Close_Module (Module); | |
515 else | |
516 -- Module not found | |
517 Hexa_Traceback (Traceback (F .. F), Suppress_Hex, Res); | |
518 Multi_Module_Symbolic_Traceback | |
519 (Traceback (F + 1 .. Traceback'Last), | |
520 Suppress_Hex, | |
521 Res); | |
522 end if; | |
523 end; | |
524 end if; | |
525 end Multi_Module_Symbolic_Traceback; | |
526 | |
527 procedure Multi_Module_Symbolic_Traceback | |
528 (Traceback : Tracebacks_Array; | |
529 Module : Module_Cache; | |
530 Suppress_Hex : Boolean; | |
531 Res : in out Bounded_String) | |
532 is | |
533 Pos : Positive; | |
534 begin | |
535 -- Will symbolize the first address... | |
536 | |
537 Pos := Traceback'First + 1; | |
538 | |
539 -- ... and all addresses in the same module | |
540 | |
541 Same_Module : | |
542 loop | |
543 exit Same_Module when Pos > Traceback'Last; | |
544 | |
545 -- Get address to check for corresponding module name | |
546 | |
547 exit Same_Module when not Is_Inside (Module.C, Traceback (Pos)); | |
548 | |
549 Pos := Pos + 1; | |
550 end loop Same_Module; | |
551 | |
552 Module_Symbolic_Traceback | |
553 (Traceback (Traceback'First .. Pos - 1), | |
554 Module, | |
555 Suppress_Hex, | |
556 Res); | |
557 Multi_Module_Symbolic_Traceback | |
558 (Traceback (Pos .. Traceback'Last), | |
559 Suppress_Hex, | |
560 Res); | |
561 end Multi_Module_Symbolic_Traceback; | |
562 | |
563 -------------------- | |
564 -- Hexa_Traceback -- | |
565 -------------------- | |
566 | |
567 procedure Hexa_Traceback | |
568 (Traceback : Tracebacks_Array; | |
569 Suppress_Hex : Boolean; | |
570 Res : in out Bounded_String) | |
571 is | |
572 use System.Traceback_Entries; | |
573 begin | |
574 if Suppress_Hex then | |
575 Append (Res, "..."); | |
576 Append (Res, ASCII.LF); | |
577 else | |
578 for J in Traceback'Range loop | |
579 Append_Address (Res, PC_For (Traceback (J))); | |
580 Append (Res, ASCII.LF); | |
581 end loop; | |
582 end if; | |
583 end Hexa_Traceback; | |
584 | |
585 -------------------------------- | |
586 -- Symbolic_Traceback_No_Lock -- | |
587 -------------------------------- | |
588 | |
589 procedure Symbolic_Traceback_No_Lock | |
590 (Traceback : Tracebacks_Array; | |
591 Suppress_Hex : Boolean; | |
592 Res : in out Bounded_String) | |
593 is | |
594 begin | |
595 if Symbolic.Module_Name.Is_Supported then | |
596 Multi_Module_Symbolic_Traceback (Traceback, Suppress_Hex, Res); | |
597 else | |
598 if Exec_Module_State = Failed then | |
599 Append (Res, "Call stack traceback locations:" & ASCII.LF); | |
600 Hexa_Traceback (Traceback, Suppress_Hex, Res); | |
601 else | |
602 Module_Symbolic_Traceback | |
603 (Traceback, | |
604 Exec_Module, | |
605 Suppress_Hex, | |
606 Res); | |
607 end if; | |
608 end if; | |
609 end Symbolic_Traceback_No_Lock; | |
610 | |
611 ------------------------ | |
612 -- Symbolic_Traceback -- | |
613 ------------------------ | |
614 | |
615 function Symbolic_Traceback | |
616 (Traceback : Tracebacks_Array; | |
617 Suppress_Hex : Boolean) return String | |
618 is | |
619 Res : Bounded_String (Max_Length => Max_String_Length); | |
620 begin | |
621 System.Soft_Links.Lock_Task.all; | |
622 Init_Exec_Module; | |
623 Symbolic_Traceback_No_Lock (Traceback, Suppress_Hex, Res); | |
624 System.Soft_Links.Unlock_Task.all; | |
625 | |
626 return To_String (Res); | |
627 | |
628 exception | |
629 when others => | |
630 System.Soft_Links.Unlock_Task.all; | |
631 raise; | |
632 end Symbolic_Traceback; | |
633 | |
634 function Symbolic_Traceback | |
635 (Traceback : System.Traceback_Entries.Tracebacks_Array) return String is | |
636 begin | |
637 return Symbolic_Traceback (Traceback, Suppress_Hex => False); | |
638 end Symbolic_Traceback; | |
639 | |
640 function Symbolic_Traceback_No_Hex | |
641 (Traceback : System.Traceback_Entries.Tracebacks_Array) return String is | |
642 begin | |
643 return Symbolic_Traceback (Traceback, Suppress_Hex => True); | |
644 end Symbolic_Traceback_No_Hex; | |
645 | |
646 function Symbolic_Traceback | |
647 (E : Ada.Exceptions.Exception_Occurrence; | |
648 Suppress_Hex : Boolean) return String | |
649 is | |
650 begin | |
651 return Symbolic_Traceback | |
652 (Ada.Exceptions.Traceback.Tracebacks (E), | |
653 Suppress_Hex); | |
654 end Symbolic_Traceback; | |
655 | |
656 function Symbolic_Traceback | |
657 (E : Ada.Exceptions.Exception_Occurrence) return String | |
658 is | |
659 begin | |
660 return Symbolic_Traceback (E, Suppress_Hex => False); | |
661 end Symbolic_Traceback; | |
662 | |
663 function Symbolic_Traceback_No_Hex | |
664 (E : Ada.Exceptions.Exception_Occurrence) return String is | |
665 begin | |
666 return Symbolic_Traceback (E, Suppress_Hex => True); | |
667 end Symbolic_Traceback_No_Hex; | |
668 | |
669 Exception_Tracebacks_Symbolic : Integer; | |
670 pragma Import | |
671 (C, | |
672 Exception_Tracebacks_Symbolic, | |
673 "__gl_exception_tracebacks_symbolic"); | |
674 -- Boolean indicating whether symbolic tracebacks should be generated. | |
675 | |
676 use Standard_Library; | |
677 begin | |
678 -- If this version of this package is available, and the binder switch -Es | |
679 -- was given, then we want to use this as the decorator by default, and we | |
680 -- want to turn on tracing for Unhandled_Raise_In_Main. Note that the user | |
681 -- cannot have already set Exception_Trace, because the runtime library is | |
682 -- elaborated before user-defined code. | |
683 | |
684 if Exception_Tracebacks_Symbolic /= 0 then | |
685 Exception_Traces.Set_Trace_Decorator (Symbolic_Traceback'Access); | |
686 pragma Assert (Exception_Trace = RM_Convention); | |
687 Exception_Trace := Unhandled_Raise_In_Main; | |
688 end if; | |
689 end System.Traceback.Symbolic; |