C++ PLT代码中的SEGFULT。你知道为什么吗?
我有一个通过调用以下函数初始化的共享库:C++ PLT代码中的SEGFULT。你知道为什么吗?,c++,c,assembly,shared-libraries,C++,C,Assembly,Shared Libraries,我有一个通过调用以下函数初始化的共享库: extern "C" { int pa__init(pa_module *m) { m->userdata = new PAModule(m); return 0; } } // extern "C" 它被编译成以下格式(地址是编译时偏移): 当我加载库并调用此方法时,我在编译时偏移量61310处得到一个segfault: 0000000000061310 <operator new(unsigned long)@plt
extern "C" {
int pa__init(pa_module *m) {
m->userdata = new PAModule(m);
return 0;
}
} // extern "C"
它被编译成以下格式(地址是编译时偏移):
当我加载库并调用此方法时,我在编译时偏移量61310
处得到一个segfault:
0000000000061310 <operator new(unsigned long)@plt>:
61310: ff 25 a2 c1 66 00 jmpq *0x66c1a2(%rip) # 6cd4b8 <operator new(unsigned long)@@Base+0x57f708>
61316: 68 94 02 00 00 pushq $0x294
6131b: e9 a0 d6 ff ff jmpq 5e9c0 <.plt>
#0 0x0000000000061316 in ?? ()
#1 0x00007fd9faae9730 in pa__init (m=0x55f1a750d850) at pa_module.cpp:24
[...]
编译时得到的偏移量6cd4b8
(在运行时重新定位为例如0x7fced7ffa4b8
)中的值为
处理器尝试跳转到该位置。但是,这仍然是编译时偏移量(指向无效内存),这就是程序出错的原因
你知道为什么在我的库加载时,get中的条目不会被重新定位吗
多谢各位 我的库原来有未定义的符号
这使得动态链接加载程序无法成功更新GOT,编译时偏移量保留在内存中。在运行时,这些地址无效并导致SEGFULT。您是否使用
dlopen
加载它?立即尝试RTLD\u
标志。另外,在0x6cd4b8
上放置一个写表,看看是谁在修改它。@Sämy:我在问调用库的可执行文件是如何链接的。使用-fPIC
构建库代码是正常的(也是唯一正确的选项)。顺便说一句,-pie
与-fPIE
不同,我认为没有-PIC
选项,只有-fPIC
。有关位置独立可执行文件(为可执行文件和库启用ASLR)的更多信息,请参阅-pie
。哦,这是脉冲加载模块。那太不幸了。你能预加载它吗?不确定这是否会影响dlopen
。现在也设置环境变量LD\u BIND\u
。@PeterCordes,但确实如此。因为在运行时0x7fced7ffa4b8
仍保留未重新定位的地址0x61316
。这不是(不再)运行时的push指令。($rip=0x7f8faf77d2f0@0x61310
但是*0x7fced7ffa4b8=0x61316
而不是0x7f8faf77d2f6
)。@Jester也谢谢你LD_BIND_NOW=1
帮助我意识到我的库中存在未定义的符号。
#0 0x0000000000061316 in ?? ()
#1 0x00007fd9faae9730 in pa__init (m=0x55f1a750d850) at pa_module.cpp:24
[...]
0x7fced7ffa4b8: 0x00061316