Я создаю независимый от позиции исполняемый файл (puppet
ниже), динамически загружаю через dlopen
, получаю main
через dlsym
и вызываю его. Это прекрасно работает, пока этот пирог не использует iostream
, в частности cout
. Если это так, то в коде происходит ошибка с трассировкой стека ниже.
Если я делаю примерно то же самое, но собираю куклу как разделяемую библиотеку, а не как 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 ()