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

Re: GDB 7.2 gets SIGSEGV when step into a function in a shared library


On 09/20/2011 06:17 AM, Liang Cheng wrote:
> But it seems to close what I want. But the extension gets the PC
> wrong, it should be  0x800036fd.
> Why we use
>                   nextpc = (CORE_ADDR)read_memory_integer ((CORE_ADDR) base,
>                                                             4, byte_order);
> instead of
>                   nextpc = (CORE_ADDR)read_memory_unsigned integer
> ((CORE_ADDR) base,
>                                                             4, byte_order);
> in arm-tdep.c::arm_get_next_pc_raw? Below is the stack in debug session of gdb.
> 

Thanks for your analysis.  We should use read_memory_unsigned_interger
here, IMO.

> (gdb) c
> Continuing.
> 
> Breakpoint 1, arm_get_next_pc (frame=0x40d9720, pc=34352) at arm-tdep.c:4854
> 4854    {
> (gdb) bt
> #0  arm_get_next_pc (frame=0x40d9720, pc=34352) at arm-tdep.c:4854
> #1  0x0000000000431b0c in arm_linux_software_single_step
> (frame=0x40d9720) at arm-linux-tdep.c:751
> #2  0x00000000004d8321 in maybe_software_singlestep
> (gdbarch=0x13cc920, pc=34352) at infrun.c:1577
> #3  0x00000000004dabad in resume (step=1, sig=TARGET_SIGNAL_0) at infrun.c:1689
> #4  0x00000000004dfbf0 in proceed (addr=<value optimized out>,
> siggnal=TARGET_SIGNAL_DEFAULT, step=1) at infrun.c:2128
> #5  0x00000000004d2227 in step_once (skip_subroutines=0,
> single_inst=1, count=1, thread=-1) at infcmd.c:1046
> #6  0x00000000004d40d4 in step_1 (skip_subroutines=0, single_inst=1,
> count_string=0x0) at infcmd.c:894
> 
> (gdb) n
> 4857      if (arm_frame_is_thumb (frame))
> (gdb) n
> 4866          if (nextpc == pc)
> (gdb) p pc
> $1 = 34352
> (gdb) p /x pc
> $2 = 0x8630
> (gdb) p /x nextpc
> $3 = 0xffffffff800036fd
> 

The value of nextpc here may explain why inferior stops at the point of
returning from xa_fun_in_lib, rather than the entry of it.

On 09/19/2011 11:57 PM, Liang Cheng wrote:
> infrun: stop_pc = 0x8630

   0x8630:      ldr     pc, [r12, #2820]!

inferior will go to 0x800036fc.

> infrun: software single step trap for Thread 1874.1874
> infrun: stepped into dynsym resolve code
> infrun: resume (step=1, signal=0), trap_expected=0
> infrun: prepare_to_wait
> infrun: target_wait (-1, status) =
> infrun:   1874 [Thread 1874.1874],
> infrun:   status->kind = stopped, signal = SIGTRAP
> infrun: infwait_normal_state
> infrun: TARGET_WAITKIND_STOPPED
> infrun: stop_pc = 0x8d20

However, inferior stops at 0x8d20,

  0x00008d1c <+88>:    blx     0x8628
  0x00008d20 <+92>:    mov     r3, r0

The reason for this symptom is gdb will insert software single-step
breakpoint at function return address (value of LR register) if the
next_pc is greater than 0xffff0000, as the following code shows

static int
arm_linux_software_single_step (struct frame_info *frame)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct address_space *aspace = get_frame_address_space (frame);
  CORE_ADDR next_pc = arm_get_next_pc (frame, get_frame_pc (frame));

  /* The Linux kernel offers some user-mode helpers in a high page.  We can
     not read this page (as of 2.6.23), and even if we could then we
couldn't
     set breakpoints in it, and even if we could then the atomic operations
     would fail when interrupted.  They are all called as functions and
return
     to the address in LR, so step to there instead.  */
  if (next_pc > 0xffff0000)
    next_pc = get_frame_register_unsigned (frame, ARM_LR_REGNUM);

  arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc);

  return 1;
}

-- 
Yao (éå)


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