我写了下一个程序:
#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;
}
并尝试以以下方式进行编译:
g++ -rdynamic main.cpp -ldl -o test
运行该程序时,我看不到任何消息。为什么?
感谢您的关注。
最佳答案
您的过程有问题,因为dlerror()
仅在错误情况下才有效,您从未验证过该错误情况实际上是在调用之前发生的。
从Linux docs:
函数dlerror()
返回人类可读的字符串,该字符串描述了
dlopen()
,dlsym()
或dlclose()
发生的最新错误
自上次呼叫dlerror()
以来。如果没有错误,则返回NULL
自初始化或自上次调用以来发生。
换句话说,您的dlopen
成功,因此dlerror()
返回NULL。然后将该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;
}