diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp
index 93a47aad1b..cfd8bd5c41 100644
--- a/src/common/appbase.cpp
+++ b/src/common/appbase.cpp
@@ -1012,25 +1012,37 @@ wxString wxAppTraitsBase::GetAssertStackTrace()
#endif // !__WINDOWS__
- wxString stackTrace;
-
class StackDump : public wxStackWalker
{
public:
- StackDump() { }
+ StackDump() { m_numFrames = 0; }
const wxString& GetStackTrace() const { return m_stackTrace; }
protected:
virtual void OnStackFrame(const wxStackFrame& frame) wxOVERRIDE
{
- m_stackTrace << wxString::Format
- (
- wxT("[%02d] "),
- wx_truncate_cast(int, frame.GetLevel())
- );
+ // 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...
+ if ( m_numFrames++ > 20 )
+ return;
+
+ m_stackTrace << wxString::Format(wxT("[%02u] "), m_numFrames);
+
+ const wxString name = frame.GetName();
+ if ( name.StartsWith("wxOnAssert") )
+ {
+ // Ignore all frames until the wxOnAssert() one, they are
+ // internal to wxWidgets and not interesting for the user
+ // (but notice that if we never find the wxOnAssert() frame,
+ // e.g. because we don't have symbol info at all, we would show
+ // everything which is better than not showing anything).
+ m_stackTrace.clear();
+ m_numFrames = 0;
+ return;
+ }
- wxString name = frame.GetName();
if ( !name.empty() )
{
m_stackTrace << wxString::Format(wxT("%-40s"), name.c_str());
@@ -1053,22 +1065,12 @@ wxString wxAppTraitsBase::GetAssertStackTrace()
private:
wxString m_stackTrace;
+ unsigned m_numFrames;
};
- // 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...
- static const int maxLines = 20;
-
StackDump dump;
- dump.Walk(8, maxLines); // 8 is chosen to hide all OnAssert() calls
- stackTrace = dump.GetStackTrace();
-
- const int count = stackTrace.Freq(wxT('\n'));
- for ( int i = 0; i < count - maxLines; i++ )
- stackTrace = stackTrace.BeforeLast(wxT('\n'));
-
- return stackTrace;
+ dump.Walk();
+ return dump.GetStackTrace();
#else // !wxDEBUG_LEVEL
// this function is still present for ABI-compatibility even in debug level
// 0 build but is not used there and so can simply do nothing
diff --git a/src/gtk/utilsgtk.cpp b/src/gtk/utilsgtk.cpp
index d1603d7f1a..36c5013722 100644
--- a/src/gtk/utilsgtk.cpp
+++ b/src/gtk/utilsgtk.cpp
@@ -20,6 +20,7 @@
#include "wx/apptrait.h"
#include "wx/process.h"
#include "wx/sysopt.h"
+#include "wx/vector.h"
#include "wx/gtk/private/timer.h"
#include "wx/evtloop.h"
@@ -254,30 +255,68 @@ class StackDump : public wxStackWalker
public:
StackDump(GtkAssertDialog *dlg) { m_dlg=dlg; }
+ void ShowStackInDialog()
+ {
+ ProcessFrames(0);
+
+ for ( wxVector::const_iterator it = m_frames.begin();
+ it != m_frames.end();
+ ++it )
+ {
+ gtk_assert_dialog_append_stack_frame(m_dlg,
+ it->name.utf8_str(),
+ it->file.utf8_str(),
+ it->line);
+ }
+
+ m_frames.clear();
+ }
+
protected:
virtual void OnStackFrame(const wxStackFrame& frame) wxOVERRIDE
{
- wxString fncname = frame.GetName();
-
- // append this stack frame's info in the dialog
- if (!frame.GetFileName().empty() || !fncname.empty())
+ const wxString name = frame.GetName();
+ if ( name.StartsWith("wxOnAssert") )
{
- gtk_assert_dialog_append_stack_frame(m_dlg,
- fncname.utf8_str(),
- frame.GetFileName().utf8_str(),
- frame.GetLine());
+ // Ignore all frames until the wxOnAssert() one, just as we do in
+ // wxAppTraitsBase::GetAssertStackTrace().
+ m_frames.clear();
+ return;
}
+
+ // Also ignore frames which don't have neither the function name nor
+ // the file name, showing them in the dialog wouldn't provide any
+ // useful information.
+ if ( name.empty() && frame.GetFileName().empty() )
+ return;
+
+ m_frames.push_back(Frame(frame));
}
private:
GtkAssertDialog *m_dlg;
+
+ struct Frame
+ {
+ explicit Frame(const wxStackFrame& f)
+ : name(f.GetName()),
+ file(f.GetFileName()),
+ line(f.GetLine())
+ {
+ }
+
+ wxString name;
+ wxString file;
+ int line;
+ };
+
+ wxVector m_frames;
};
static void get_stackframe_callback(void* p)
{
StackDump* dump = static_cast(p);
- // skip over frames up to including wxOnAssert()
- dump->ProcessFrames(6);
+ dump->ShowStackInDialog();
}
#endif // wxDEBUG_LEVEL && wxUSE_STACKWALKER