This is the mail archive of the gdb-patches@sourceware.cygnus.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]

[PATCH] in_prologue() fix



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]