Search code examples
debuggingwindbgdbgeng

IDebugSymbols::GetNameByOffset and overloaded functions


I'm using IDebugSymbols::GetNameByOffset and I'm finding that I get the same symbol name for different functions that overload the same name.

E.g. The code I'm looking up the symbols for might be as follows:

void SomeFunction(int) {..}
void SomeFunction(float) {..}

At runtime, when I have an address of an instruction from each of these functions I'd like to use GetNameByOffset and tell the two apart somehow. I've experimented with calling SetSymbolOptions toggling the SYMOPT_UNDNAME and SYMOPT_NO_CPP flags as documented here, but this didn't work.

Does anyone know how to tell these to symbols apart in the debugger engine universe?


Edit: Please see me comment on the accepted answer for a minor amendment to the proposed solution.


Solution

  • Quote from dbgeng.h:

        // A symbol name may not be unique, particularly
        // when overloaded functions exist which all
        // have the same name.  If GetOffsetByName
        // finds multiple matches for the name it
        // can return any one of them.  In that
        // case it will return S_FALSE to indicate
        // that ambiguity was arbitrarily resolved.
        // A caller can then use SearchSymbols to
        // find all of the matches if it wishes to
        // perform different disambiguation.
        STDMETHOD(GetOffsetByName)(
            THIS_
            __in PCSTR Symbol,
            __out PULONG64 Offset
            ) PURE;
    

    So, I would get the name with IDebugSymbols::GetNameByOffset() (it comes back like "module!name" I believe), make sure it is an overload (if you're not sure) using IDebugSymbols::GetOffsetByName() (which is supposed to return S_FALSE for multiple overloads), and look up all possibilities with this name using StartSymbolMatch()/EndSymbolMatch(). Not a one liner though (and not really helpful for that matter...)

    Another option would be to go with

    HRESULT
      IDebugSymbols3::GetFunctionEntryByOffset(
        IN ULONG64  Offset,
        IN ULONG  Flags,
        OUT OPTIONAL PVOID  Buffer,
        IN ULONG  BufferSize,
        OUT OPTIONAL PULONG  BufferNeeded
        );
    // It can be used to retrieve FPO data on a particular function:
    FPO_DATA fpo;
    HRESULT hres=m_Symbols3->GetFunctionEntryByOffset(
            addr,   // Offset
            0,      // Flags
            &fpo,       // Buffer
            sizeof(fpo),    // BufferSize
            0       // BufferNeeded
            ));
    
    and then use fpo.cdwParams for basic parameter size discrimination (cdwParams=size of parameters)