[英]Usage of dlsym()/dlopen()
我寫了下一個程序:
#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文檔 :
函數
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;
}
這是(可能)未定義的行為:
std::cout << dlerror() << std::endl;
...除非dlerror
實際上不是null(可能不是)。 它應該是:
char* error = dlerror();
if (error != 0)
std::cout << error << std::endl;
...要么:
void *handle = dlopen(0, RTLD_NOW);
if (handle == 0)
std::cout << dlerror() << std::endl;
另外,如果dlerror
為非null(或handle
為null),則可能應該中止,因為在null handle
上調用dlsym
也是未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.