Search code examples
windbgdbghelp

Find address of a symbols of a class method using dbghelp


I'm trying to use dbghelp in order to find the address of a class method. For example, a DirectX method (DXGI): dxgi!CDXGIFactory::CreateSwapChainImpl

I've the correct symbols and _NT_SYMBOLS_PATH is defined. Using WinDBG, the following 'x' command is working fine:

0:000> x dxgi!CDXGIFactory::CreateSwapChain
6acb78ce          dxgi!CDXGIFactory::CreateSwapChain (<no parameter info>)
6acdaf69          dxgi!CDXGIFactory::CreateSwapChain (<no parameter info>)

However, trying to use this string with SymFromName, I'm getting an error 1168 (Element not found):

result = SymFromName( hprocess, L"dxgi!CDXGIFactory::CreateSwapChain", &symbol )
// result is false, GetLastError is 1168

Does it fail because of the '::', or because there are two addresses for the same symbol (how do I work around?).


Solution

  • It is definitely the SYMOPT_EXACT_SYMBOL setting which is causing the 1168 error to be thrown. Otherwise having multiple symbols or '::' is fine, and the API can return a valid address.

    One work-around would be to use mangled names:

    #pragma optimize("", off)
    class base
    {
    public:
        void method(int i)    { printf("in method(int)\n"); }
        void method(double d) { printf("in method(double)\n"); }
    };
    
    int __cdecl main(int argc, char* argv[])
    {
        HANDLE hProcess = GetCurrentProcess();
        SymInitialize(hProcess, NULL, TRUE);
        SymSetOptions(SYMOPT_EXACT_SYMBOLS);
        SetLastError(0);
    
        SYMBOL_INFO symbol = {0};
        symbol.SizeOfStruct = sizeof(symbol);
    
        BOOL result = SymFromName(hProcess, "cpptest!?method@base@@QEAAXH@Z", &symbol);
    
        printf("symbol : 0x%I64X\n", symbol.Address);
        printf("error : %u, result : %u\n", GetLastError(), result);
    
        return 0;
    }
    


    And for future reference, WinDbg uses the IDebugSymbols::StartSymbolMatch API to lookup multiple symbols.