2

目标:我正在尝试列出 pdb 文件中包含的所有函数的地址。

当前方法:我找到了 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");
  }
...

但是每次我运行它(在一个有效的 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.

所以,不知何故,某处存在 NULL 尊重。当我使用调试器运行时,我可以验证它pEnumSymbolsByAddr不是 NULL 并且传递给的指针pEnumSymbolsByAddr->Next不是 NULL。

我搜索了 SO,发现我并不孤单:为什么 IDiaEnumSymbolsByAddr::Next 崩溃?

我无法让调试器进入 msdia140.dll,所以我不知道到底出了什么问题。我还没有找到任何成功使用该pEnumSymbolsByAddr->Next功能的人。

4

1 回答 1

1

您忘记初始化迭代器,使用 IDiaEnumSymbolsByAddr::symbolByAddr()。这会产生第一个符号,调用 Next() 移动到下一个符号。只需按照MSDN 文章中显示的片段:

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;
}
于 2015-08-21T18:21:46.263 回答