2

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.

pauldoo
  • 18,087
  • 20
  • 94
  • 116

1 Answers1

2

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)
deemok
  • 2,735
  • 19
  • 11
  • It turns out that my overloaded functions took parameters of the same size, so `cdwParams` didn't cut it. However, the `ulOffStart` field on `FPO_DATA` turns out to be perfect. It gives "offset 1st byte of function code" according to WinNT.h. – pauldoo Jan 25 '09 at 16:48