mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
try to get stack traces for InternalErrors, it doesn't work yet for errors caught with OnExceptionInMainLoop, because they are rethrown.
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1260 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -9,6 +9,10 @@
|
||||
#include <util/prec.hpp>
|
||||
#include <util/error.hpp>
|
||||
#include <cli/text_io_handler.hpp>
|
||||
#include <cli/text_io_handler.hpp>
|
||||
#if wxUSE_STACKWALKER
|
||||
#include <wx/stackwalk.h>
|
||||
#endif
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(ScriptParseError);
|
||||
|
||||
@@ -43,6 +47,85 @@ String Error::what() const {
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Stolen from wx/appbase.cpp
|
||||
// we can't just call it, because of static linkage
|
||||
#if wxUSE_STACKWALKER
|
||||
String get_stack_trace() {
|
||||
wxString stackTrace;
|
||||
|
||||
class StackDumper : public wxStackWalker {
|
||||
public:
|
||||
StackDumper() {}
|
||||
|
||||
const wxString& GetStackTrace() const { return m_stackTrace; }
|
||||
|
||||
protected:
|
||||
virtual void OnStackFrame(const wxStackFrame& frame) {
|
||||
m_stackTrace << wxString::Format(_("[%02d] "), frame.GetLevel());
|
||||
|
||||
wxString name = frame.GetName();
|
||||
if ( !name.empty() ) {
|
||||
m_stackTrace << wxString::Format(_("%-40s"), name.c_str());
|
||||
} else {
|
||||
m_stackTrace << wxString::Format(
|
||||
_("%p"),
|
||||
(void*)frame.GetAddress()
|
||||
);
|
||||
}
|
||||
|
||||
if ( frame.HasSourceLocation() ) {
|
||||
m_stackTrace << _('\t')
|
||||
<< frame.GetFileName()
|
||||
<< _(':')
|
||||
<< (unsigned int)frame.GetLine();
|
||||
}
|
||||
|
||||
m_stackTrace << _('\n');
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_stackTrace;
|
||||
};
|
||||
|
||||
StackDumper dump;
|
||||
dump.Walk(2); // don't show InternalError() call itself
|
||||
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...
|
||||
static const int maxLines = 20;
|
||||
const int count = stackTrace.Freq(wxT('\n'));
|
||||
for ( int i = 0; i < count - maxLines; i++ )
|
||||
stackTrace = stackTrace.BeforeLast(wxT('\n'));
|
||||
|
||||
return stackTrace;
|
||||
}
|
||||
#else
|
||||
String get_stack_trace() {
|
||||
return _(""); // not supported
|
||||
}
|
||||
#endif // wxUSE_STACKWALKER
|
||||
|
||||
InternalError::InternalError(const String& str)
|
||||
: Error(
|
||||
_("An internal error occured:\n\n") +
|
||||
str + _("\n")
|
||||
_("Please save your work (use 'save as' to so you don't overwrite things)\n")
|
||||
_("and restart Magic Set Editor.\n\n")
|
||||
_("You should leave a bug report on http://magicseteditor.sourceforge.net/\n")
|
||||
_("Press Ctrl+C to copy this message to the clipboard.")
|
||||
)
|
||||
{
|
||||
// add a stacktrace
|
||||
const String stack_trace = get_stack_trace();
|
||||
if (!stack_trace.empty()) {
|
||||
message << _("\n\nCall stack:\n") << stack_trace;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Parse errors
|
||||
|
||||
ScriptParseError::ScriptParseError(size_t pos, int line, const String& filename, const String& error)
|
||||
|
||||
+5
-4
@@ -27,7 +27,7 @@ class Error {
|
||||
/// Return the error message
|
||||
virtual String what() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
String message; ///< The error message
|
||||
};
|
||||
|
||||
@@ -35,9 +35,7 @@ class Error {
|
||||
/// Internal errors
|
||||
class InternalError : public Error {
|
||||
public:
|
||||
inline InternalError(const String& str)
|
||||
: Error(_ERROR_1_("internal error", str.c_str()))
|
||||
{}
|
||||
InternalError(const String& str);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : File errors
|
||||
@@ -148,6 +146,9 @@ void handle_warning(const String& w, bool now = true);
|
||||
/** Should be called repeatedly (e.g. in an onIdle event handler) */
|
||||
void handle_pending_errors();
|
||||
|
||||
/// Make a stack trace for use in InternalErrors
|
||||
String get_stack_trace();
|
||||
|
||||
/// Catch all types of errors, and pass then to handle_error
|
||||
#define CATCH_ALL_ERRORS(handle_now) \
|
||||
catch (const Error& e) { \
|
||||
|
||||
Reference in New Issue
Block a user