Search code examples
c++debuggingwinapidebug-symbolsdbghelp

Obtain function args from callstack address


I am printing out some debug information about the callstack. I can get the function name easily enough using SymFromAddr

void getFunctionInfo(FunctionInfo& funcInfo, uintptr_t address)
{
   DWORD64 dwDisplacement; //not used

   static char buffer[ sizeof(SYMBOL_INFO) + MAX_SYM_NAME ];
   PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) buffer;

   pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
   pSymbol->MaxNameLen = MAX_SYM_NAME;

   if ( SymFromAddr( m_process, address, &dwDisplacement, pSymbol) )
   {
    strcpy(funcInfo.funcName, pSymbol->Name, MAX_SYM_NAME);     
   }

   //TODO get function arguments 

}

However I want to reproduce the full signature of the function in order to disambiguate between overrides and basically reproduce what is shown in the visual studio callstack window. I am unable to find an api call to achieve this.

Is there one?


Solution

  • Thanks to @IInspectable for providing me with the answer: UnDecorateSymbolName

    This is my modified code:

    void getFunctionInfo(FunctionInfo& funcInfo, uintptr_t address)
    {
    
        static char buffer[ sizeof(SYMBOL_INFO) + MAX_SYM_NAME ];
        PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) buffer;
    
        pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
        pSymbol->MaxNameLen = MAX_SYM_NAME;
    
       //set sym options to get the mangled function name 
    
        DWORD64 dwDisplacement;
        DWORD options = SymGetOptions();
        DWORD newOptions = options & ~SYMOPT_UNDNAME;
        newOptions = newOptions | SYMOPT_PUBLICS_ONLY;
        SymSetOptions(newOptions);
    
        if (SymFromAddr(m_process, address, &dwDisplacement, pSymbol))  //m_process is set up elsewhere
        {
           //convert to full function name complete with params      
           char undecoratedName[MAX_SYM_NAME];
           UnDecorateSymbolName(pSymbol->Name, undecoratedName, MAX_SYM_NAME, UNDNAME_COMPLETE);
    
           strncpy(funcInfo.funcName, undecoratedName, MAX_SYM_NAME);
        }
    
        //revert to original options
        SymSetOptions(options);   
    }
    

    There is also a more complicated but more powerful way of getting function parameters and more besides by using SymGetTypeInfo. Details of this can be found at this excellent CodeProject article: Using PDB files and symbols to debug your application