+#if wxUSE_STACKWALKER
+ class StackDump : public wxStackWalker
+ {
+ public:
+ StackDump() { }
+
+ const wxString& GetStackTrace() const { return m_stackTrace; }
+
+ protected:
+ virtual void OnStackFrame(const wxStackFrame& frame)
+ {
+ m_stackTrace << wxString::Format(_T("[%02d] "), frame.GetLevel());
+
+ wxString name = frame.GetName();
+ if ( !name.empty() )
+ {
+ m_stackTrace << wxString::Format(_T("%-40s"), name.c_str());
+ }
+ else
+ {
+ m_stackTrace << wxString::Format
+ (
+ _T("0x%08lx"),
+ (unsigned long)frame.GetAddress()
+ );
+ }
+
+ if ( frame.HasSourceLocation() )
+ {
+ m_stackTrace << _T('\t')
+ << frame.GetFileName()
+ << _T(':')
+ << frame.GetLine();
+ }
+
+ m_stackTrace << _T('\n');
+ }
+
+ private:
+ wxString m_stackTrace;
+ };
+
+ StackDump dump;
+ dump.Walk(5); // don't show OnAssert() call itself
+ wxString stackTrace = dump.GetStackTrace();
+
+ // don't show more than maxLines or we could get a dialog too tall to be
+ // shown on screen: 20 should be ok everywhere as even with 15 pixel high
+ // characters it is still only 300 pixels...
+ const int maxLines = 20;
+ int count = stackTrace.Freq(wxT('\n'));
+ if (count > maxLines)
+ {
+ int i;
+ for (i = 0; i < count - maxLines; i++)
+ stackTrace = stackTrace.BeforeLast(wxT('\n'));
+ }
+ if ( !stackTrace.empty() )
+ {
+ msg << _T("\n\nCall stack:\n")
+ << stackTrace;
+ }
+#endif // wxUSE_STACKWALKER
+