Function address incoherence
Andrea Cardaci <[email protected]>
| Newsgroups | gmane.comp.gdb.devel |
|---|---|
| Message-ID | <CACMsj9PVtSb_+1gYAUaQPafUd0A-PDuQT5UpvVUWmOHExzxb=w@mail.gmail.com> |
Hi,
I could use some clarification about the following behavior that
initially came up in a issue [1] opened to the gdb-dashboard project.
Basically in some cases it appears that there's some kind of symbol
conflict (this is a bad name but I don't know how to else call it).
I can only reproduce it on a 32 bit Linux machine with the following:
vagrant@ubuntu-xenial:~$ gcc -x c -o test - <<<'int main(){}'
vagrant@ubuntu-xenial:~$ gdb -q --batch test -ex 'b *0' -ex r -ex
disassemble -ex 'p &_start'
Breakpoint 1 at 0x0
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x0
Dump of assembler code for function _start:
=> 0xb7fdba20 <+0>: mov %esp,%eax
0xb7fdba22 <+2>: call 0xb7fdc5c0 <_dl_start>
End of assembler dump.
$1 = (<text variable, no debug info> *) 0x80482e0 <_start>
As you can see, $pc points to 0xb7fdba20 and the disassemble commands
reports that it is part of _start, yet if I print the address of
_start I obtain a different value (0x80482e0). (Using the disassemble
command is just an example, simply printing $pc shows 0xb7fdba20
<_start>.)
Now the latter (0x80482e0) is what appears to be the *real* _start:
vagrant@ubuntu-xenial:~$ readelf -s test | grep ' _start'
60: 080482e0 0 FUNC GLOBAL DEFAULT 14 _start
While the other address (0xb7fdba20) appears to be contained in
/lib/ld-linux.so.2:
0xb7fdb860 - 0xb7ff48fd is .text in /lib/ld-linux.so.2
According to objdump -d /lib/ld-linux.so.2, $pc points at the
following instructions in the _dl_rtld_di_serinfo function:
00000860 <_dl_rtld_di_serinfo@@GLIBC_PRIVATE-0x83c0>:
[...]
a20: 89 e0 mov %esp,%eax
a22: e8 99 0b 00 00 call 15c0 <realloc@plt+0xd80>
So where does the _start reported by the disassemble command comes
from? Is this a GDB bug or I'm missing something here?
Back to the gdb-dashboard issue, I fetch the function address with
gdb.parse_and_eval(frame.name()).address and since frame.name() is
_start, the address that I obtain is 0x80482e0 instead of 0xb7fdba20
thus I end up displaying wrong offsets.
Best,
Andrea
[1]: https://github.com/cyrus-and/gdb-dashboard/issues/70