When faced with an error which causes an exception, what is your approach for debugging the issue?
I have tried using -Es in Binder accompanied with -g in Compiler and Binder. However, this just gives me a stack trace with addresses, which then passing to addr2line does not seem to work ( maybe because of it being PIE ? ).
EDIT: it actually gives different addresses for what is the same call stack in different runs
Furthermore, I have tried using gdb’s command catch exception but it complains that the runtime does not have the necessary debugging information. For this it may be useful to note that I am using voidlinux-musl.
There is a package: GNAT.Exception_Actions. Use it to set an exception handler. Inside the handler you can trace the exception and print the call stack using this snippet:
procedure Call_Stack is
use GNAT.Traceback, GNAT.Traceback.Symbolic;
TB : Tracebacks_Array (1..1_000); Len : Natural;
begin
Call_Chain (TB, Len); Put_Line (Symbolic_Traceback (TB (1..Len)));
end Call_Stack;
As for the rest, from my experience:
-Es does not work
gdb is useless in most cases
expect nasty surprizes on ARM targets
expect issues with tracing relocatable libraries
I never develop on ARM. First I make it work on x86 under Windows. Then I do a short check under a Linux for x86. If both work chances are good that ARM would be OK.
I am in X86, just using the musl libc implementation. I tried your snippet but it works the same as -Es for me, it just gives the backtrace addresses but nothing else .
example:
raised ADA.ASSERTIONS.ASSERTION_ERROR : failed precondition from rv-instruction-encoding.adb:728
0x7f752b2b6c21 ??? at ???
0x560b6e4fb8ba ??? at ???
0x560b6e4fe48f ??? at ???
0x560b6e525955 ??? at ???
0x560b6e525e5a ??? at ???
0x560b6e4f2ebd ??? at ???
0x560b6e4f3490 ??? at ???
0x7f752b52ae09 ??? at ???
I have .debug_info and peers in the executable elf. Also, gdb seems to work just fine for stepping, next, etc. Using backtrace gives the backtrace correctly, with symbols included.
project Main is
for Main use ("main.adb");
for Source_Files use ("main.adb");
for Object_Dir use "obj";
package Compiler is
for Default_Switches ("Ada") use ("-g");
end Compiler;
package Binder is
for Default_Switches ("Ada") use ("-g", "-Es");
end Binder;
end Main;
Explicit exception
main.adb
with Ada.Text_IO;
procedure Main is
begin
Ada.Text_IO.Put_Line ("~ Ada Lovelace ~");
raise Program_Error;
end Main;
output
~ Ada Lovelace ~
raised PROGRAM_ERROR : main.adb:7 explicit raise
0x56094691244b ??? at ???
0x560946912940 ??? at ???
0x7f89b38fee09 ??? at ???
Call_Stack
main.adb
with Ada.Text_IO;
with GNAT.Traceback, GNAT.Traceback.Symbolic;
procedure Main is
procedure Call_Stack is
use Ada.Text_IO, GNAT.Traceback, GNAT.Traceback.Symbolic;
TB : Tracebacks_Array (1..1_000); Len : Natural;
begin
Call_Chain (TB, Len); Put_Line (Symbolic_Traceback (TB (1..Len)));
end Call_Stack;
begin
Ada.Text_IO.Put_Line ("~ Ada Lovelace ~");
Call_Stack;
end Main;
output
~ Ada Lovelace ~
0x5577db8594e3 ??? at ???
0x5577db859648 ??? at ???
0x5577db859b6a ??? at ???
0x7f5284bdfe09 ??? at ???
Void Linux does not appear to have a similar package to that one. I have seen that package is availiable in Alpine Linux. /usr/lib/libc.so does have debug_info and others too.
Here is what it looks like in the debugger:
Reading symbols from ./obj/main...
(gdb) start
Temporary breakpoint 1 at 0x3608: file /home/xxxx/Codeberg/rv_emu/hello_world/main.adb, line 5.
Starting program: /home/xxxx/Codeberg/rv_emu/hello_world/obj/main
Temporary breakpoint 1, main () at /home/xxxx/Codeberg/rv_emu/hello_world/main.adb:5
5 procedure Main is
(gdb) catch exception
❌️ Your Ada runtime appears to be missing some debugging information.
Cannot insert Ada exception catchpoint in this configuration.
(gdb)
I recommend the following flags: -Og (optimize for debugging), -ggdb generate GDB friendly info, -gnatVa enable all checks, -gnatwa enable all common warnings. Then in GDB do the catch exception as you did but also catch assert, which seems to be also taking place for you. You can also rebuild the entire RunTime System (RTS) with these flags and if the error takes place in the RTS, you will get all the symbols. For this, please, refer to 3. The GNAT Compilation Model — GNAT User's Guide for Native Platforms 27.0w documentation