2013-03-26 78 views
1

我試圖從共享庫的dlopen()失敗調用中報告所有未解析的符號。我已經嘗試了RTLD_LAZY和RTLD_NOW作爲dlopen調用的標誌。我知道共享庫有10個缺失的符號(即,如果你執行了一個靜態鏈接g ++ blah blah:鏈接將失敗,並丟失10個符號)。我想讓dlerror()告訴我在加載失敗期間所有10個丟失的符號。如何使dlerror()報告dlopen()無法加載共享庫的所有*未解析符號?

有沒有人知道如何哄這種情況發生?我從man頁面看到,dlerror()返回最後一個錯誤;所以也許我問的太多了,但是想知道有沒有人知道。

非常感謝,

回答

4

我想dlerror獲得()失敗的負載時告訴我的所有10個人失蹤符號。

您不能:裝載機儘快報告錯誤它發現該庫不能(即一旦它發現的第一個缺少符號)加載。裝載機沒有任何意義,所以它不會。

但是,您可以使用LD_PRELOADLD_TRACE_LOADED_OBJECTS來模擬ldd -r所做的操作,以獲得完整答案。例如:

$ cat main.c 
#include <dlfcn.h> 
#include <stdio.h> 

int main() 
{ 
    void *p = dlopen("./foo.so", RTLD_NOW); 
    if (p == NULL) { 
    printf("%s\n", dlerror()); 
    return 1; 
    } 
    return 0; 
} 


$ cat foo.c 
int bar(), baz(); // not defined anywhere 
int foo() { 
    return bar() + baz(); 
} 

$ gcc main.c -ldl; gcc -fPIC -shared -o foo.so foo.c 

$ ./a.out 
./foo.so: undefined symbol: baz # only the first symbol is reported 

$ ldd -r ./a.out 
    linux-vdso.so.1 => (0x00007fff52ddc000) 
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f158e48d000) 
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f158e0ce000) 
    /lib64/ld-linux-x86-64.so.2 (0x00007f158e6b2000) 

那是不行的,因爲你的程序永遠不會執行,因而不會裝載foo.so。但LD_PRELOAD營救:

$ LD_BIND_NOW=1 LD_WARN=1 LD_TRACE_LOADED_OBJECTS=1 LD_PRELOAD=./foo.so ./a.out 
    linux-vdso.so.1 => (0x00007fff3c1b6000) 
    ./foo.so (0x00007ffd33212000) 
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffd3300e000) 
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffd32c4f000) 
    /lib64/ld-linux-x86-64.so.2 (0x00007ffd33414000) 
undefined symbol: baz (./foo.so) 
undefined symbol: bar (./foo.so) 

Voilà:所有未解決的符號現在報告。