0

我正在打印一些关于调用堆栈的调试信息。我可以使用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 

}

但是,我想重现函数的完整签名,以便消除覆盖之间的歧义,并基本上重现 Visual Studio 调用堆栈窗口中显示的内容。我无法找到实现此目的的 api 调用。

有吗?

4

1 回答 1

0

感谢@IInspectable 为我提供了答案:UnDecorateSymbolName

这是我修改后的代码:

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

除了使用SymGetTypeInfo之外,还有一种更复杂但更强大的方法来获取函数参数等等。可以在这篇出色的 CodeProject 文章中找到详细信息:使用 PDB 文件和符号来调试您的应用程序

于 2014-12-10T17:46:20.807 回答