msys2 / MINGW-packages

Package scripts for MinGW-w64 targets to build under MSYS2.
https://packages.msys2.org
BSD 3-Clause "New" or "Revised" License
2.24k stars 1.21k forks source link

Cannot catch Ada exceptions #20790

Open jcmoyer opened 4 months ago

jcmoyer commented 4 months ago

Description / Steps to reproduce the issue

With both mingw-w64-x86_64-gcc-ada and mingw-w64-ucrt-x86_64-gcc-ada, gdb is unable to catch Ada exceptions even when compiling with -g.

main.adb:

procedure main is
   E : exception;
begin
   raise E with "test";
end main;

Compile with debug info and start gdb: gnatmake -g main && gdb ./main.exe:

(gdb) catch exception
Your Ada runtime appears to be missing some debugging information.
Cannot insert Ada exception catchpoint in this configuration.
(gdb) r
Starting program: main.exe
[New Thread 5472.0x2790]
[New Thread 5472.0x254c]

raised MAIN.E : test
[Thread 5472.0x2790 exited with code 1]
[Thread 5472.0x254c exited with code 1]
[Inferior 1 (process 5472) exited with code 01]
(gdb) bt
No stack.

Expected behavior

Exceptions should be catchable.

Actual behavior

Exceptions cannot be caught.

Verification

Windows Version

MINGW64_NT-10.0-19044

MINGW environments affected

Are you willing to submit a PR?

Yes

jcmoyer commented 4 months ago

I can catch exceptions with mingw64 gdb when the binary is built with the GNAT-FSF distribution of gcc.

GNAT-FSF ships a 19M libgnat.a mingw64 ships a 7M libgnat.a

Both distributions appear to have debug symbols, and looking at gdb's source the message about missing debug info should be printed when __gnat_debug_raise_exception can't be located. mingw64's distribution contains that symbol according to nm --debug-syms. I can place a breakpoint there and catch the exception before it's thrown:

(gdb) break __gnat_debug_raise_exception
Breakpoint 1 at 0x140007a9b
(gdb) r
Starting program: main.exe
[New Thread 6164.0x2358]
[New Thread 6164.0x1f38]
[New Thread 6164.0x23cc]

Thread 1 hit Breakpoint 1, 0x00007ff7c02d7a9b in __gnat_debug_raise_exception ()
(gdb) bt
#0  0x00007ff7c02d7a9b in __gnat_debug_raise_exception ()
#1  0x00007ff7c02d3438 in ada.exceptions.complete_occurrence ()
#2  0x00007ff7c02d344d in ada.exceptions.complete_and_propagate_occurrence ()
#3  0x00007ff7c02d34b9 in __gnat_raise_exception ()
#4  0x00007ff7c02d19ce in main () at main.adb:4

Besides that it looks like the GNAT-FSF libgnat.a has extra sections that the mingw64 one does not: .debug_abbrev .debug_aranges .debug_frame .debug_info .debug_line .debug_line_str, could this be a problem?

jcmoyer commented 4 months ago

I was able to solve this by modifying mingw-w64-gcc PKGBUILD to use options=('!emptydirs' '!strip') and building gcc myself. Now I can catch Ada exceptions. I get why the binaries are stripped (it adds 3.6G to the package size!) but is there a better approach for solving this problem?