debughlp.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 768 行 · 第 1/2 页
CPP
768 行
// we have to limit the depth of UDT dumping as otherwise we get in
// infinite loops trying to dump linked lists... 10 levels seems quite
// reasonable, full information is in minidump file anyhow
if ( level > 10 )
return s;
s.reserve(512);
s = GetSymbolName(pSym);
#if !wxUSE_STL
// special handling for ubiquitous wxString: although the code below works
// for it as well, it shows the wxStringBase class and takes 4 lines
// instead of only one as this branch
if ( s == _T("wxString") )
{
wxString *ps = (wxString *)pVariable;
// we can't just dump wxString directly as it could be corrupted or
// invalid and it could also be locked for writing (i.e. if we're
// between GetWriteBuf() and UngetWriteBuf() calls) and assert when we
// try to access it contents using public methods, so instead use our
// knowledge of its internals
const wxChar *p = NULL;
if ( !::IsBadReadPtr(ps, sizeof(wxString)) )
{
p = ps->data();
wxStringData *data = (wxStringData *)p - 1;
if ( ::IsBadReadPtr(data, sizeof(wxStringData)) ||
::IsBadReadPtr(p, sizeof(wxChar *)*data->nAllocLength) )
{
p = NULL; // don't touch this pointer with 10 feet pole
}
}
s << _T("(\"") << (p ? p : _T("???")) << _T(")\"");
}
else // any other UDT
#endif // !wxUSE_STL
{
// Determine how many children this type has.
DWORD dwChildrenCount = 0;
DoGetTypeInfo(pSym, TI_GET_CHILDRENCOUNT, &dwChildrenCount);
// Prepare to get an array of "TypeIds", representing each of the children.
TI_FINDCHILDREN_PARAMS *children = (TI_FINDCHILDREN_PARAMS *)
malloc(sizeof(TI_FINDCHILDREN_PARAMS) +
(dwChildrenCount - 1)*sizeof(ULONG));
if ( !children )
return s;
children->Count = dwChildrenCount;
children->Start = 0;
// Get the array of TypeIds, one for each child type
if ( !DoGetTypeInfo(pSym, TI_FINDCHILDREN, children) )
{
free(children);
return s;
}
s << _T(" {\n");
// Iterate through all children
SYMBOL_INFO sym;
wxZeroMemory(sym);
sym.ModBase = pSym->ModBase;
for ( unsigned i = 0; i < dwChildrenCount; i++ )
{
sym.TypeIndex = children->ChildId[i];
// children here are in lexicographic sense, i.e. we get all our nested
// classes and not only our member fields, but we can't get the values
// for the members of the nested classes, of course!
DWORD nested;
if ( DoGetTypeInfo(&sym, TI_GET_NESTED, &nested) && nested )
continue;
// avoid infinite recursion: this does seem to happen sometimes with
// complex typedefs...
if ( sym.TypeIndex == pSym->TypeIndex )
continue;
s += DumpField(&sym, pVariable, level + 1);
}
free(children);
s << wxString(_T('\t'), level + 1) << _T('}');
}
return s;
}
/* static */
wxDbgHelpDLL::SymbolTag
wxDbgHelpDLL::DereferenceSymbol(PSYMBOL_INFO pSym, void **ppData)
{
SymbolTag tag = SYMBOL_TAG_NULL;
for ( ;; )
{
if ( !DoGetTypeInfo(pSym, TI_GET_SYMTAG, &tag) )
break;
if ( tag != SYMBOL_TAG_POINTER_TYPE )
break;
ULONG tiNew;
if ( !DoGetTypeInfo(pSym, TI_GET_TYPEID, &tiNew) ||
tiNew == pSym->TypeIndex )
break;
pSym->TypeIndex = tiNew;
// remove one level of indirection except for the char strings: we want
// to dump "char *" and not a single "char" for them
if ( ppData && *ppData && GetBasicType(pSym) != BASICTYPE_CHAR )
{
DWORD_PTR *pData = (DWORD_PTR *)*ppData;
if ( ::IsBadReadPtr(pData, sizeof(DWORD_PTR *)) )
{
break;
}
*ppData = (void *)*pData;
}
}
return tag;
}
/* static */ wxString
wxDbgHelpDLL::DumpSymbol(PSYMBOL_INFO pSym, void *pVariable)
{
wxString s;
SYMBOL_INFO symDeref = *pSym;
switch ( DereferenceSymbol(&symDeref, &pVariable) )
{
case SYMBOL_TAG_UDT:
// show UDT recursively
s = DumpUDT(&symDeref, pVariable);
break;
case SYMBOL_TAG_BASE_TYPE:
// variable of simple type, show directly
BasicType bt = GetBasicType(&symDeref);
if ( bt )
{
s = DumpBaseType(bt, pSym->Size, pVariable);
}
break;
}
return s;
}
// ----------------------------------------------------------------------------
// debugging helpers
// ----------------------------------------------------------------------------
// this code is very useful when debugging debughlp.dll-related code but
// probably not worth having compiled in normally, please do not remove it!
#if 0 // ndef NDEBUG
static wxString TagString(wxDbgHelpDLL::SymbolTag tag)
{
static const wxChar *tags[] =
{
_T("null"),
_T("exe"),
_T("compiland"),
_T("compiland details"),
_T("compiland env"),
_T("function"),
_T("block"),
_T("data"),
_T("annotation"),
_T("label"),
_T("public symbol"),
_T("udt"),
_T("enum"),
_T("function type"),
_T("pointer type"),
_T("array type"),
_T("base type"),
_T("typedef"),
_T("base class"),
_T("friend"),
_T("function arg type"),
_T("func debug start"),
_T("func debug end"),
_T("using namespace"),
_T("vtable shape"),
_T("vtable"),
_T("custom"),
_T("thunk"),
_T("custom type"),
_T("managed type"),
_T("dimension"),
};
wxCOMPILE_TIME_ASSERT( WXSIZEOF(tags) == wxDbgHelpDLL::SYMBOL_TAG_MAX,
SymbolTagStringMismatch );
wxString s;
if ( tag < WXSIZEOF(tags) )
s = tags[tag];
else
s.Printf(_T("unrecognized tag (%d)"), tag);
return s;
}
static wxString KindString(wxDbgHelpDLL::DataKind kind)
{
static const wxChar *kinds[] =
{
_T("unknown"),
_T("local"),
_T("static local"),
_T("param"),
_T("object ptr"),
_T("file static"),
_T("global"),
_T("member"),
_T("static member"),
_T("constant"),
};
wxCOMPILE_TIME_ASSERT( WXSIZEOF(kinds) == wxDbgHelpDLL::DATA_MAX,
DataKindStringMismatch );
wxString s;
if ( kind < WXSIZEOF(kinds) )
s = kinds[kind];
else
s.Printf(_T("unrecognized kind (%d)"), kind);
return s;
}
static wxString UdtKindString(wxDbgHelpDLL::UdtKind kind)
{
static const wxChar *kinds[] =
{
_T("struct"),
_T("class"),
_T("union"),
};
wxCOMPILE_TIME_ASSERT( WXSIZEOF(kinds) == wxDbgHelpDLL::UDT_MAX,
UDTKindStringMismatch );
wxString s;
if ( kind < WXSIZEOF(kinds) )
s = kinds[kind];
else
s.Printf(_T("unrecognized UDT (%d)"), kind);
return s;
}
static wxString TypeString(wxDbgHelpDLL::BasicType bt)
{
static const wxChar *types[] =
{
_T("no type"),
_T("void"),
_T("char"),
_T("wchar"),
_T(""),
_T(""),
_T("int"),
_T("uint"),
_T("float"),
_T("bcd"),
_T("bool"),
_T(""),
_T(""),
_T("long"),
_T("ulong"),
_T(""),
_T(""),
_T(""),
_T(""),
_T(""),
_T(""),
_T(""),
_T(""),
_T(""),
_T(""),
_T("CURRENCY"),
_T("DATE"),
_T("VARIANT"),
_T("complex"),
_T("bit"),
_T("BSTR"),
_T("HRESULT"),
};
wxCOMPILE_TIME_ASSERT( WXSIZEOF(types) == wxDbgHelpDLL::BASICTYPE_MAX,
BasicTypeStringMismatch );
wxString s;
if ( bt < WXSIZEOF(types) )
s = types[bt];
if ( s.empty() )
s.Printf(_T("unrecognized type (%d)"), bt);
return s;
}
// this function is meant to be called from under debugger to see the
// proprieties of the given type id
extern "C" void DumpTI(ULONG ti)
{
SYMBOL_INFO sym = { sizeof(SYMBOL_INFO) };
sym.ModBase = 0x400000; // it's a constant under Win32
sym.TypeIndex = ti;
wxDbgHelpDLL::SymbolTag tag = wxDbgHelpDLL::SYMBOL_TAG_NULL;
DoGetTypeInfo(&sym, TI_GET_SYMTAG, &tag);
DoGetTypeInfo(&sym, TI_GET_TYPEID, &ti);
OutputDebugString(wxString::Format(_T("Type 0x%x: "), sym.TypeIndex));
wxString name = wxDbgHelpDLL::GetSymbolName(&sym);
if ( !name.empty() )
{
OutputDebugString(wxString::Format(_T("name=\"%s\", "), name.c_str()));
}
DWORD nested;
if ( !DoGetTypeInfo(&sym, TI_GET_NESTED, &nested) )
{
nested = FALSE;
}
OutputDebugString(wxString::Format(_T("tag=%s%s"),
nested ? _T("nested ") : wxEmptyString,
TagString(tag).c_str()));
if ( tag == wxDbgHelpDLL::SYMBOL_TAG_UDT )
{
wxDbgHelpDLL::UdtKind udtKind;
if ( DoGetTypeInfo(&sym, TI_GET_UDTKIND, &udtKind) )
{
OutputDebugString(_T(" (") + UdtKindString(udtKind) + _T(')'));
}
}
wxDbgHelpDLL::DataKind kind = wxDbgHelpDLL::DATA_UNKNOWN;
if ( DoGetTypeInfo(&sym, TI_GET_DATAKIND, &kind) )
{
OutputDebugString(wxString::Format(
_T(", kind=%s"), KindString(kind).c_str()));
if ( kind == wxDbgHelpDLL::DATA_MEMBER )
{
DWORD ofs = 0;
if ( DoGetTypeInfo(&sym, TI_GET_OFFSET, &ofs) )
{
OutputDebugString(wxString::Format(_T(" (ofs=0x%x)"), ofs));
}
}
}
wxDbgHelpDLL::BasicType bt = GetBasicType(&sym);
if ( bt )
{
OutputDebugString(wxString::Format(_T(", type=%s"),
TypeString(bt).c_str()));
}
if ( ti != sym.TypeIndex )
{
OutputDebugString(wxString::Format(_T(", next ti=0x%x"), ti));
}
OutputDebugString(_T("\r\n"));
}
#endif // NDEBUG
#endif // wxUSE_DBGHELP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?