summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2021-01-20 16:38:00 -0500
committerGlenn Smith <glenn@vector35.com>2021-06-24 17:34:58 -0400
commit4783514ff534bb8d10ea74d30b00a49ece06d89a (patch)
tree134b546cd052190e6d864f60dc88f2efd67a4b8f
parent7f488c8f3221d268e2dfd51ae559a531ad9e66ea (diff)
Catch main thread callback errors #2239
-rw-r--r--mainthread.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/mainthread.cpp b/mainthread.cpp
index 59d67c12..dd503cae 100644
--- a/mainthread.cpp
+++ b/mainthread.cpp
@@ -7,6 +7,7 @@ using namespace std;
struct MainThreadActionContext
{
function<void()> action;
+ exception_ptr exception;
};
@@ -53,7 +54,26 @@ void BinaryNinja::RegisterMainThread(MainThreadActionHandler* handler)
static void ExecuteAction(void* ctxt)
{
MainThreadActionContext* action = (MainThreadActionContext*)ctxt;
- action->action();
+
+ // We can't throw across a thread and *certainly* not across the api boundary
+ // But how do we deal with exceptions thrown in main thread callbacks if the caller doesn't wait for them?
+ // Likely the only good solution is abort()
+ try
+ {
+ action->action();
+ }
+ catch (const std::exception& e)
+ {
+ LogError("Exception in main thread handler: %s", e.what());
+ fprintf(stderr, "Exception in main thread handler: %s\n", e.what());
+ abort();
+ }
+ catch (...)
+ {
+ LogError("Exception in main thread handler: <unknown exception>");
+ fprintf(stderr, "Exception in main thread handler: <unknown exception>\n");
+ abort();
+ }
delete action;
}
@@ -70,7 +90,14 @@ Ref<MainThreadAction> BinaryNinja::ExecuteOnMainThread(const function<void()>& a
static void ExecuteActionLocal(void* ctxt)
{
MainThreadActionContext* action = (MainThreadActionContext*)ctxt;
- action->action();
+ try
+ {
+ action->action();
+ }
+ catch (...)
+ {
+ action->exception = current_exception();
+ }
}
@@ -78,7 +105,12 @@ void BinaryNinja::ExecuteOnMainThreadAndWait(const function<void()>& action)
{
MainThreadActionContext ctxt;
ctxt.action = action;
+ ctxt.exception = exception_ptr();
BNExecuteOnMainThreadAndWait(&ctxt, ExecuteActionLocal);
+ if (ctxt.exception)
+ {
+ rethrow_exception(ctxt.exception);
+ }
}