2013-06-30 70 views
2

我在寫一些存儲每個內存分配的回溯的代碼。然後,我將這些列表寫入文件進行離線分析。在win32中,我使用_AddressOfReturnAddress,然後手動創建回溯。由於每次運行的地址都是隨機的,因此我使用GetModuleInformationlpBaseOfDll來獲取基地址。這對於沒有FPO的x86很有效,這對我來說已經足夠了。然後我使用win32 API加載PDB將地址轉換爲函數名稱。獲取linux可執行文件的加載地址(__builtin_return_address和addr2line)

我該如何做到這一點在linux上?我目前的方法是使用__builtin_return_address(x)addr2line離線得到相同的結果。問題是每次運行的地址都是隨機的,所以addr2line不理解它們。 __executable_start沒有工作,因爲它每次運行返回相同的值。有沒有辦法在運行時獲得我的可執行文件的基址?

一個試驗使我這個:

__executable_start: 0x8048000 
backtrace: 
0x9cce628 
0x9cce2b8 
0x9cce260 
0x9cce1f8 
0x9cce138 
0x9cce0c8 
0x9cce060 
0x9cce008 

而接下來:

__executable_start: 0x8048000 
backtrace: 
0x8db6628 
0x8db62b8 
0x8db6260 
0x8db61f8 
0x8db6138 
0x8db60c8 
0x8db6060 
0x8db6008 

等。

+0

我以爲只有堆棧和數據段有隨機地址 - 文段應該有一個固定的地址,你可以用'objdump'看到它。無關地,你看過像「放鬆」這樣的圖書館嗎? –

+0

我抽取了更多的地址,我認爲只有那些指向動態加載的庫才能被隨機化,這更有意義。我只是打印第一個,這可能來自C++庫。其他地址似乎與'objdump'和'__executable_start'的基地址相匹配。 – user408952

+2

是的,共享庫是可重定位的,所以他們的地址也可能隨機化。 –

回答

1

您可以使用dl_iterate_phdr()在Linux上,以確定每個動態加載對象的加載地址:

#define _GNU_SOURCE 
#include <stdio.h> 
#include <link.h> 

int callback(struct dl_phdr_info *info, size_t size, void *data) 
{ 
    printf("%s @ %#lx\n", info->dlpi_name, (unsigned long)info->dlpi_addr); 
    return 0; 
} 

int main() 
{ 
    dl_iterate_phdr(&callback, NULL); 
    return 0; 
} 
相關問題