DBG: use undocumented __unDNameEx function to significantly speed up symbol loading
Before: Loaded 313534 line infos in 47.406 Loaded 140366 symbols in 171.640 After: Loaded 313534 line infos in 4.187 Loaded 140366 symbols in 9.391
This commit is contained in:
parent
a9782ac6c6
commit
82774e2445
|
@ -1,3 +1,4 @@
|
||||||
|
#include "_global.h"
|
||||||
#include <comutil.h>
|
#include <comutil.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
@ -10,6 +11,7 @@
|
||||||
|
|
||||||
#include "pdbdiafile.h"
|
#include "pdbdiafile.h"
|
||||||
#include "stringutils.h"
|
#include "stringutils.h"
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
volatile LONG PDBDiaFile::m_sbInitialized = 0;
|
volatile LONG PDBDiaFile::m_sbInitialized = 0;
|
||||||
|
|
||||||
|
@ -802,6 +804,50 @@ bool PDBDiaFile::resolveSymbolSize(IDiaSymbol* symbol, uint64_t & size, uint32_t
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef char* pchar_t;
|
||||||
|
typedef const char* pcchar_t;
|
||||||
|
typedef char* (*GetParameter_t)(long n);
|
||||||
|
using Alloc_t = decltype(malloc);
|
||||||
|
using Free_t = decltype(free);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
UNDNAME_COMPLETE = 0x0, //Enables full undecoration.
|
||||||
|
UNDNAME_NO_LEADING_UNDERSCORES = 0x1, //Removes leading underscores from Microsoft extended keywords.
|
||||||
|
UNDNAME_NO_MS_KEYWORDS = 0x2, //Disables expansion of Microsoft extended keywords.
|
||||||
|
UNDNAME_NO_FUNCTION_RETURNS = 0x4, //Disables expansion of return type for primary declaration.
|
||||||
|
UNDNAME_NO_ALLOCATION_MODEL = 0x8, //Disables expansion of the declaration model.
|
||||||
|
UNDNAME_NO_ALLOCATION_LANGUAGE = 0x10, //Disables expansion of the declaration language specifier.
|
||||||
|
UNDNAME_NO_MS_THISTYPE = 0x20, //NYI Disable expansion of MS keywords on the 'this' type for primary declaration.
|
||||||
|
UNDNAME_NO_CV_THISTYPE = 0x40, //NYI Disable expansion of CV modifiers on the 'this' type for primary declaration/
|
||||||
|
UNDNAME_NO_THISTYPE = 0x60, //Disables all modifiers on the this type.
|
||||||
|
UNDNAME_NO_ACCESS_SPECIFIERS = 0x80, //Disables expansion of access specifiers for members.
|
||||||
|
UNDNAME_NO_THROW_SIGNATURES = 0x100, //Disables expansion of "throw-signatures" for functions and pointers to functions.
|
||||||
|
UNDNAME_NO_MEMBER_TYPE = 0x200, //Disables expansion of static or virtual members.
|
||||||
|
UNDNAME_NO_RETURN_UDT_MODEL = 0x400, //Disables expansion of the Microsoft model for UDT returns.
|
||||||
|
UNDNAME_32_BIT_DECODE = 0x800, //Undecorates 32-bit decorated names.
|
||||||
|
UNDNAME_NAME_ONLY = 0x1000, //Gets only the name for primary declaration; returns just [scope::]name. Expands template params.
|
||||||
|
UNDNAME_TYPE_ONLY = 0x2000, //Input is just a type encoding; composes an abstract declarator.
|
||||||
|
UNDNAME_HAVE_PARAMETERS = 0x4000, //The real template parameters are available.
|
||||||
|
UNDNAME_NO_ECSU = 0x8000, //Suppresses enum/class/struct/union.
|
||||||
|
UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000, //Suppresses check for valid identifier characters.
|
||||||
|
UNDNAME_NO_PTR64 = 0x20000, //Does not include ptr64 in output.
|
||||||
|
};
|
||||||
|
|
||||||
|
#if _MSC_VER != 1800
|
||||||
|
#error unDNameEx is undocumented and possibly unsupported on your runtime! Uncomment this line if you understand the risks and want continue regardless...
|
||||||
|
#endif //_MSC_VER
|
||||||
|
|
||||||
|
//undname.cxx
|
||||||
|
extern "C" pchar_t __cdecl __unDNameEx(_Out_opt_z_cap_(maxStringLength) pchar_t outputString,
|
||||||
|
pcchar_t name,
|
||||||
|
int maxStringLength, // Note, COMMA is leading following optional arguments
|
||||||
|
Alloc_t pAlloc,
|
||||||
|
Free_t pFree,
|
||||||
|
GetParameter_t pGetParameter,
|
||||||
|
unsigned long disableFlags
|
||||||
|
);
|
||||||
|
|
||||||
bool PDBDiaFile::convertSymbolInfo(IDiaSymbol* symbol, DiaSymbol_t & symbolInfo, const bool collectUndecoratedNames)
|
bool PDBDiaFile::convertSymbolInfo(IDiaSymbol* symbol, DiaSymbol_t & symbolInfo, const bool collectUndecoratedNames)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -825,9 +871,38 @@ bool PDBDiaFile::convertSymbolInfo(IDiaSymbol* symbol, DiaSymbol_t & symbolInfo,
|
||||||
|
|
||||||
symbolInfo.name = getSymbolNameString(symbol);
|
symbolInfo.name = getSymbolNameString(symbol);
|
||||||
|
|
||||||
if(collectUndecoratedNames)
|
if(collectUndecoratedNames && !symbolInfo.name.empty() && symbolInfo.name.at(0) == '?')
|
||||||
{
|
{
|
||||||
symbolInfo.undecoratedName = getSymbolUndecoratedNameString(symbol);
|
//TODO: undocumented hack to have some kind of performance while undecorating names
|
||||||
|
auto mymalloc = [](size_t size) { return emalloc(size, "convertSymbolInfo::undecoratedName"); };
|
||||||
|
auto myfree = [](void* ptr) { return efree(ptr, "convertSymbolInfo::undecoratedName"); };
|
||||||
|
symbolInfo.undecoratedName.resize(max(512, symbolInfo.name.length() * 2));
|
||||||
|
if(!__unDNameEx((char*)symbolInfo.undecoratedName.data(),
|
||||||
|
symbolInfo.name.c_str(),
|
||||||
|
symbolInfo.undecoratedName.size(),
|
||||||
|
mymalloc,
|
||||||
|
myfree,
|
||||||
|
nullptr,
|
||||||
|
UNDNAME_COMPLETE))
|
||||||
|
{
|
||||||
|
symbolInfo.undecoratedName.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
symbolInfo.undecoratedName.resize(strlen(symbolInfo.undecoratedName.c_str()));
|
||||||
|
if(symbolInfo.name == symbolInfo.undecoratedName)
|
||||||
|
symbolInfo.undecoratedName = ""; //https://stackoverflow.com/a/18299315
|
||||||
|
/*auto test = getSymbolUndecoratedNameString(symbol); //TODO: this does not appear to work very well
|
||||||
|
if(!symbolInfo.undecoratedName.empty())
|
||||||
|
{
|
||||||
|
if(test != symbolInfo.undecoratedName)
|
||||||
|
{
|
||||||
|
dprintf("undecoration mismatch, msvcrt: \"%s\", DIA: \"%s\"\n",
|
||||||
|
symbolInfo.undecoratedName.c_str(),
|
||||||
|
test.c_str());
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = symbol->get_addressSection((DWORD*)&symbolInfo.segment);
|
hr = symbol->get_addressSection((DWORD*)&symbolInfo.segment);
|
||||||
|
|
|
@ -79,10 +79,9 @@ void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a mangled/decorated C++ name to a readable format
|
// Don't show duplicated decorated/undecorated names
|
||||||
if(info.decoratedName == info.undecoratedName)
|
if(info.undecoratedName.empty() || info.decoratedName == info.undecoratedName)
|
||||||
{
|
{
|
||||||
curSymbol.decoratedSymbol = curSymbol.undecoratedSymbol;
|
|
||||||
curSymbol.undecoratedSymbol = nullptr;
|
curSymbol.undecoratedSymbol = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -305,10 +305,18 @@ void SymbolView::cbSymbolEnum(SYMBOLINFO* symbol, void* user)
|
||||||
{
|
{
|
||||||
symbolList->setCellContent(index, 2, symbol->decoratedSymbol);
|
symbolList->setCellContent(index, 2, symbol->decoratedSymbol);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
symbolList->setCellContent(index, 2, QString());
|
||||||
|
}
|
||||||
if(symbol->undecoratedSymbol)
|
if(symbol->undecoratedSymbol)
|
||||||
{
|
{
|
||||||
symbolList->setCellContent(index, 3, symbol->undecoratedSymbol);
|
symbolList->setCellContent(index, 3, symbol->undecoratedSymbol);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
symbolList->setCellContent(index, 3, QString());
|
||||||
|
}
|
||||||
|
|
||||||
if(symbol->isImported)
|
if(symbol->isImported)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue