dlsym()/ dlopen()的用法

use*_*552 0 c++ posix symbols

我写了下一个程序:

#include <iostream>
#include <dlfcn.h>

int main(int argc, char** argv)
{
    typedef void* (*fptr)();
    fptr func;
    void *handle = dlopen(0, RTLD_NOW);
    std::cout << dlerror() << std::endl;    
    *(void **)(&func) = dlsym(handle, "__libc_start_main");
    std::cout << dlerror() << std::endl;

    std::cout << handle << " " << func << "\n";

    dlclose(handle);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

并尝试以下一种方式编译:

g++ -rdynamic main.cpp -ldl -o test
Run Code Online (Sandbox Code Playgroud)

当我运行这个程序时,我没有看到任何消息.为什么?

感谢U的关注.

Who*_*aig 5

您的进程是错误的,因为dlerror()它只对在错误条件下调用有效,在调用之前您从未验证过.

来自Linux文档:

该函数dlerror()返回描述,从最近发生的错误人类可读的字符串dlopen(),dlsym()dlclose() 因为对最后一次通话dlerror().如果自初始化或上次调用后没有发生错误,则返回NULL.

换句话说,你的dlopen成功,所以返回NULL dlerror().那么NULL被作为一个char *std::cout,并kerboom.

底线:在调用之前检查错误情况dlerror().试试这个:

#include <iostream>
#include <dlfcn.h>

int main(int argc, char** argv)
{
    typedef void* (*fptr)();
    fptr func;

    void *handle = dlopen(0, RTLD_NOW);
    if (handle == nullptr)
    {
        std::cout << dlerror() << std::endl;
        exit(EXIT_FAILURE);
    }

    func = (fptr)dlsym(handle, "__libc_start_main");
    if (!func)
    {
        std::cout << dlerror() << std::endl;
        exit(EXIT_FAILURE);
    }

    std::cout << handle << " " << func << "\n";

    dlclose(handle);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)