[fedora-arm] Understanding gdb disassembly output

Daniel Drake dsd at laptop.org
Tue May 1 21:10:30 UTC 2012


Hi,

I have been trying to understand more about the WebKit JIT crash,
looking at the assembly around the crash.
I'm confused about some of the output of gdb, can anyone help?


Core was generated by `epiphany'.
Program terminated with signal 11, Segmentation fault.
#0  0x000013e4 in ?? ()
Missing separate debuginfos, use: debuginfo-install
epiphany-3.3.90-1.fc17.armv7hl
(gdb) bt
#0  0x000013e4 in ?? ()
#1  0x499fe5dc in ?? ()
#2  0x499fe5dc in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) info registers
r0             0x4996e240	1234625088
r1             0xfffffffb	4294967291
r2             0x4996e240	1234625088
r3             0xfffffffb	4294967291
r4             0x47626688	1197631112
r5             0x1d2	466
r6             0x47626588	1197630856
r7             0x5357c57c	1398261116
r8             0x41d9f3e4	1104802788
r9             0x47626570	1197630832
r10            0x45a67400	1168536576
r11            0x41f55058	1106595928
r12            0x4c1d0ab0	1276971696
sp             0xbe8aed78	0xbe8aed78
lr             0x499fe5dc	1235215836
pc             0x13e4	0x13e4
cpsr           0x600f0010	1611595792

The PC is obviously bad here.
So lets look at the code around the LR to see where we came from.

(gdb) x/12i $lr-32
   0x499fe5bc:	mov	r0, sp
   0x499fe5c0:	str	r4, [sp, #3118288]	; 0x60
   0x499fe5c4:	mov	r8, #408	; 0x198
   0x499fe5c8:	str	r8, [r4, #-3118288]	; 0x2c
   0x499fe5cc:	ldr	r3, [pc, #31461008]	; 0x499fea40
   0x499fe5d0:	str	r4, [r3]
   0x499fe5d4:	ldr	r8, [pc, #31461008]	; 0x499fea44
   0x499fe5d8:	blx	r8
   0x499fe5dc:	str	r0, [r4, #3118288]	; 0x70
   0x499fe5e0:	str	r1, [r4, #3118288]	; 0x74
   0x499fe5e4:	b	0x499fc264
   0x499fe5e8:	b	0x499fe618


Specifically this bit looks of interest:

   0x499fe5d4:	ldr	r8, [pc, #31461008]	; 0x499fea44
   0x499fe5d8:	blx	r8

So the first instruction here says "take the data at address
pc+31461008 and save it in r8".
pc is always 8 bytes on from the address of the current instruction,
so at the moment pc = 0x499fe5d4 + 8 = 0x499fe5dc

So the address of the data being loaded into r8 is: 0x499fe5dc +
31461008 = 0x4b7ff46c

The contents of this memory:
(gdb) x/x 0x4b7ff46c
0x4b7ff46c:	0x00000000

Hmm, seems unlikely.
But going back to the instruction:

   0x499fe5d4:	ldr	r8, [pc, #31461008]	; 0x499fea44

What's that weird "; 0x499fea44" annotation? Where has gdb pulled that
number from?

Lets investigate it anyway:
(gdb) x/x 0x499fea44
0x499fea44:	0x41d9f3e4

Probably a pointer? Lets find out.

(gdb) x/4i 0x41d9f3e4
   0x41d9f3e4 <cti_op_resolve_global>:	str	lr, [sp, #3118288]	; 0x40
   0x41d9f3e8 <cti_op_resolve_global+4>:	bl	0x41cf4aac
   0x41d9f3ec <cti_op_resolve_global+8>:	
    ldr	lr, [sp, #3118288]	; 0x40
   0x41d9f3f0 <cti_op_resolve_global+12>:	mov	pc, lr

Yep, looks like a pointer.

Looking at the instruction once again:

   0x499fe5d4:	ldr	r8, [pc, #31461008]	; 0x499fea44

Lets see what value r8 has (maybe it hasn't changed since we ran that
line of code). See top of this mail. It's 0x41d9f3e4 (i.e.
cti_op_resolve_global). Which is the location pointed at by the weird
annotation of address 0x499fea44.

So it seems very likely that code execution jumped to 0x41d9f3e4, and
gdb seems to confirm that, but I don't know how/why.


Digging further down... cti_op_resolve_global (as pasted above)
branches to 0x41cf4aac.

(gdb) x/4i 0x41cf4aac
   0x41cf4aac:	add	r12, pc, #2097152	; 0x200000
   0x41cf4ab0:	add	r12, r12, #389120	; 0x5f000
   0x41cf4ab4:	ldr	pc, [r12, #3118288]!	; 0x240

So if I calculate right, on that first line, pc=0x41cf4aac + 8
So this causes a jump to the address pointed at by the memory location
0x41cf4aac + 8 + 2097152 + 389120 + 3118288 = 0x4224cf84. (r12 is also
updated to point at that same memory location).

So lets look at that address:

(gdb) x/x 0x4224cf84
0x4224cf84:	Cannot access memory at address 0x4224cf84

Hmm.

Note that r12 was also updated to point at the same location where the
new PC value was read from. Lets assume it hasn't changed since that
assignment, and check it out. r12=0x4c1d0ab0

(gdb) x/x 0x4c1d0ab0
0x4c1d0ab0:	0x41f50e00
(gdb) x/4i 0x41f50e00
   0x41f50e00 <_ZN3JSC9Structure6s_infoE>:	ldrsbmi	r4, [r0, #240]!	; 0xf0
   0x41f50e04 <_ZN3JSC9Structure6s_infoE+4>:	andeq	r0, r0, r0
   0x41f50e08 <_ZN3JSC9Structure6s_infoE+8>:	andeq	r0, r0, r0
   0x41f50e0c <_ZN3JSC9Structure6s_infoE+12>:	andeq	r0, r0, r0

0x41f50e00 <_ZN3JSC9Structure6s_infoE>:	0x41f04fd0	0x00000000	0x00000000	0x00000000
0x41f50e10 <_ZN3JSC9Structure6s_infoE+16>:	0x41ea7bec	0x41ea7038	0x41e4b4bc	0x41e4b4c4
0x41f50e20 <_ZN3JSC9Structure6s_infoE+32>:	0x41e4b5f4	0x41e4b5b4	0x41e4b584	0x41e4b554


Looks like data, not code, so maybe r12 has been changed after all.
(or we're trying to execute those instructions and going wildly
wrong).

Either way, I feel like my own calculations are not agreeing with the
actual behaviour of the program. Where does the 0x499fea44 annotation
come from? Why can't I calculate the behaviour of the code at
0x41cf4aac?

Thanks,
Daniel


More information about the arm mailing list