我写了下一个程序:
#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当我运行这个程序时,我没有看到任何消息。为什么?
谢谢你的关注。
发布于 2014-05-14 12:11:17
您的流程是错误的,因为dlerror()只在错误条件下有效调用,而在调用之前从未验证过这种情况。
来自Linux文档
函数
dlerror()返回一个人类可读的字符串,描述自上次调用dlerror()以来dlopen()、dlsym()或dlclose()发生的最新错误。如果自初始化或上次调用以来没有发生错误,则返回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;
}发布于 2014-05-14 12:10:32
这很可能是未定义的行为:
std::cout << dlerror() << std::endl; ...unless dlerror实际上是非空的(可能不是)。它应该是:
char* error = dlerror();
if (error != 0)
std::cout << error << std::endl;...or:
void *handle = dlopen(0, RTLD_NOW);
if (handle == 0)
std::cout << dlerror() << std::endl;此外,如果dlerror为非空(或handle为空),则可能应该中止,因为在空handle上调用dlsym也是未定义的行为。
https://stackoverflow.com/questions/23654120
复制相似问题