2017-11-25 322 views
2

我有一個共享庫(hlapi.so)在Linux系統上運行。這hlapi.so有很多模塊(我的意思是.c文件)。其中一個被命名爲hlapi.c定義這樣的兩個全球DATAS:GDB能否從xx.so解析全局數據而不執行?

static int hlapiInitialized = FALSE; 
static struct hlapi_data app_sp; 

當然也有這個hlapi.c模塊在其他許多代碼。 hlapi.so發佈給基於我們的hlapi.so構建自己的應用程序(名爲appbasehlapi)的客戶。

現在我得到了一個核心轉儲,其客戶解析的回溯顯示核心位於我們的代碼中。但客戶只能向我們提供核心轉儲文件。 appbasehlapi可執行文件不會與我們共享。所以在我的手中,我只有核心轉儲文件+ hlapi.so。

爲了調試這個核心,由我指揮

gdb --core=mycoredumpfile 

裝入核心轉儲文件,然後在gdb,我用

set solib-search-path . 

指定包含hlapi.so這樣的文件夾gdb可以從hlapi.so加載符號。然後我使用:

print hlapiInitialized 
print app_sp 

解析模塊中的全局數據。但是輸出值非常不正常。

我在這裏的問題是,如果我可以解析全局數據通過gdb中定義的hlapi.so沒有可執行文件?如果我通過gdb獲得的輸出是可信的? 我很欣賞任何評論。

順便說一句,hlapi.so是用gcc選項「-g -fPIC」構建的。

+0

是否知道核心轉儲是否由您正在用於調試的庫的_exact_相同版本生成? – duskwuff

+0

@duskwuff,是的。它與我們發佈給客戶的hlapi.so版本相同。 –

回答

0

我調查了一段時間的問題,在我看來,我相信GDB可以在沒有可執行文件的情況下解析全局變量。

在測試中,將以下代碼在hlapi.cpp:

static int hlapiInitialized = 0; 

void hlapiInit() 
{ 
    if (hlapiInitialized == 0) 
    { 
     // do something else 
    } 

    hlapiInitialized = 1; 
} 

的objdump顯示組件的代碼,它是:

00000000000009a2 <_Z9hlapiInitv>: 
9a2: 55      push %rbp 
9a3: 48 89 e5    mov %rsp,%rbp 
9a6: c7 05 98 06 20 00 01 movl $0x1,0x200698(%rip) # 201048 <_ZL16hlapiInitialized> 
9ad: 00 00 00 
9b0: 90      nop 
9b1: 5d      pop %rbp 
9b2: c3      retq 

在運行的應用程序,我生成核心傾倒它。在GDB,指定solib搜索路徑之前,我得到:

(gdb) disas hlapiInit 
No symbol table is loaded. Use the "file" command. 

一旦指定的搜索路徑,輸出是:

(gdb) disas hlapiInit 
Dump of assembler code for function hlapiInit(): 
    0x00007ffff7bd59a2 <+0>: push %rbp 
    0x00007ffff7bd59a3 <+1>: mov %rsp,%rbp 
    0x00007ffff7bd59a6 <+4>: movl $0x1,0x200698(%rip)  # 0x7ffff7dd6048 <_ZL16hlapiInitialized> 
    0x00007ffff7bd59b0 <+14>: nop 
    0x00007ffff7bd59b1 <+15>: pop %rbp 
    0x00007ffff7bd59b2 <+16>: retq 
End of assembler dump. 

輸出從hlapi.so和比較後,核心文件,我們知道一旦共享庫已經加載到進程中,全局變量的地址將被重新分配,並且全局變量的地址是清楚的。因此,一旦擁有共享庫的符號信息,gdb就可以映射這些變量。