簡體   English   中英

dlsym()/ dlopen()的用法

[英]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也是未定義的行為。

請參閱為什么將std :: cout輸出發送到NULL后完全消失

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM