2
votes

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
IDiaEnumSymbolsByAddr::symbolByAddr: "Positions the enumerator by performing a lookup by image section number and offset." This sounds like you have to initialize the enumerator before using it, by calling the symbolByAddr interface function prior to iterating over the remaining symbols.IInspectable

1 Answers

1
votes

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;
}