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

Liang Cheng
2011-09-14T16:21:42Z

Hi,

The application and library under debug were built for ARM. The
target is running Android OS,
and the host is Linux X86 64. As long as we try to step into the
function xa_fun_in_lib, it would
cause segmentation fault in gdb. Same thing happened if step the instructions.

Here are the experiments I did for this issue, and some notes.

0/. Apparently the app is built into ARM instruction, and the lib is
built into Thumb instruction.
1/. The symbols of xa_fun_in_lib is good.
2./ If I set breakpoint at xa_fun_in_lib, I would be able to step into
the function once the breakpoint
is hit.
3/. In order to see which address it tries to access, I manually
changed the vPacket to use 's',
and stepped the instruction " 0x8630: ldr pc, [r12, #2820]!
; 0xb04". Also I added
some instrumentation code in gdbserver side
linux_low.c::linux_resume_one_lwp, as follows:

ptrace(PTRACE_GETREGS, lwpid_of(lwp), 0, (void *)&tmpBuf);
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, lwpid_of (lwp), 0,
/* Coerce to a uintptr_t first to avoid potential gcc warning
of coercing an 8 byte integer to a 4 byte pointer. */
(PTRACE_ARG4_TYPE) (uintptr_t) signal);

retVal = ptrace(PTRACE_GETREGS, lwpid_of(lwp), 0, (void *)&tmpBuf);

Before ptrace(SINGLESTEP/CONT..) is called,
(gdb) x /32x &tmpBuf
0xbed9c8d0: 0x0000000a 0x80009a04 0x00000000 0x00000000
0xbed9c8e0: 0xbeaf6c58 0x00008d9c 0x00000001 0xbeaf6c40
0xbed9c8f0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbed9c900: 0x00008630 0xbeaf6c38 0x00008d21
0x00008630 <---------this is the PC

after it is called,
(gdb) x /32x &tmpBuf
0xbed9c8d0: 0x0000000a 0x80009a04 0x00000000 0x00000000
0xbed9c8e0: 0xbeaf6c58 0x00008d9c 0x00000001 0xbeaf6c40
0xbed9c8f0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbed9c900: 0x00009134 0xbeaf6c38 0x80003701
0x80483702 <---------this is the PC

It looks like PC gets messed up when executing the instruction at
0x8630. I don't know
this happens, or whether in this case registers dump are valid.

4/. If both app and library are built with ARM flag, which means both
app and lib would use ARM
instruction, I am not able step into the function too although 'step'
does not cause segmentation
fault. In this case, if I manipulate the vPacket (sent to gdbserver on
target) to use 's' instead of 'c',
it would be able to step into the function.

So far I am stuck because of no idea why PC gets messed up. Anyone
else the similar issue
when trying to debug function in library? And any input to how to
investigate gdb/gdbserver side
also is appreciated. (below some other information is dumped).

thanks
Liang

(gdb) disassemble /m 0x8d14
Dump of assembler code for function main:
....
286         z = xa_fun_in_lib(10);
=> 0x00008d18 <+84>:    mov.w   r0, #10
0x00008d1c <+88>:    blx     0x8628
0x00008d20 <+92>:    mov     r3, r0
0x00008d22 <+94>:    str     r3, [r7, #44]   ; 0x2c

(gdb) x /8i 0x8628
=> 0x8628: add r12, pc, #0
0x862c: add r12, r12, #0
0x8630: ldr pc, [r12, #2820]! ; 0xb04
<====== This line seems to cause the issue.
0x8634: andeq r0, r0, r0
(gdb) info register
....
sp 0xbee1fc48 0xbee1fc48
lr 0x8d21 36129
pc 0x8628 0x8628
cpsr 0x60000010 1610612752

(gdb) x /8xdwx 0x8630+0xb04
0x9134 <_GLOBAL_OFFSET_TABLE_+32>: 0x800036fd 0x00000000
0x00000000 0x00000000
0x9144 <__dso_handle+4>: 0x00000000 0x00000000
0x00000000 0x00000000

(gdb) info address xa_fun_in_lib
Symbol "xa_fun_in_lib(int)" is a function at address 0x800036fc.

(gdb) l xa_fun_in_lib
212 }
213 }
214
215
216 int xa_fun_in_lib(int x)
217 {
218 int y = 0;
219 int z = 3;
220
221 z = x + y + z*8;
(gdb) l
222 return z;
223 }
(gdb) x /32i 0x800036fc
0x800036fc <xa_fun_in_lib(int)>: push {r7}
0x800036fe <xa_fun_in_lib(int)+2>: sub sp, #20
0x80003700 <xa_fun_in_lib(int)+4>: add r7, sp, #0
0x80003702 <xa_fun_in_lib(int)+6>: str r0, [r7, #4]
0x80003704 <xa_fun_in_lib(int)+8>: mov.w r3, #0
0x80003708 <xa_fun_in_lib(int)+12>: str r3, [r7, #12]
0x8000370a <xa_fun_in_lib(int)+14>: mov.w r3, #3
0x8000370e <xa_fun_in_lib(int)+18>: str r3, [r7, #8]
0x80003710 <xa_fun_in_lib(int)+20>: ldr r2, [r7, #4]
0x80003712 <xa_fun_in_lib(int)+22>: ldr r3, [r7, #12]
0x80003714 <xa_fun_in_lib(int)+24>: adds r2, r2, r3
0x80003716 <xa_fun_in_lib(int)+26>: ldr r3, [r7, #8]
0x80003718 <xa_fun_in_lib(int)+28>: mov.w r3, r3, lsl #3
0x8000371c <xa_fun_in_lib(int)+32>: adds r3, r2, r3
0x8000371e <xa_fun_in_lib(int)+34>: str r3, [r7, #8]
0x80003720 <xa_fun_in_lib(int)+36>: ldr r3, [r7, #8]
0x80003722 <xa_fun_in_lib(int)+38>: mov r0, r3
0x80003724 <xa_fun_in_lib(int)+40>: add.w r7, r7, #20
0x80003728 <xa_fun_in_lib(int)+44>: mov sp, r7
0x8000372a <xa_fun_in_lib(int)+46>: pop {r7}
0x8000372c <xa_fun_in_lib(int)+48>: bx lr
0x8000372e: nop