From 12df88ecf9787f4ed59051646775165b74301cf0 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 5 Oct 2013 15:20:18 +0300 Subject: [PATCH] Implement graphical reporting for uncaught exceptions --- source/graphics/cocoa/display.cpp | 2 ++ source/graphics/cocoa/errordialog.cpp | 22 ++++++++++++++++++++++ source/graphics/cocoa/errordialog.m | 16 ++++++++++++++++ source/graphics/display.h | 2 ++ source/graphics/errordialog.h | 25 +++++++++++++++++++++++++ source/graphics/windows/display.cpp | 2 ++ source/graphics/windows/errordialog.cpp | 19 +++++++++++++++++++ source/graphics/x11/display.cpp | 3 +++ source/graphics/x11/errordialog.cpp | 15 +++++++++++++++ 9 files changed, 106 insertions(+) create mode 100644 source/graphics/cocoa/errordialog.cpp create mode 100644 source/graphics/cocoa/errordialog.m create mode 100644 source/graphics/errordialog.h create mode 100644 source/graphics/windows/errordialog.cpp create mode 100644 source/graphics/x11/errordialog.cpp diff --git a/source/graphics/cocoa/display.cpp b/source/graphics/cocoa/display.cpp index 5be28cd..c6824b8 100644 --- a/source/graphics/cocoa/display.cpp +++ b/source/graphics/cocoa/display.cpp @@ -11,6 +11,8 @@ namespace Graphics { Display::Display(const std::string &): priv(new Private) { + static ErrorDialog err_dlg(0); + priv->display = create_display(); } diff --git a/source/graphics/cocoa/errordialog.cpp b/source/graphics/cocoa/errordialog.cpp new file mode 100644 index 0000000..ec44461 --- /dev/null +++ b/source/graphics/cocoa/errordialog.cpp @@ -0,0 +1,22 @@ +#include "errordialog.h" + +using namespace std; + +extern "C" void run_alert(const char *, const char *); + +namespace Msp { +namespace Graphics { + +bool ErrorDialog::report_uncaught_exception(const exception &e) const +{ + if(Application::get_data()) + { + string type = Debug::demangle(typeid(e).name()); + run_alert(type.c_str(), e.what()); + return true; + } + return false; +} + +} // namespace Graphics +} // namespace Msp diff --git a/source/graphics/cocoa/errordialog.m b/source/graphics/cocoa/errordialog.m new file mode 100644 index 0000000..2b6b3c6 --- /dev/null +++ b/source/graphics/cocoa/errordialog.m @@ -0,0 +1,16 @@ +#import +#import + +// The function gets incorrect linkage without a prototype +void run_alert(const char *, const char *); + +void run_alert(const char *type, const char *what) +{ + NSString *message = [[[NSString stringWithUTF8String:type] stringByAppendingString:@": "] + stringByAppendingString:[NSString stringWithUTF8String:what]]; + NSAlert *alert = [NSAlert alertWithMessageText:@"Uncaught exception" + defaultButton:nil alternateButton:nil otherButton:nil + informativeTextWithFormat:@"%@", message]; + [alert runModal]; +} + diff --git a/source/graphics/display.h b/source/graphics/display.h index 8d2f618..bff17c3 100644 --- a/source/graphics/display.h +++ b/source/graphics/display.h @@ -4,6 +4,7 @@ #include #include #include +#include "errordialog.h" #include "monitor.h" #include "videomode.h" @@ -22,6 +23,7 @@ private: Monitor *primary_monitor; std::list modes; Private *priv; + ErrorDialog *err_dialog; public: Display(const std::string &disp_name = std::string()); diff --git a/source/graphics/errordialog.h b/source/graphics/errordialog.h new file mode 100644 index 0000000..7ece72e --- /dev/null +++ b/source/graphics/errordialog.h @@ -0,0 +1,25 @@ +#ifndef MSP_GRAPHICS_ERRORDIALOG_H_ +#define MSP_GRAPHICS_ERRORDIALOG_H_ + +#include + +namespace Msp { +namespace Graphics { + +class Display; + +class ErrorDialog: public Debug::ErrorReporter +{ +private: + Display *display; + +public: + ErrorDialog(Display *d): display(d) { } + + virtual bool report_uncaught_exception(const std::exception &) const; +}; + +} // namespace Graphics +} // namespace Msp + +#endif diff --git a/source/graphics/windows/display.cpp b/source/graphics/windows/display.cpp index 6553a8c..7b61666 100644 --- a/source/graphics/windows/display.cpp +++ b/source/graphics/windows/display.cpp @@ -11,6 +11,8 @@ Display::Display(const string &): primary_monitor(0), priv(new Private) { + static ErrorDialog err_dlg(0); + for(unsigned i=0;; ++i) { DISPLAY_DEVICE adapter_dev; diff --git a/source/graphics/windows/errordialog.cpp b/source/graphics/windows/errordialog.cpp new file mode 100644 index 0000000..5215039 --- /dev/null +++ b/source/graphics/windows/errordialog.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include "errordialog.h" + +using namespace std; + +namespace Msp { +namespace Graphics { + +bool ErrorDialog::report_uncaught_exception(const exception &e) const +{ + string msg = Debug::demangle(typeid(e).name())+":\n"+e.what(); + MessageBoxA(0, msg.c_str(), "Uncaught exception", MB_OK|MB_ICONERROR); + return false; +} + +} // namespace Graphics +} // namespace Msp diff --git a/source/graphics/x11/display.cpp b/source/graphics/x11/display.cpp index 6f677c3..70b77c6 100644 --- a/source/graphics/x11/display.cpp +++ b/source/graphics/x11/display.cpp @@ -94,6 +94,8 @@ Display::Display(const string &disp_name): XSetErrorHandler(x_error_handler); + err_dialog = new ErrorDialog(this); + #ifdef WITH_XRANDR int event_base; int error_base; @@ -200,6 +202,7 @@ Display::~Display() { XCloseDisplay(priv->display); delete priv; + delete err_dialog; } void Display::set_mode(const VideoMode &requested_mode, bool exclusive) diff --git a/source/graphics/x11/errordialog.cpp b/source/graphics/x11/errordialog.cpp new file mode 100644 index 0000000..59085b4 --- /dev/null +++ b/source/graphics/x11/errordialog.cpp @@ -0,0 +1,15 @@ +#include "errordialog.h" + +using namespace std; + +namespace Msp { +namespace Graphics { + +bool ErrorDialog::report_uncaught_exception(const exception &) const +{ + // TODO Implement a simple dialog with basic X11 primitives + return false; +} + +} // namespace Graphics +} // namespace Msp -- 2.45.2