2014-08-29 327 views
1

正如其他SO答案中提到的,我使用GNU ld的包裝機制來攔截在Linux上調用malloc的調用(例如參見here)。 使用的鏈接器標誌是-Wl,--wrap=malloc,並且相應的void __wrap_malloc(size_t)也被定義。 這適用於所有編譯單元鏈接到同一個二進制文件的測試應用程序。未解決的符號__real_malloc動態加載一個庫,編譯時使用--wrap = malloc

現在,我需要修改一個動態鏈接庫,通過dlopen()加載到主程序中。 鏈接庫成功,但將其加載到主程序中失敗,並顯示undefined symbol: __real_malloc

對圖書館運行nm顯示__wrap_malloc被定義,但__real_malloc不是。 但是,根據man ldthis SO回答,malloc應替換爲__wrap_malloc__real_malloc應指向malloc使用此技術時。

在測試應用程序中,我看到__real_malloc未在編譯的目標文件中定義,但在鏈接到可執行文件後解析。

那麼,爲什麼符號在測試應用程序中解析,而不是在動態庫中解析? 在這兩種情況下,都應執行最終的鏈接步驟,以解決此符號。 或者是否需要在動態庫的鏈接步驟中添加另一個庫才能解決__real_malloc

爲了以防萬一,無法通過dlopen修改加載動態庫的目標應用程序。

回答

1

它應該工作,只需要對鏈接問題中的代碼稍作更改。

testapp.c

#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 

typedef void f_t(void); 

int main() 
{ 
    void* h = dlopen("./malloc_wrapper.so", RTLD_NOW); 
    if (h == NULL) 
    { 
     puts(dlerror()); 
     exit(1); 
    } 

    f_t* f = (f_t*)dlsym(h, "test"); 

    if (f == NULL) 
    { 
     puts(dlerror()); 
     exit(1); 
    } 

    (*f)(); 

    return 0; 
} 

malloc_wrapper.c

#include <stdlib.h> /* added */ 
#include <stdio.h> 
void *__real_malloc (size_t); 

/* This function wraps the real malloc */ 
void *__wrap_malloc(size_t size) 
{ 
    void *lptr = __real_malloc(size); 
    printf("Malloc: %lu bytes @%p\n", size, lptr); 
    return lptr; 
} 

void test(void) /* added */ 
{ 
    free(malloc(1024)); 
} 

編譯和運行。

gcc -Wl,-wrap,malloc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so 
gcc testapp.c -o testapp -ldl 
./testapp 
Malloc: 1024 bytes @0x1d44680 

編譯malloc_wrapper.so這樣重現錯誤您所描述:

gcc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so 
./testapp 
./malloc_wrapper.so: undefined symbol: __real_malloc 

也許你編譯和鏈接可執行文件,而不是共享對象的時候使用保鮮?

+0

感謝您的示例,並很抱歉找回這麼晚。在爲函數添加'extern「C」'聲明後,將包含內容更改爲'C++'等價物,並使用'g ++'編譯文件,它適用於此示例。不幸的是,我正在使用的這個項目要複雜得多。所以它的構建過程似乎是一個問題。也許我會更新這個問題,如果我有關於這個問題的更多細節。 – MKroehnert 2015-01-26 16:59:27