Reputation: 9521
$ gdb --version
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
I'm debugging with gdb and faced some weird address offset. I have a shared library written in C++
with a function foo
which disassembles as follows (the first fragment):
Dump of assembler code for function foo:
0x00007ffff5c82d70 <+0>: push rbp
0x00007ffff5c82d71 <+1>: mov rbp,rsp
0x00007ffff5c82d74 <+4>: push r15
0x00007ffff5c82d76 <+6>: push r14
0x00007ffff5c82d78 <+8>: push r13
0x00007ffff5c82d7a <+10>: push r12
0x00007ffff5c82d7c <+12>: push rbx
0x00007ffff5c82d7d <+13>: sub rsp,0x18
0x00007ffff5c82d81 <+17>: test rdi,rdi
0x00007ffff5c82d84 <+20>: mov DWORD PTR [rbp-0x34],r8d
0x00007ffff5c82d88 <+24>: je 0x7ffff5c82e58 <foo+232>
0x00007ffff5c82d8e <+30>: mov r15,rsi
0x00007ffff5c82d91 <+33>: mov r14,rdx
0x00007ffff5c82d94 <+36>: mov r13d,ecx
0x00007ffff5c82d97 <+39>: mov rbx,rdi
0x00007ffff5c82d9a <+42>: jmp 0x7ffff5c82ded <foo+125>
0x00007ffff5c82d9c <+44>: nop DWORD PTR [rax+0x0]
# Where do these negative offsets come from?
0x00007ffff5c82da0 <+-1632>: mov r9d,DWORD PTR [r12]
0x00007ffff5c82da4 <+-1628>: lea rcx,[rip+0xcadbe2]
0x00007ffff5c82dab <+-1621>: lea rdx,[rip+0xcadde6]
0x00007ffff5c82db2 <+-1614>: lea rdi,[rip+0xcadb67]
#...
# negative offset of some unrelated function `bar`
0x00007ffff5c82e19 <+-1511>: js 0x7ffff5c82dde <bar+4294965726>
Such negative offsets point are interpreted as belonging to some unrelated function (I did not find anything that could match these function up) bar
.
Such things causes confusion when using GUI gdb frontend.
Any idea why gdb may show such negative instruction offset? Is it a GDB bug? If so, is there any workaround?
I tried to find out what is the objdump
output regarding this function and did not notice anything strange (the same fragment as in the gdb example):
$ objdump -M intel -d libsomelib.so | grep -A 100 -i "0000000000e78d70"
0000000000e78d70 <foo>:
e78d70: 55 push rbp
e78d71: 48 89 e5 mov rbp,rsp
e78d74: 41 57 push r15
e78d76: 41 56 push r14
e78d78: 41 55 push r13
e78d7a: 41 54 push r12
e78d7c: 53 push rbx
e78d7d: 48 83 ec 18 sub rsp,0x18
e78d81: 48 85 ff test rdi,rdi
e78d84: 44 89 45 cc mov DWORD PTR [rbp-0x34],r8d
e78d88: 0f 84 ca 00 00 00 je e78e58 <foo+0xe8>
e78d8e: 49 89 f7 mov r15,rsi
e78d91: 49 89 d6 mov r14,rdx
e78d94: 41 89 cd mov r13d,ecx
e78d97: 48 89 fb mov rbx,rdi
e78d9a: eb 51 jmp e78ded <foo+0x7d>
e78d9c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
e78da0: 45 8b 0c 24 mov r9d,DWORD PTR [r12]
e78da4: 48 8d 0d e2 db ca 00 lea rcx,[rip+0xcadbe2]
e78dab: 48 8d 15 e6 dd ca 00 lea rdx,[rip+0xcadde6]
e78db2: 48 8d 3d 67 db ca 00 lea rdi,[rip+0xcadb67]
//...
//just fine
e78e19: 78 c3 js e78dde <foo+0x6e>
The clear difference between the output of the gdb and objdump can be seen in the final line.
GDB:
0x00007ffff5c82e19 <+-1511>: js 0x7ffff5c82dde <bar+4294965726>
objdump:
e78e19: 78 c3 js e78dde <foo+0x6e>
Upvotes: 0
Views: 335
Reputation: 213375
Any idea why gdb may show such negative instruction offset?
Yes: in <bar+4294965726>
, GDB interprets offset as signed int: 4294965726 == -1570
Is it a GDB bug?
Yes.
Unfortunately it's not clear how to reproduce this, or why GDB decided to show offset from bar
instead of showing offset from foo
. And without that, a proper bug report would be hard to create.
Upvotes: 2