program compiled with debug information.
However the ``addr2line`` tool does not work with Position-Independent Code
-(PIC), the historical example being Windows DLLs, which nowadays encompasses
-Position-Independent Executables (PIE) on recent Windows versions.
-
-In order to translate addresses into the source lines with Position-Independent
-Executables on recent Windows versions, in other words without using the switch
-:switch:`-no-pie` during linking, you need to use the ``gnatsymbolize`` tool
-with :switch:`--load` instead of the ``addr2line`` tool. The main difference
-is that you need to copy the Load Address output in the traceback ahead of the
-sequence of addresses. And the default mode of ``gnatsymbolize`` is equivalent
-to that of ``addr2line`` with the above switches, so none of them is needed::
+(PIC), the historical example being Linux dynamic libraries and Windows DLLs,
+which nowadays encompasse Position-Independent Executables (PIE) on recent
+Linux and Windows versions.
+
+In order to translate addresses the source lines with Position-Independent
+Executables on recent Linux and Windows versions, in other words without
+using the switch :switch:`-no-pie` during linking, you need to use the
+``gnatsymbolize`` tool with :switch:`--load` instead of the ``addr2line``
+tool. The main difference is that you need to copy the Load Address output
+in the traceback ahead of the sequence of addresses. And the default mode
+of ``gnatsymbolize`` is equivalent to that of ``addr2line`` with the above
+switches, so none of them is needed::
$ gnatmake stb -g -bargs -E
$ stb
Call stack traceback locations:
0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4
- $ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335
+ $ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335 \
0x4011c4 0x4011f1 0x77e892a4
0x00401373 Stb.P1 at stb.adb:5
with Ada.Text_IO;
with GNAT.Traceback;
with GNAT.Debug_Utilities;
+ with System;
procedure STB is
use Ada;
+ use Ada.Text_IO;
use GNAT;
use GNAT.Traceback;
+ use System;
+
+ LA : constant Address := Executable_Load_Address;
procedure P1 is
TB : Tracebacks_Array (1 .. 10);
begin
Call_Chain (TB, Len);
- Text_IO.Put ("In STB.P1 : ");
+ Put ("In STB.P1 : ");
for K in 1 .. Len loop
- Text_IO.Put (Debug_Utilities.Image (TB (K)));
- Text_IO.Put (' ');
+ Put (Debug_Utilities.Image_C (TB (K)));
+ Put (' ');
end loop;
- Text_IO.New_Line;
+ New_Line;
end P1;
procedure P2 is
end P2;
begin
+ if LA /= Null_Address then
+ Put_Line ("Load address: " & Debug_Utilities.Image_C (LA));
+ end if;
+
P2;
end STB;
$ gnatmake stb -g
$ stb
- In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C#
- 16#0040_1461# 16#0040_11C4# 16#0040_11F1# 16#77E8_92A4#
+ Load address: 0x400000
+ In STB.P1 : 0x40F1E4 0x4014F2 0x40170B 0x40171C 0x401461 0x4011C4 \
+ 0x4011F1 0x77E892A4
You can then get further information by invoking the ``addr2line`` tool or
This program, when built and run, prints a list of addresses which
correspond to the traceback when inside function ``Call_Me_Third``.
- For instance, on x86_64 GNU/Linux:
+ For instance, on x86-64 GNU/Linux:
::
$ gnatmake -g -q foo.adb
$ ./foo
- 0x0000000000402561
- 0x00000000004025EF
- 0x00000000004025FB
- 0x0000000000402611
- 0x00000000004024C7
+ Load address: 0x00005586C9D7D000
+ 0x00005586C9D81105
+ 0x00005586C9D8119B
+ 0x00005586C9D811A7
+ 0x00005586C9D8128C
+ 0x00005586C9D81069
``gnatsymbolize`` can be used to translate those addresses into
code locations as follow:
::
- $ gnatsymbolize foo 0x0000000000402561 0x00000000004025EF \
- 0x00000000004025FB 0x0000000000402611 0x00000000004024C7
- Pck.Call_Me_Third at pck.adb:12
- Pck.Call_Me_Second at pck.adb:20
- Pck.Call_Me_First at pck.adb:25
- Foo at foo.adb:6
- Main at b~foo.adb:184
+ $ gnatsymbolize --load foo 0x00005586C9D7D000 0x00005586C9D81105 \
+ 0x00005586C9D8119B 0x00005586C9D811A7 0x00005586C9D8128C \
+ 0x00005586C9D81069
+ 0x5586c9d81105 Pck.Call_Me_Third at pck.adb:12
+ 0x5586c9d8119b Pck.Call_Me_Second at pck.adb:20
+ 0x5586c9d811a7 Pck.Call_Me_First at pck.adb:25
+ 0x5586c9d8128c Foo at foo.adb:6
+ 0x5586c9d81069 Main at b~foo.adb:199
Switches for ``gnatsymbolize``
------------------------------
:switch:`--load`
Interpret the first address as the load address of the executable.
- This is needed for position-independent executables on Windows.
+ This is needed for position-independent executables on Linux and Windows.
Requirements for Correct Operation
----------------------------------
@copying
@quotation
-GNAT User's Guide for Native Platforms , Nov 18, 2022
+GNAT User's Guide for Native Platforms , Nov 28, 2022
AdaCore
`[warning-as-error]'
Used to tag warning messages that have been converted to error messages by
use of the pragma Warning_As_Error. Note that such warnings are prefixed by
-the string â\80\9cerror: â\80\9c rather than “warning: “.
+the string â\80\9cerror: â\80\9d rather than “warning: “.
@item
`[enabled by default]'
program compiled with debug information.
However the @code{addr2line} tool does not work with Position-Independent Code
-(PIC), the historical example being Windows DLLs, which nowadays encompasses
-Position-Independent Executables (PIE) on recent Windows versions.
+(PIC), the historical example being Linux dynamic libraries and Windows DLLs,
+which nowadays encompasse Position-Independent Executables (PIE) on recent
+Linux and Windows versions.
-In order to translate addresses into the source lines with Position-Independent
-Executables on recent Windows versions, in other words without using the switch
-@code{-no-pie} during linking, you need to use the @code{gnatsymbolize} tool
-with @code{--load} instead of the @code{addr2line} tool. The main difference
-is that you need to copy the Load Address output in the traceback ahead of the
-sequence of addresses. And the default mode of @code{gnatsymbolize} is equivalent
-to that of @code{addr2line} with the above switches, so none of them is needed:
+In order to translate addresses the source lines with Position-Independent
+Executables on recent Linux and Windows versions, in other words without
+using the switch @code{-no-pie} during linking, you need to use the
+@code{gnatsymbolize} tool with @code{--load} instead of the @code{addr2line}
+tool. The main difference is that you need to copy the Load Address output
+in the traceback ahead of the sequence of addresses. And the default mode
+of @code{gnatsymbolize} is equivalent to that of @code{addr2line} with the above
+switches, so none of them is needed:
@example
$ gnatmake stb -g -bargs -E
Call stack traceback locations:
0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4
-$ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335
+$ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335 \
0x4011c4 0x4011f1 0x77e892a4
0x00401373 Stb.P1 at stb.adb:5
with Ada.Text_IO;
with GNAT.Traceback;
with GNAT.Debug_Utilities;
+with System;
procedure STB is
use Ada;
+ use Ada.Text_IO;
use GNAT;
use GNAT.Traceback;
+ use System;
+
+ LA : constant Address := Executable_Load_Address;
procedure P1 is
TB : Tracebacks_Array (1 .. 10);
begin
Call_Chain (TB, Len);
- Text_IO.Put ("In STB.P1 : ");
+ Put ("In STB.P1 : ");
for K in 1 .. Len loop
- Text_IO.Put (Debug_Utilities.Image (TB (K)));
- Text_IO.Put (' ');
+ Put (Debug_Utilities.Image_C (TB (K)));
+ Put (' ');
end loop;
- Text_IO.New_Line;
+ New_Line;
end P1;
procedure P2 is
end P2;
begin
+ if LA /= Null_Address then
+ Put_Line ("Load address: " & Debug_Utilities.Image_C (LA));
+ end if;
+
P2;
end STB;
@end example
$ gnatmake stb -g
$ stb
-In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C#
-16#0040_1461# 16#0040_11C4# 16#0040_11F1# 16#77E8_92A4#
+Load address: 0x400000
+In STB.P1 : 0x40F1E4 0x4014F2 0x40170B 0x40171C 0x401461 0x4011C4 \
+ 0x4011F1 0x77E892A4
@end example
@end quotation
@printindex ge
-@anchor{cf}@w{ }
@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ }
+@anchor{cf}@w{ }
@c %**end of body
@bye
-- The traceback information is in the form of absolute code locations.
-- These code locations may be converted to corresponding source locations
--- using the external addr2line utility, or from within GDB.
+-- using the addr2line or gnatsymbolize utilities, or from within GDB.
-- In order to use this facility, in some cases the binder must be invoked
-- with -E switch (store the backtrace with exception occurrence). Please
-- refer to gnatbind documentation for more information.
--- To analyze the code locations later using addr2line or gdb, the necessary
--- units must be compiled with the debugging switch -g in the usual manner.
--- Note that it is not necessary to compile with -g to use Call_Chain. In
--- other words, the following sequence of steps can be used:
+-- To analyze the code locations later using addr2line, gnatsymbolize or GDB,
+-- the necessary units must be compiled with the debugging switch -g in the
+-- usual manner. Note that it is not necessary to compile with -g to use
+-- Call_Chain. In other words, the following sequence of steps can be used:
-- Compile without -g
-- Run the program, and call Call_Chain
-- Recompile with -g
--- Use addr2line to interpret the absolute call locations (note that
--- addr2line expects addresses in hexadecimal format).
+-- Use addr2line or gnatsymbolize to interpret the absolute call locations
+-- (note that addr2line expects addresses in hexadecimal format).
-- This capability is currently supported on the following targets:
--- AiX PowerPC
+-- AIX PowerPC
-- GNU/Linux x86
-- GNU/Linux PowerPC
-- LynxOS x86
--- LynxOS 178 xcoff PowerPC
--- LynxOS 178 elf PowerPC
+-- LynxOS-178 PowerPC
-- Solaris x86
--- Solaris sparc
+-- Solaris SPARC
-- VxWorks ARM
--- VxWorks7 ARM
-- VxWorks PowerPC
-- VxWorks x86
--- Windows XP
+-- Windows
-- Note: see also GNAT.Traceback.Symbolic, a child unit in file g-trasym.ads
-- providing symbolic trace back capability for a subset of the above targets.
function Call_Chain
(Max_Len : Positive;
Skip_Frames : Natural := 1) return Tracebacks_Array;
- -- Returns up to Max_Len tracebacks corresponding to the current call
+ -- Return up to Max_Len tracebacks corresponding to the current call
-- chain. Result array order is the same as in above procedure Call_Chain
-- except that Skip_Frames says how many of the most recent calls should be
-- excluded from the result, starting with this procedure itself: 1 means
-- exclude the frame for this procedure, 2 means 1 + exclude the frame for
-- this procedure's caller, ...
+ function Executable_Load_Address return System.Address;
+ pragma Import (C,
+ Executable_Load_Address,
+ "__gnat_get_executable_load_address");
+ -- Return the load address of the executable or System.Null_Address if the
+ -- executable has been loaded at the address computed by the static linker.
+ -- This address is needed to interpret the absolute call locations given by
+ -- the subprograms of this unit when Position-Independent Executables (PIE)
+ -- are used on recent GNU/Linux and Windows versions.
+
end GNAT.Traceback;