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

Liang Cheng
2011-09-19T22:18:00Z

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

(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

On Mon, Sep 19, 2011 at 10:57 AM, Liang Cheng <liang.cheng555@gmail.com> wrote:
> Oh.. I just put too much focus on gdb server side.. ;)
> Built a gdb from gdb 7.3.1 source, although it behaves better (no
> segmentation fault), stepping
> is still not right yet.
>
> (gdb) n
> 286         z = xa_fun_in_lib(10);
> (gdb) set debug infrun 1
> (gdb) show debug infrun
> Inferior debugging is 1.
> (gdb) s
> infrun: clear_proceed_status_thread (Thread 1874.1874)
> infrun: proceed (addr=0xffffffff, signal=144, step=1)
> infrun: resume (step=1, signal=0), trap_expected=0
> infrun: wait_for_inferior (treat_exec_as_sigtrap=0)
> 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 = 0x8d1c
> infrun: software single step trap for Thread 1874.1874
> infrun: stepping inside range [0x8d18-0x8d24]
> 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 = 0x8628
> 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 = 0x862c
> 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 = 0x8630
> 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
> infrun: software single step trap for Thread 1874.1874
> infrun: stepping inside range [0x8d18-0x8d24]
> 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 = 0x8d22
> infrun: software single step trap for Thread 1874.1874
> infrun: stepping inside range [0x8d18-0x8d24]
> 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 = 0x8d24
> infrun: software single step trap for Thread 1874.1874
> infrun: stepped to a different line
> infrun: stop_stepping
> 289         res = (*engine)->Realize(engine, XA_BOOLEAN_FALSE);
> (gdb) display /i $pc
> 1: x/i $pc
> => 0x8d24 <main+96>:    ldr     r3, [r7, #48]   ; 0x30
> (gdb) info address xa_fun_in_lib
> Symbol "xa_fun_in_lib(int)" is a function at address 0x800036fc.
>
> On Fri, Sep 16, 2011 at 8:28 PM, Yao Qi <yao@codesourcery.com> wrote:
>> On 09/17/2011 04:03 AM, Liang Cheng wrote:
>>> Yao/Hui,
>>>
>>> Built a gdbserver based on gdb 7.3.1,  and I get the exactly same error.
>>> The gdb that I used is arm-eabi-4.4.3.
>>>
>>
>> You may misunderstand my point.  I suggest that you build recent gdb
>> instead of gdbserver.  AFAICS, this problem is related to gdb, rather
>> than gdbserver.
>>
>> "arm-eabi-4.4.3" is not a right version of gdb.
>>
>>> Here is debug output. Next step is to try gdb trunk.
>>
>> Please build gdb from gdb trunk.
>>
>>>
>>> Breakpoint 1, main (argc=1, argv=0xbed00cb4) at vendor/altestavplayback.c:284
>>> 284         CheckErr(res);
>>> 1: x/i $pc
>>> => 0x8d12 <main+78>:    ldr     r0, [r7, #52]   ; 0x34
>>> (gdb) n
>>> 286         z = xa_fun_in_lib(10);
>>> 1: x/i $pc
>>> => 0x8d18 <main+84>:    mov.w   r0, #10
>>> (gdb) set debug infrun 1
>>> (gdb) show debug infrun
>>> Inferior debugging is 1.
>>> (gdb) s
>>> infrun: clear_proceed_status_thread (Thread 746.746)
>>> infrun: proceed (addr=0xffffffff, signal=144, step=1)
>>> infrun: resume (step=1, signal=0), trap_expected=0
>>> infrun: wait_for_inferior (treat_exec_as_sigtrap=0)
>>> infrun: target_wait (-1, status) =
>>> infrun:   746 [Thread 746.746],
>>> infrun:   status->kind = stopped, signal = SIGTRAP
>>> infrun: infwait_normal_state
>>> infrun: TARGET_WAITKIND_STOPPED
>>> infrun: stop_pc = 0x8d1c
>>> infrun: software single step trap for Thread 746.746
>>> infrun: stepping inside range [0x8d18-0x8d24]
>>> infrun: resume (step=1, signal=0), trap_expected=0
>>> infrun: prepare_to_wait
>>> infrun: target_wait (-1, status) =
>>> infrun:   746 [Thread 746.746],
>>> infrun:   status->kind = stopped, signal = SIGTRAP
>>> infrun: infwait_normal_state
>>> infrun: TARGET_WAITKIND_STOPPED
>>> infrun: stop_pc = 0x8628
>>> infrun: software single step trap for Thread 746.746
>>> 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:   746 [Thread 746.746],
>>> infrun:   status->kind = stopped, signal = SIGTRAP
>>> infrun: infwait_normal_state
>>> infrun: TARGET_WAITKIND_STOPPED
>>> infrun: stop_pc = 0x862c
>>> infrun: software single step trap for Thread 746.746
>>> 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:   746 [Thread 746.746],
>>> infrun:   status->kind = stopped, signal = SIGTRAP
>>> infrun: infwait_normal_state
>>> infrun: TARGET_WAITKIND_STOPPED
>>> infrun: stop_pc = 0x8630
>>> infrun: software single step trap for Thread 746.746
>>> infrun: stepped into dynsym resolve code
>>> infrun: resume (step=1, signal=0), trap_expected=0
>>
>> GDB is trying to single step this instruction,
>>
>>   0x8630:      ldr     pc, [r12, #2820]!       ; 0xb04
>>
>> at this point, GDB will compute the "next pc" of this instruction, and
>> set breakpoint on that address.  GDB 7.2 can (or should) compute the
>> "next pc" correctly, but may not set single-step breakpoint correctly
>> for correct execution state.
>>
>> Ulrich had a patch to address this issue, which might be the cause of
>> your problem.
>>
>>  [rfc, arm] Always use correct execution state for single-step breakpoints
>>  http://sourceware.org/ml/gdb-patches/2011-03/msg01077.html
>>
>> This patch should be in 7.3.1.  If my assumption above is correct, using
>> gdb 7.3.1 or cvs trunk should fix your problem.
>>
>>> infrun: prepare_to_wait
>>> infrun: target_wait (-1, status) =
>>> infrun:   746 [Thread 746.746],
>>> infrun:   status->kind = stopped, signal = SIGSEGV
>>> infrun: infwait_normal_state
>>> infrun: TARGET_WAITKIND_STOPPED
>>> infrun: stop_pc = 0x8d22
>>> infrun: random signal 11
>>>
>>> Program received signal SIGSEGV, Segmentation fault.
>>> infrun: stop_stepping
>>> 0x00008d22 in main (argc=1, argv=0xbed00cb4) at vendor/altestavplayback.c:286
>>> 286         z = xa_fun_in_lib(10);
>>> 1: x/i $pc
>>> => 0x8d22 <main+94>:    str     r3, [r7, #44]   ; 0x2c
>>>
>>> On Fri, Sep 16, 2011 at 8:55 AM, Yao Qi <yao@codesourcery.com> wrote:
>>>> On 09/16/2011 12:39 AM, Liang Cheng wrote:
>>>>> Sorry for not being clear.
>>>>> Here is the debug session getting SIGSEGV. xa_fun_in_lib is the
>>>>> function defined in shared library, and its symbols has been found by
>>>>> gdb.  Step instruction also caused the same issue. The reason that I
>>>>> attach those disassemble dump is to avoid rounds of ask-give.  Let me
>>>>> know if disassemble of the piece of code is needed.  Any idea of why
>>>>> it happens?
>>>>>
>>>>
>>>> This debug session is much clear than last one.  Thanks.
>>>>
>>>>> Breakpoint 1, main (argc=1, argv=0xbef25ca4) at vendor/altestavplayback.c:284
>>>>> 284         CheckErr(res);
>>>>> 3: x/i $pc
>>>>> => 0x8d12 <main+78>:    ldr     r0, [r7, #52]   ; 0x34
>>>>> (gdb) n
>>>>> 286         z = xa_fun_in_lib(10);
>>>>> 3: x/i $pc
>>>>> => 0x8d18 <main+84>:    mov.w   r0, #10
>>>>> (gdb) s
>>>>>
>>>>
>>>> Before you run `step', turn on some debug output first.  Like this `set
>>>> debug infrun 1'.  Then, when you run `step', you can see some debug
>>>> output, which will show how PC is changed and events inferior gets
>>>> during command `step'.
>>>>
>>>> However, before we go into the details of debug output, could you check
>>>> whether GDB cvs trunk works or not.  You just have to build gdb for arm,
>>>> and I think GDB cvs trunk should be able to work with your 7.2 gdbserver.
>>>>
>>>>> Program received signal SIGSEGV, Segmentation fault.
>>>>> 0x00008d22 in main (argc=1, argv=0xbef25ca4) at vendor/altestavplayback.c:286
>>>>> 286         z = xa_fun_in_lib(10);
>>>>> 3: x/i $pc
>>>>> => 0x8d22 <main+94>:    str     r3, [r7, #44]   ; 0x2c
>>>>> (gdb) info address xa_fun_in_lib
>>>>> Symbol "xa_fun_in_lib(int)" is a function at address 0x800036fc.
>>>>>
>>>>> On Thu, Sep 15, 2011 at 11:13 AM, Yao Qi <yao@codesourcery.com> wrote:
>>>>>> On 09/15/2011 12:21 AM, Liang Cheng wrote:
>>
>>
>> --
>> Yao (齐尧)
>>
>