Skip to content

Commit ca00363

Browse files
author
Grant Karapetyan
authored
Update windows SEH handlers in other threads (#580)
* Update windows SEH handlers in other threads * Fix build
1 parent 5cc25ef commit ca00363

File tree

5 files changed

+66
-9
lines changed

5 files changed

+66
-9
lines changed

source/MRMesh/MRLog.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ void removeOldLogs( const std::filesystem::path& dir, int hours = 24 )
5353
}
5454

5555
#ifndef __EMSCRIPTEN__
56+
#ifdef _WIN32
57+
class SignalObserver : public tbb::task_scheduler_observer {
58+
public:
59+
SignalObserver( std::function<void()> func )
60+
: task_scheduler_observer(),
61+
func_{ func }
62+
{
63+
observe( true ); // activate the observer
64+
}
65+
void on_scheduler_entry( bool ) override
66+
{
67+
func_();
68+
}
69+
private:
70+
std::function<void()> func_;
71+
};
72+
#endif
73+
5674
void crashSignalHandler( int signal )
5775
{
5876
spdlog::critical( "Crash signal: {}", signal );
@@ -134,8 +152,14 @@ Logger::Logger()
134152

135153
void setupLoggerByDefault()
136154
{
155+
#ifdef NDEBUG
137156
#ifndef __EMSCRIPTEN__
138157
printStacktraceOnCrash();
158+
#ifdef _WIN32
159+
// observe tbb threads creation and add signals handlers for them
160+
static SignalObserver tbbObserver( [] () { printStacktraceOnCrash(); } );
161+
#endif
162+
#endif
139163
#endif
140164
redirectSTDStreamsToLogger();
141165
// write log to console

source/MRPch/MRTBB.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <tbb/task_arena.h>
2323
#include <tbb/task_group.h>
2424
#include <tbb/global_control.h>
25+
#include <tbb/task_scheduler_observer.h>
2526
#pragma warning(pop)
2627

2728
#ifdef __EMSCRIPTEN__

source/MRViewer/MRProgressBar.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#include "MRPch/MRWasm.h"
88
#include <GLFW/glfw3.h>
99

10+
#ifdef _WIN32
11+
#include <excpt.h>
12+
#endif
13+
1014
#if defined( __EMSCRIPTEN__ ) && !defined( __EMSCRIPTEN_PTHREADS__ )
1115
namespace
1216
{
@@ -119,6 +123,7 @@ void ProgressBar::orderWithMainThreadPostProcessing( const char* name, TaskWithM
119123

120124
instance.progress_ = 0.0f;
121125

126+
instance.task_ = task;
122127
instance.currentTask_ = 0;
123128
if ( taskCount == 1 )
124129
instance.currentTask_ = 1;
@@ -132,15 +137,15 @@ void ProgressBar::orderWithMainThreadPostProcessing( const char* name, TaskWithM
132137
ImGui::OpenPopup( instance.setupId_ );
133138
instance.lastPostEvent_ = std::chrono::system_clock::now();
134139
#if !defined( __EMSCRIPTEN__ ) || defined( __EMSCRIPTEN_PTHREADS__ )
135-
instance.thread_ = std::thread( [task, &instance] ()
140+
instance.thread_ = std::thread( [&instance] ()
136141
{
137142
SetCurrentThreadName( "ProgressBar" );
138-
instance.tryRunTask_( task );
143+
instance.tryRunTaskWithSehHandler_();
139144
} );
140145
#else
141-
staticTaskForLaterCall = [&instance, task] ()
146+
staticTaskForLaterCall = [&instance] ()
142147
{
143-
instance.tryRunTask_( task );
148+
instance.tryRunTaskWithSehHandler_();
144149
};
145150
emscripten_async_call( asyncCallTask, nullptr, 200 );
146151
#endif
@@ -249,11 +254,14 @@ ProgressBar::~ProgressBar()
249254
thread_.join();
250255
}
251256

252-
void ProgressBar::tryRunTask_( TaskWithMainThreadPostProcessing task )
257+
void ProgressBar::tryRunTask_()
253258
{
259+
#ifndef NDEBUG
260+
onFinish_ = task_();
261+
#else
254262
try
255263
{
256-
onFinish_ = task();
264+
onFinish_ = task_();
257265
}
258266
catch ( const std::bad_alloc& badAllocE )
259267
{
@@ -273,6 +281,28 @@ void ProgressBar::tryRunTask_( TaskWithMainThreadPostProcessing task )
273281
menu->showErrorModal( msg );
274282
};
275283
}
284+
#endif
285+
}
286+
287+
void ProgressBar::tryRunTaskWithSehHandler_()
288+
{
289+
#if !defined(_WIN32) || !defined(NDEBUG)
290+
tryRunTask_();
291+
#else
292+
__try
293+
{
294+
tryRunTask_();
295+
}
296+
__except ( EXCEPTION_EXECUTE_HANDLER )
297+
{
298+
onFinish_ = []()
299+
{
300+
spdlog::error( "Unknown exception occurred" );
301+
if ( auto menu = getViewerInstance().getMenuPlugin() )
302+
menu->showErrorModal( "Unknown exception occurred" );
303+
};
304+
}
305+
#endif
276306
finish_();
277307
}
278308

source/MRViewer/MRProgressBar.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ class ProgressBar
5050
ProgressBar();
5151
~ProgressBar();
5252

53-
// cover task execution with try catch block
53+
// cover task execution with try catch block (in release only)
5454
// if catches exception shows error in main thread overriding user defined main thread post processing
55-
void tryRunTask_( TaskWithMainThreadPostProcessing task );
55+
void tryRunTask_();
56+
void tryRunTaskWithSehHandler_();
5657

5758
void postEvent_();
5859
void finish_();
@@ -63,6 +64,7 @@ class ProgressBar
6364
std::chrono::time_point<std::chrono::system_clock> lastPostEvent_;
6465

6566
std::thread thread_;
67+
TaskWithMainThreadPostProcessing task_;
6668
std::function<void()> onFinish_;
6769

6870
// needed to be able to call progress bar from any point, not only from ImGui frame scope

source/MRViewer/MRViewer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ int launchDefaultViewer( const Viewer::LaunchParams& params, const ViewerSetup&
224224
setup.setupSettingsManager( &viewer, params.name );
225225
setup.setupConfiguration( &viewer );
226226
setup.setupExtendedLibraries();
227-
#ifdef __EMSCRIPTEN__
227+
#if defined(__EMSCRIPTEN__) || !defined(NDEBUG)
228228
return viewer.launch( params );
229229
#else
230230
int res = 0;

0 commit comments

Comments
 (0)