2016-09-06 69 views
2

我最近设置一个断点,其中初始地址是:断点有两个地址?

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

和第二(常住地址)是:

(gdb) run 

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

这是因为该可执行文件被剥离?还是执行可执行文件并且地址发生变化?

而且,主要是:

(gdb) b main 
Breakpoint 1 at 0x804bdec 

这似乎很接近的地址,所以我会包括它。

编辑:

What does the concept of relocation mean?

So most of the binary is composed of reloc table?

+0

你的问题对我来说并不完全清楚。如果你在运行时地址不同(你可以使用info break来检查),那么是的,它可能是运行时重定位。如果它实际上有两个地址,那么可能由于各种编译器优化而发生。 –

+0

@Tom Tromey在什么情况下会有2个地址?如果没有,你给我了我正在寻找的“运行时重定位”标语 – Jim

+0

由于内联和重载分辨率的原因,推测一个函数可能有多个地址。 – kfsone

回答

4

也许你看到从UNIX上的共享库函数的过程链接表(PLT)地址?

编译器建立一个'trampoline'地址表,间接引用共享库依赖关系。这是一个复杂的话题,有一个详细的文章here

这里是一个简单的例子。

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; 
} 

编译

/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流浪汉

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 

正如你所看到的符号'foo'有两个地址和两个断点。一个是PLT,另一个是共享库中的符号位置。

正如注释所述,模板实例化和编译器优化也可以为一个符号或源代码行创建多个地址。

+0

是的,定义与程序链接表有关。我意识到“预执行”地址对应于我制作的objdump -d文件中的地址。谢谢。 – Jim