2015-08-21 65 views
2

目標:我試圖列出包含在pdb文件中的所有函數的地址。使用getSymbolsByAddr遍歷DIA SDK中的符號

現行辦法:我發現DIA SDK,我修改dia2dump例如:https://msdn.microsoft.com/en-us/library/hd8h6f46.aspx

我添加了一個新功能:

bool DumpFunctionsNm(IDiaSession *pSession) { 

    IDiaEnumSymbolsByAddr *pEnumSymbolsByAddr; 
    IDiaSymbol *pSymbol = (IDiaSymbol *) malloc(sizeof(IDiaSymbol)*2); 
    ULONG celt = 0; 
    wprintf(L"NM style output enabled\n"); 
    if (FAILED(pSession->getSymbolsByAddr(&pEnumSymbolsByAddr))){ 
    return false; 
    } 

    while (SUCCEEDED(pEnumSymbolsByAddr->Next(1, &pSymbol, &celt)) && (celt == 1)) { 
    IDiaEnumSymbols *pEnumFunction; 

     printf("iteration\n"); 
    } 
... 

但everyt時間我上運行(一個有效的PDB文件),我得到這個異常:

Exception thrown at 0x0FE1537B (msdia140.dll) in Dia2Dump.exe: 0xC0000005: Access violation reading location 0x00000000. 

If there is a handler for this exception, the program may be safely continued. 

所以,不知何故,某處有一個空的尊重。當我使用調試器運行時,我可以驗證pEnumSymbolsByAddr不爲NULL,並且傳遞給pEnumSymbolsByAddr->Next的指針不爲NULL。

我搜索SO,發現我並不孤單:Why does IDiaEnumSymbolsByAddr::Next crash?

我不能讓調試器來逐步裏面msdia140.dll,所以我不知道究竟是怎麼了。我還沒有找到成功使用pEnumSymbolsByAddr->Next功能的人。

+0

[IDiaEnumSymbolsByAddr :: symbolByAddr](https://msdn.microsoft.com/en-us/library/7dhd2yk6.aspx)通過圖像部分編號和偏移量查找。「*這聽起來像你必須在使用它之前初始化枚舉器,在遍歷其餘符號之前調用symbolByAddr接口函數。 – IInspectable

回答

1

您忘了初始化迭代器,請使用IDiaEnumSymbolsByAddr :: symbolByAddr()。產生第一個符號,調用Next()移到下一個符號。通過執行*「位置上的枚舉:只要按照在MSDN article所示的片段:

bool DumpFunctionsNm(IDiaSession *pSession) { 
    IDiaEnumSymbolsByAddr *pEnumSymbolsByAddr; 
    IDiaSymbol *pSymbol; 
    ULONG celt = 0; 
    wprintf(L"NM style output enabled\n"); 
    if (FAILED(pSession->getSymbolsByAddr(&pEnumSymbolsByAddr))) { 
     return false; 
    } 
    if (FAILED(pEnumSymbolsByAddr->symbolByAddr(1, 0, &pSymbol))) { 
     pEnumSymbolsByAddr->Release(); 
     return false; 
    } 
    do { 
     // Do something with symbol... 
     printf("iteration\n"); 
     pSymbol->Release(); 

     if (FAILED(pEnumSymbolsByAddr->Next(1, &pSymbol, &celt))) { 
      pEnumSymbolsByAddr->Release(); 
      return false; 
     } 
    } while (celt == 1); 
    pEnumSymbolsByAddr->Release(); 
    return true; 
} 
+1

我相信代碼泄漏COM對象,無論是失敗還是成功。 'IDiaEnumSymbolsByAddr'和'IDiaSymbol'應該是'Release()'d。不幸的是,MSDN決定使用智能指針庫,而不是直C提供示例代碼。 – IInspectable

+0

@IInspectable是的,我的原始代碼被截斷(Release()在'...'部分中) – zje