Iterating through Symbols in DIA SDK with getSymbolsByAddr

1.1k views Asked by At

GOAL: I'm trying to list the addresses of all functions contained in a pdb file.

CURRENT APPROACH: I found the DIA SDK and I'm modifying the dia2dump example: https://msdn.microsoft.com/en-us/library/hd8h6f46.aspx

I have added a new function:

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");
  }
...

But everyt time I run it (on a valid pdb file), I get this exception:

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.

So, somehow, somewhere there's a NULL deference. When I'm running with the debugger, I can verify that pEnumSymbolsByAddr is not NULL and that the pointers being passed to pEnumSymbolsByAddr->Next are not NULL.

I searched SO and found that I am not alone: Why does IDiaEnumSymbolsByAddr::Next crash?

I can't get the debugger to step inside msdia140.dll, so I don't know what exactly is going wrong. I am yet to find anyone who's successfully used the pEnumSymbolsByAddr->Next function.

1

There are 1 answers

2
Hans Passant On BEST ANSWER

You forgot to initialize the iterator, use IDiaEnumSymbolsByAddr::symbolByAddr(). That produces the first symbol, call Next() to move to the next one. Just follow the snippet shown in the 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;
}