簡體   English   中英

如何從轉儲和符號文件中獲取變量名?

[英]How to get variable names out of a dump and a symbol file?

我正在調試轉儲文件,同時可以訪問符號文件。

我正在使用一個腳本,該腳本結合了以下windbg命令的結果:

x /2 *!*  // which types are present in the symbol files?
!heap -h 0 // which memory address ranges are used in the dump?

(至少,這就是我的理解。萬一我錯了,請毫不猶豫地糾正我)

腳本的結果(在此Windbg擴展列表下找到的heap_stat.py )是一個內存地址列表,其后是它們的類型。 通過統計這些數據,我可以得出是否存在內存泄漏。

最重要的是,使用提到的內存地址的WinDbg命令dt CStringArray m_nSize (當然,在CStringArray的特定情況下),我可以看到使用的CStringArray對象的條目總數,並查看是否存在CStringArray有很多條目的對象。

但是,此系統有一個缺點:
當我發現這樣一個包含大量條目的CStringArray對象時,我就被困在那里,因為在我的應用程序中的所有CStringArray對象中,我都不知道要處理哪個對象。

可能有用的一件事是內存地址所涉及的局部變量的名稱,但有一個陷阱:我不知道此信息是否存在,如果是的話,我可以在符號文件或轉儲中找到它嗎? ,(顯然)我需要運行哪個命令才能獲取此信息(我沒有找到使dt <flag> <memory address>返回由<memory address>占據的局部變量名稱的dt <flag> <memory address> )?

有誰能夠幫助我?

為了澄清起見,這是我的腳本當前的結果如下所示:

0x0065a4d0  mfc110u!CStringArray  Size:[1]
0x0065a4e4  mfc110u!CStringArray  Size:[0]
0x0065a4f8  mfc110u!CStringArray  Size:[295926]
0x0065a520  mfc110u!CStringArray  Size:[0]

如您所見,我可以看到存儲變量的內存地址,可以看到類型(從符號文件中檢索),還可以看到條目的數量(從dt Windbg命令中檢索),但是我d希望產生如下輸出:

0x0065a4d0  mfc110u!CStringArray  Size:[1]      var1
0x0065a4e4  mfc110u!CStringArray  Size:[0]      var2
0x0065a4f8  mfc110u!CStringArray  Size:[295926] var3
0x0065a520  mfc110u!CStringArray  Size:[0]      var3

要么:

0x0065a4d0  mfc110u!CStringArray  Size:[1]      obj1.prop1
0x0065a4e4  mfc110u!CStringArray  Size:[0]      obj2.prop1
0x0065a4f8  mfc110u!CStringArray  Size:[295926] obj1.prop2
0x0065a520  mfc110u!CStringArray  Size:[0]      obj1.prop2

這樣的輸出將表明我需要驗證源代碼中的var3obj1.prop2發生了什么。

我編寫了以下MFC應用程序(部分來源):

CStringArray stringarray;
void* anotherarray = new CStringArray();

void CLocalVariableNameApp::AnotherMethod(void* a)
{
    CStringArray* temp = static_cast<CStringArray*>(a);
    temp->Add(L"Something else");
}

CLocalVariableNameApp::CLocalVariableNameApp()
{
    stringarray.Add(L"Something");
    AnotherMethod(anotherarray);
    CStringArray* holycow = static_cast<CStringArray*>(anotherarray);
    holycow->Add(L"Yet something else");
    DebugBreak();
}

如您所見,第二個CStringArray具有多個名稱: anotherarrayatempholycow

觀察1:在內存地址和變量名上不會有簡單的1:1映射。

本地變量名稱可從PDB文件中獲得:

0:000> k
 # ChildEBP RetAddr  
00 0022fa40 00fa2a30 KERNELBASE!DebugBreak+0x2
01 0022fb3c 00f97958 LocalVariableName!CLocalVariableNameApp::CLocalVariableNameApp+0x90 [c:\...\localvariablename.cpp @ 38] 
02 0022fc10 014b628a LocalVariableName!`dynamic initializer for 'theApp''+0x28 [c:\...\localvariablename.cpp @ 43] 
03 0022fc18 014b5e8c LocalVariableName!_initterm+0x1a [f:\...\crt0dat.c @ 955] 
04 0022fc2c 014a9263 LocalVariableName!_cinit+0x6c [f:\...\crt0dat.c @ 308] 
05 0022fc78 014a947d LocalVariableName!__tmainCRTStartup+0xf3 [f:\...\crt0.c @ 237] 
06 0022fc80 7558336a LocalVariableName!wWinMainCRTStartup+0xd [f:\...\crt0.c @ 165] 
07 0022fc8c 771198f2 kernel32!BaseThreadInitThunk+0xe
08 0022fccc 771198c5 ntdll!__RtlUserThreadStart+0x70
09 0022fce4 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> .frame 1
01 0022fb3c 00f97958 LocalVariableName!CLocalVariableNameApp::CLocalVariableNameApp+0x90 [c:\...\localvariablename.cpp @ 38] 
0:000> dv
           this = 0x01637118
        holycow = 0x00445820

請注意,名稱atemp不可見。

觀察點2:變量名將受到其范圍的限制。 如果要記住所有變量名,則需要跟蹤所有函數。

上面是一個調試版本。 版本不同:

0:000> k
 # ChildEBP RetAddr  
00 005efe04 002a1c18 KERNELBASE!DebugBreak+0x2
01 005efe20 002a1095 LocalVariableName!CLocalVariableNameApp::CLocalVariableNameApp+0x88 [c:\...\localvariablename.cpp @ 39] 
02 005efe24 003c0289 LocalVariableName!`dynamic initializer for 'theApp''+0x5 [c:\...\localvariablename.cpp @ 43] 
03 005efe38 003c01ea LocalVariableName!_initterm+0x29 [f:\...\crt0dat.c @ 954] 
04 005efe48 003bd280 LocalVariableName!_cinit+0x5a [f:\...\crt0dat.c @ 321] 
05 005efe88 7558336a LocalVariableName!__tmainCRTStartup+0xde [f:\...\crt0.c @ 237] 
06 005efe94 771198f2 kernel32!BaseThreadInitThunk+0xe
07 005efed4 771198c5 ntdll!__RtlUserThreadStart+0x70
08 005efeec 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> .frame 1
01 005efe20 002a1095 LocalVariableName!CLocalVariableNameApp::CLocalVariableNameApp+0x88 [c:\...\localvariablename.cpp @ 39] 
0:000> dv
           this = 0x0043f420

請注意, holycow丟失了。

觀察結果3:在發行版本中,可能不需要(優化)變量,因此不存在變量。

總體結論:不可能將內存地址映射到變量名。

暫無
暫無

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

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