This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello, We have recently noticed this failure. To demonstrate it, you'll need to use the GNAT compiler because the sources that caused the problem are in the GNAT runtime. Use the following little Ada program: with Ada.Text_IO; use Ada.Text_IO; procedure Foo is begin Put_Line ("Hello World."); Put_Line ("Me again."); end Foo; Compile it using the following command: % gnatmake -g foo The following GDB transcript demonstrates the problem: (gdb) b foo.adb:5 Breakpoint 1 at 0x120015a18: file foo.adb, line 5. (gdb) run Starting program: /[...]/foo Breakpoint 1, _ada_foo () at foo.adb:5 5 Put_Line ("Hello World."); (gdb) n 0x0000000120023fe8 in ada__text_io__put_line__2 () at a-textio.adb:6 6 a-textio.adb: No such file or directory. in a-textio.adb The expected behavior was for GDB to stop at line 6 of foo.adb, not inside Put_Line: (gdb) n Hello World. 6 Put_Line ("Me again."); Here is what happens. First, after having hit the breakpoint at line 5, GDB sees the following code for line 5: #.stabn 68,0,5,$LM2 lda $1,$LC0 lda $2,$LC1 bis $31,$1,$16 bis $31,$2,$17 jsr $26,ada__text_io__put_line__2 ldgp $29,0($26) (for the curious, LC0 and LC1 are the string "Hello World." and its bounds). That's the assembly code as generated by GCC. However, if you look at the actual assembly code, as produced after the link, you will see that the OSF/1 linker has done a little optimization (which I find is done quite often). Here is how the jsr instruction has been modified: bsr ra,0x120023fe8 <ada__text_io__put_line__2+8> The jump is actually made to the third instruction of Put_Line. So when GDB starts doing the "next" operation, it eventually receives a sigtrap. Normally, GDB should detect that we are inside a function call and therefore should step_over_function(). But it fails to recognize this situation because of the conjunction of the following two factors: 1. The stop_pc is not at the "official" Put_Line function start address 2. The function does not have a prologue So the following test fails in infrun.c:handle_inferior_event() fails, and GDB incorrectly thinks that we have landed at the next line of code: if (((stop_pc == ecs->stop_func_start /* Quick test */ || in_prologue (stop_pc, ecs->stop_func_start)) && !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, ecs->stop_func_name) || ecs->stop_func_name == 0) Just FYI, the first instructions of Put_Line are: <ada__text_io__put_line__2+0>: ldah gp,8191(t12) <ada__text_io__put_line__2+4>: lda gp,-1088(gp) <ada__text_io__put_line__2+8>: ldq t8,-28008(gp) <ada__text_io__put_line__2+12>: nop <ada__text_io__put_line__2+16>: mov a0,t0 <ada__text_io__put_line__2+20>: mov a1,a2 <ada__text_io__put_line__2+24>: ldq a0,0(t8) <ada__text_io__put_line__2+28>: mov t0,a1 <ada__text_io__put_line__2+32>: ldq t12,-30040(gp) <ada__text_io__put_line__2+36>: jmp zero,(t12),0x120023d50 <ada__text_io__put_line> If it wasn't for the linker optimization, the check for "top_pc == ecs->stop_func_start" would probably have kicked in, and all would have been fine. So I suggest we refine this test to use a new gdbarch function which, by default, would be the exact equivalent of this equality check. But I then provide an OSF/1-specific version of this function that checks that we stopped either at the first instruction of the function, or right after the couple of instructions forming the ldgp macro. 2003-12-01 J. Brobecker <brobecker@gnat.com> * gdbarch.sh (at_function_start): New gdbarch function. * gdbarch.h: Regenerate. * gdbarch.c: Regenerate. * arch-utils.c (default_at_function_start): New function. * arch-utils.h (default_at_function_start): Add prototype. * infrun.c (handle_inferior_event): Use new gdbarch function at_function_start to properly detect function calls during STEP_OVER_ALL. * alpha-osf1-tdep.c (alpha_osf1_at_function_start): New function. (alpha_osf1_init_abi): Set the gdbarch at_function_call function. Tested on alpha-osf1 and x86-linux. No regression. OK to apply? Thanks, -- Joel
Attachment:
next.diff
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |