Segfault в cout динамически загружаемой, независимой от позиции - PullRequest
0 голосов
/ 08 мая 2018

Я создаю независимый от позиции исполняемый файл (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 ()
...