c++ - 动态加载的与位置无关的可执行文件中的段错误
问题描述
我构建了一个与位置无关的可执行文件(puppet
如下),动态加载 via dlopen
,获取它的main
viadlsym
并调用它。这很好用,只要这个 PIE 不使用iostream
, 特别是cout
. 如果是这样,则代码会在下面的堆栈跟踪中出现段错误。
如果我做大致相同的事情,但将 puppet 编译为共享库,而不是 PIE(将 main 重命名为其他内容),一切正常。
什么可能导致这个问题?它只存在于 Linux 上;在 Mac 上这工作正常。
puppet.cpp
:
#include <iostream>
int main(int argc, char** argv)
{
std::cout << "Hello from puppet" << std::endl;
}
main.cpp
:
#include <iostream>
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>
int main()
{
std::cout << "Hello from main" << std::endl;
typedef int (*MainType)(int argc, char *argv[]);
void* lib = dlopen("./puppet", RTLD_LAZY);
if (lib == NULL)
{
std::cerr << "Unable to open the library" << std::endl;
return 1;
}
MainType f = (MainType) dlsym(lib, "main");
if (f == NULL)
{
std::cerr << "Unable to get the function" << std::endl;
return 1;
}
int argc = 0; char** argv = 0;
f(argc, argv);
}
Makefile
:
all: main puppet
puppet: puppet.cpp
g++ puppet.cpp -o puppet -fPIE -Wl,-pie -Wl,--export-dynamic
main: main.cpp
g++ main.cpp -o main -ldl
段错误的回溯:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff795da56 in std::ostream::sentry::sentry (this=0x7fffffffe080, __os=...) at /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/ostream.tcc:46
46 /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/ostream.tcc: No such file or directory.
(gdb) back
#0 0x00007ffff795da56 in std::ostream::sentry::sentry (this=0x7fffffffe080, __os=...) at /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/ostream.tcc:46
#1 0x00007ffff795e109 in std::__ostream_insert<char, std::char_traits<char> > (__out=..., __s=__s@entry=0x7ffff6ce0b95 "Hello from puppet", __n=17) at /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/lib
stdc++-v3/include/bits/ostream_insert.h:76
#2 0x00007ffff795e5a9 in std::operator<< <std::char_traits<char> > (__out=..., __s=0x7ffff6ce0b95 "Hello from puppet") at /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/char_t
raits.h:320
#3 0x00007ffff6ce0a87 in main () from ./puppet
#4 0x0000555555554a7e in main ()
解决方案
推荐阅读
- ruby-on-rails - Rails 通过调用方法渲染传递参数
- python - 等待元素并返回它
- python - 在 IntelliJ Ultimate IDE 中从项目运行 python 测试
- automation - 自动化 - 如何组织测试用例、测试对象和测试套件?
- excel - 在 if 条件中使用 where 子句
- android - 安卓设备的ejabberd服务器登录失败
- java - 将cpp函数指针转换为java接口方法
- git - 如何在已经提交到其他分支的其他分支中推送更改
- php - PHP - sleep() 在时间过去后无法继续执行
- docker - Docker Swarm 和 Mesos 中的资源利用