Function address incoherence

Andrea Cardaci cyrus.and@gmail.com
Sat Aug 24 10:27:00 GMT 2019


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



More information about the Gdb mailing list