断点有两个地址?

Jim*_*Jim 3 debugging assembly gdb breakpoints

我最近设置了一个断点,初始地址是:

(gdb) b viewscreen_movieplayerst::create(char, viewscreenst*)
Breakpoint 1 at 0x804beec
Run Code Online (Sandbox Code Playgroud)

第二个(常用地址)是:

   (gdb) run

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

这是因为可执行文件被删除了吗?还是可执行文件执行完毕,执行后地址发生变化?

另外,主要是:

(gdb) b main 
Breakpoint 1 at 0x804bdec
Run Code Online (Sandbox Code Playgroud)

这看起来与地址非常接近,所以我将其包括在内。

编辑:

搬迁的概念是什么?

那么大部分二进制文件都是由reloc表组成的?

Mat*_*her 5

也许您正在看到 Unix 上共享库函数的过程链接表 (PLT) 地址?

编译器构建一个“trampoline”地址表,间接引用共享库依赖项。这是一个复杂的话题,这里有一篇详细的文章

这是一个简单的例子。

库文件

#include <iostream>


int foo()
{
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

垃圾文件

#include<iostream>

int foo();
int main(int argc, char* argv[])
{
  int k = foo();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译

/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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

正如评论所指出的,模板实例化和编译器优化还可以为一个符号或源代码行创建多个地址。