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 ではなく、渡されるポインターが NULL でないことを確認できpEnumSymbolsByAddr->Nextます。

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 に答える