2

I recently set a breakpoint where the initial address was :

(gdb) b viewscreen_movieplayerst::create(char, viewscreenst*)
Breakpoint 1 at 0x804beec

and the second (usual address) was :

   (gdb) run

   Breakpoint 1, 0xf7b46630 
   in viewscreen_movieplayerst::create(char,viewscreenst*)()
   from/path/libs/libgraphics.so

Is this because the executable is stripped? Or is the executable executed and the address changes after the execution?

Also, main is :

(gdb) b main 
Breakpoint 1 at 0x804bdec

Which seems pretty close to the address so I'll include it.

Edit:

What does the concept of relocation mean?

So most of the binary is composed of reloc table?

Community
  • 1
  • 1
Jim
  • 65
  • 7
  • Your question isn't totally clear to me. If the address differs when you `run` (you can check with `info break`), then yes, it is probably runtime relocation. If it actually has two addresses, then that can happen due to various compiler optimizations. – Tom Tromey Sep 06 '16 at 20:36
  • @Tom Tromey In what situation would it have 2 addresses? If not, you gave me the "runtime relocation" catchphrase I was looking for – Jim Sep 06 '16 at 21:12
  • Presumably a function can have multiple addresses due to inlining and overload resolution. – kfsone Sep 06 '16 at 21:23
  • 1
    Yes, inlining. There are related optimizations as well, but they are rarer. Also if you are setting a `file:line` breakpoint, you can see multiple addresses due to template instantations -- you will ordinarily get one hit per instantiation. – Tom Tromey Sep 06 '16 at 22:55

1 Answers1

4

Perhaps you are seeing the Procedure Linkage Table (PLT) address from a shared library function on Unix?

The compiler builds a table of 'trampoline' addresses that indirectly refer to the shared library dependencies. It is a complicated topic, there is a detailed article here

Here is a simple example.

lib.cpp

#include <iostream>


int foo()
{
  return 0;
}

junk.cpp

#include<iostream>

int foo();
int main(int argc, char* argv[])
{
  int k = foo();
  return 0;
}

Compile

/tmp$ g++ -fPIC -g -std=c++11 -shared -o libtest_library.so lib.cpp
/tmp$ g++  -g -std=c++11  -o tramp junk.cpp -L . -l test_library

gdb tramp

Reading symbols from tramp...done.
(gdb) p foo
$1 = (<text from jump slot in .got.plt, no debug info>) 0x4006d6 <foo()@plt+6>
(gdb) b foo
Breakpoint 1 at 0x4006d0
(gdb) d 1
(gdb) r
Starting program: /tmp/tramp 
lib:  0x602010
[Inferior 1 (process 12804) exited normally]
(gdb) b foo
Breakpoint 2 at 0x4006d0 (2 locations)
(gdb) info break
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   <MULTIPLE>         
2.1                         y     0x00000000004006d0 <foo()@plt>
2.2                         y     0x00002aaaaacd0a99 in foo() at lib.cpp:6

As you can see the symbol 'foo' has two addresses and two breakpoints. One is the PLT and the other the symbol location in the shared library.

As the comments noted, template instantiations and compiler optimizations can also create multiple addresses for one symbol or source line.

Matthew Fisher
  • 2,258
  • 2
  • 14
  • 23
  • Yes, definely has something to do with the procedure linkage table. I realized that the "pre-execution" address corresponds to the address in the objdump -d file i made. Thank you. – Jim Sep 07 '16 at 02:46