This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
[PATCH] in_prologue() fix
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: [PATCH] in_prologue() fix
- From: Elena Zannoni <ezannoni at cygnus dot com>
- Date: Tue, 25 Apr 2000 19:12:37 -0400 (EDT)
This is a little convoluted, but the bug is real: after a nexti, gdb
runs until the end of the program.
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.3
diff -c -r1.3 symtab.c
*** symtab.c 2000/04/04 02:08:52 1.3
--- symtab.c 2000/04/25 19:16:58
***************
*** 4426,4436 ****
nosyms:
! /* If func_start is zero (meaning unknown) then we don't know whether pc is
! in the prologue or not. I.E. it might be. */
if (!func_start)
return 1;
/* We need to call the target-specific prologue skipping functions with the
function's start address because PC may be pointing at an instruction that
--- 4426,4441 ----
nosyms:
! /* If func_start is zero (meaning unknown) then we don't know
! whether pc is in the prologue or not. I.E. it might be. */
if (!func_start)
return 1;
+
+ /* If PC is already lower that FUNC_START, it is not part of the
+ function. */
+ if (pc < func_start)
+ return 0;
/* We need to call the target-specific prologue skipping functions with the
function's start address because PC may be pointing at an instruction that
-------
Let me try to explain what's going on.
This test in handle_inferior_event() tells us if we are in a
subroutine call:
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)
{
/* It's a subroutine call. */
[....]
}
If stop_pc is less than ecs->stop_func_start, stop_pc is not in the
stop function at all, however in_prologue() will return true, in the
case there is no line info.
This case happens in the following example (d10v) where DECR_PC_AFTER_BREAK > 0,
and the real stop pc + DECR_PC_AFTER_BREAK is the address of an
instruction of a different function than the one we really stopped at.
In the example below, we stopped at the nop || nop line in main, but
it looks to gdb as we stopped in the function after that, in this case
Test2. At the point of the test above in H.I.E., stop_pc has been
readjusted to be the real place at which we stopped, but
ecs->stop_func_start is the beginning of Test2.
main:
Test1:
ldi r0, #1
ldi r1, #2
bl.l func
nop || nop
Test2:
ldi r0, #1
ldi r1, #2
bl.l func
nop || nop
nop || nop
End_test:
nop
nop
func:
ldi r0, #10
ldi r1, #20
jmp r13
.end
It may be that the real fix is to make ecs->stop_func_start be the
beginning of the function where the adjusted stop_pc is. However that
would require several changes to H.I.E. But in any event in_prologue()
is wrong for this particular case.
Elena