Bug 11385 - cannot catch Ada exceptions
Summary: cannot catch Ada exceptions
Status: UNCONFIRMED
Alias: None
Product: gdb
Classification: Unclassified
Component: ada (show other bugs)
Version: 7.0
: P1 critical
Target Milestone: 7.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-16 14:28 UTC by Mark Gardinier
Modified: 2014-09-07 20:09 UTC (History)
5 users (show)

See Also:
Host: i686-redhat-linux-gnu
Target: i686-redhat-linux-gnu
Build: i686-redhat-linux-gnu
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Gardinier 2010-03-16 14:28:31 UTC
I keep getting "cannot insert catchpoints in this configuration when debugging a
gnat program with gdb.  Everything else works fine but not being able to trap on
an exception being raised is not very good.

ATI@ATI TOOLS]$ gdb fixfortran
GNU gdb (GDB) Fedora (7.0.1-33.fc12)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/ATI/DOTSBIR/Phase_II/SCOPE/CODE/TOOLS/fixfortran...done.
(gdb) break main
Breakpoint 1 at 0x8049d2d: file
/home/ATI/DOTSBIR/Phase_II/SCOPE/CODE/TOOLS/b~fixfortran.adb, line 198.
(gdb) run
Starting program: /home/ATI/DOTSBIR/Phase_II/SCOPE/CODE/TOOLS/fixfortran 

Breakpoint 1, main (argc=1, argv=(system.address) 0xbffff184,
envp=(system.address) 0xbffff18c)
    at /home/ATI/DOTSBIR/Phase_II/SCOPE/CODE/TOOLS/b~fixfortran.adb:198
198	      Ensure_Reference : aliased System.Address :=
Ada_Main_Program_Name'Address;
(gdb) catch exception
Cannot insert catchpoints in this configuration.
(gdb)
Comment 1 Simon Wright 2011-10-19 14:17:29 UTC
I find the same with the GDB git tree (at commit 4b8a2e28391c990494a9eb60adcbd840af952fe6, Wed Oct 19 07:17:11 2011 +0000) on Mac OS X Lion, debugging a GCC 4.6.0 program.

I think there's something about the way ada-lang.c sniffs for the Ada-specific symbols that fails to find the required symbol (it looks for __gnat_debug_raise_exception, in s-except.o), though I haven't yet been able to spot any difference; the arguments passed to lookup_symbol_aux() look the same. Should I dig deeper?

If I first set an ordinary breakpoint on that symbol
   (gdb) break __gnat_debug_raise_exception
then "catch exception" works!

This problem doesn't happen with GNAT GPL 2011-generated code, which is based on GCC 4.5.3.
Comment 2 Simon Wright 2011-10-19 14:28:16 UTC
It seems to be something about the way GCC 4.6.0 generates object code; if I write hi.c

void __gnat_debug_raise_exception(void)
{
}

int main(void)
{
  return 0;
}

and compile with GCC 4.6.0, 'catch exception' works first time (in other words, the ada-lang.c lookup is OK).
Comment 3 Simon Wright 2011-10-19 19:55:27 UTC
When 'break __gnat_debug_raise_exception' finds the symbol, it actually finds it in lookup_minimal_symbol() in minsyms.c, after attempts via lookup_symbol() have failed. The backtrace is

#0  lookup_minimal_symbol (name=0x7fff5fbfee00 "__gnat_debug_raise_exception", sfile=0x0, objf=0x0) at minsyms.c:299
#1  0x000000010017a41a in decode_variable (copy=0x7fff5fbfee00 "__gnat_debug_raise_exception", funfirstline=1, canonical=0x7fff5fbff208, file_symtab=0x0) at linespec.c:2125
#2  0x00000001001777d4 in decode_line_1 (argptr=0x7fff5fbff2d0, funfirstline=1, default_symtab=0x0, default_line=0, canonical=0x7fff5fbff208) at linespec.c:1072
#3  0x0000000100102e9e in parse_breakpoint_sals (address=0x7fff5fbff2d0, sals=0x7fff5fbff260, canonical=0x7fff5fbff208) at breakpoint.c:7591
#4  0x0000000100103be2 in create_breakpoint (gdbarch=0x1010a5a10, arg=0x100a0a1ce "", cond_string=0x0, thread=0, parse_condition_and_thread=1, tempflag=0, type_wanted=bp_breakpoint, ignore_count=0, pending_break_support=AUTO_BOOLEAN_AUTO, ops=0x1005f74c0, from_tty=1, enabled=1, internal=0) at breakpoint.c:7825

