#if wxUSE_DBGHELP
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// to prevent recursion which could result from corrupted data we limit
+// ourselves to that many levels of embedded fields inside structs
+static const unsigned MAX_DUMP_DEPTH = 20;
+
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
wxString s;
// avoid infinite recursion
- if ( level > 100 )
+ if ( level > MAX_DUMP_DEPTH )
{
return s;
}
wxDbgHelpDLL::DumpUDT(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
{
wxString s;
+
+ // 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 ( s == _T("wxString") )
{
wxString *ps = (wxString *)pVariable;
- s << _T("(\"") << *ps << _T(")\"");
+
+ // 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