Can we alter the check in ada-lang.c to use lookup_minimal_symbol()? What makes it a minimal symbol when compiled by Ada (s-except.adb) rather than C (my hi.c, in Comment 2)?
Comment 4 Simon Wright 2011-10-20 12:49:28 UTC
Results unchanged with gcc-4.7-180238.
Comment 5 Florian Weimer 2012-01-30 06:46:09 UTC
(In reply to comment #3)

> Can we alter the check in ada-lang.c to use lookup_minimal_symbol()? What makes
> it a minimal symbol when compiled by Ada (s-except.adb) rather than C (my hi.c,
> in Comment 2)?

I think minimal symbols are symbols which do not come from debugging information.  Does Ada support work even if the run-time library is dynamically linked and compiled without debugging information?  Then using the minimal symbol seems okay.  Otherwise, GDB should just print a better error message, and the fix is not to strip the Ada run-time libraries.
Comment 6 Simon Wright 2012-02-02 11:22:19 UTC
(In reply to comment #5)
> I think minimal symbols are symbols which do not come from debugging
> information.  Does Ada support work even if the run-time library is dynamically
> linked and compiled without debugging information?  Then using the minimal
> symbol seems okay.  Otherwise, GDB should just print a better error message,
> and the fix is not to strip the Ada run-time libraries.

I believe the dynamic Ada run-time libraries are stripped, but when an Ada program is built with -g, it uses the static Ada libraries.

The Makefile for the Ada RTS (for 4.7) explicitly compiles s-excdeb.adb, which is where 4.7 keeps the problematic symbol, for debugging:

# compile s-excdeb.o without optimization and with debug info to let the
# debugger set breakpoints and inspect subprogram parameters on exception
# related events.

In 4.6, the symbol’s in s-except.adb, I don’t have the source tree to hand but I expect it’s the same.

In case there’s any stripping going on during RTS installation, I rebuilt my test program with an explicit recompilation of s-except:

$ gnatmake -c -u -f -g /opt/gcc-4.6.0-x86_64/lib/gcc/x86_64-apple-darwin10/4.6.0/adainclude/s-except.adb -O0
gcc -gnatpg -c -I/opt/gcc-4.6.0-x86_64/lib/gcc/x86_64-apple-darwin10/4.6.0/adainclude/ -g -O0 -I- /opt/gcc-4.6.0-x86_64/lib/gcc/x86_64-apple-darwin10/4.6.0/adainclude/s-except.adb

$ gnatmake -g -a stbga.adb -largs -v
gnatbind -x stbga.ali
gnatlink stbga.ali -g -v

GNATLINK 4.6.0
Copyright (C) 1995-2010, Free Software Foundation, Inc.
gcc -c -g -gnatA -gnatWb -gnatiw -g -gnatws /Users/simon/tmp/b~stbga.adb
/opt/gcc-4.6.0-x86_64/bin/gcc b~stbga.o ./s-except.o ./stbga.o -g -o stbga -L./ -L/opt/gcc-4.6.0-x86_64/lib/gcc/x86_64-apple-darwin10/4.6.0/adalib/ /opt/gcc-4.6.0-x86_64/lib/gcc/x86_64-apple-darwin10/4.6.0/adalib/libgnat.a

(note the explicit “./s-except.o” & the link against the installed libgnat.a)

but still

$ gdb stbga
GNU gdb (GDB) 7.3.50.20111019-cvs
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin11".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /Users/simon/tmp/stbga...
warning: can't find section '*UND*' in OSO file /opt/gcc-4.6.0-x86_64/lib/gcc/x86_64-apple-darwin10/4.6.0/adalib/libgnat.a(targext.o)
done.
(gdb) catch exception
Unable to insert catchpoint. Try to start the program first.
Comment 7 Simon Wright 2014-05-22 11:25:05 UTC
I still get this problem with GDB 7.7, GCC 4.9.0 on x86_64-apple-darwin13.

Using dwarfdump --debug-info, hi.o (see my comment #2) says

0x0000009b:     TAG_subprogram [2]
                 AT_external( 0x01 )
                 AT_name( "__gnat_debug_raise_exception" )
                 AT_decl_file( "/Users/simon/tmp/hi.c" )
                 AT_decl_line( 1 )
                 AT_prototyped( 0x01 )
                 AT_low_pc( 0x0000000000000000 )
                 AT_high_pc( 0x0000000000000001 )
                 AT_frame_base( rsp+8 )

whereas the RTS s-excdeb.o says

0x0000024b:     TAG_subprogram [9] *
                 AT_external( 0x01 )
                 AT_name( "system__exceptions_debug__debug_raise_exception" )
                 AT_decl_file( "/Users/simon/tmp/gcc-4.9.0/gcc/ada/s-excdeb.adb" )
                 AT_decl_line( 40 )
                 AT_MIPS_linkage_name( "__gnat_debug_raise_exception" )
                 AT_prototyped( 0x01 )
                 AT_low_pc( 0x0000000000000000 )
                 AT_high_pc( 0x000000000000000c )
                 AT_frame_base( 0x00000000
                    0x0000000000000000 - 0x0000000000000001: rsp+8
                    0x0000000000000001 - 0x0000000000000004: rsp+16
                    0x0000000000000004 - 0x000000000000000b: rbp+16
                    0x000000000000000b - 0x000000000000000c: rsp+8 )
                 AT_sibling( {0x000002c2} )

and there’s one obvious difference: in the C version, the AT_Name is the one being looked for (__gnat_debug_raise_exception), whereas in the Ada version it’s the AT_MIPS_linkage_name.

standard_lookup() (ada-lang.c:4259) says
  sym = lookup_symbol_in_language (name, block, domain, language_c, 0);

Could it be the ‘language_c’ that’s the problem? .. will check further (I see that standard_lookup() is called in several places, so maybe not).
Comment 8 Simon Wright 2014-05-24 16:46:04 UTC
(In reply to Simon Wright from comment #7)

Well, that was misleading.

Current state of investigation (all work on Mac OS X 10.9.2/10.9.3 (Darwin 13.1.0/13.2.0), GDB 7.7:

If the program being debugged was built with GNAT GPL 2011/2/3/4, then everything is OK.

If the program being debugged was built with FSF GCC 4.6/7/8/9 the problem arises; ‘catch exception’ fails.

One cure is to reference one of the symbols in s-excdeb.o first, perhaps by printing it:

Reading symbols from inf...done.
(gdb) catch exception
Your Ada runtime appears to be missing some debugging information.
Cannot insert Ada exception catchpoint in this configuration.
(gdb) p __gnat_debug_raise_exception
$1 = {<text variable, no debug info>} 0x10000b692 <__gnat_debug_raise_exception>
(gdb) catch exception
Catchpoint 1: all Ada exceptions

Another is to read all the symbols to start with:

$ gdb -readnow foo
[...]
Reading symbols from inf...expanding to full symbols...done.
(gdb) catch exception
Catchpoint 1: all Ada exceptions

'p __gnat_debug_raise_exception’ actually reports the minsym, but for some reason then goes on to read the full symbol, i.e. to load the symtab, which is what ‘catch exception’ requires.

So far I haven’t been able to work out why using different compilers should affect this result.