From db27fb777a325039cf5c10b7bf40bcf5b605e9b8 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Mon, 10 Jan 2022 13:58:43 -0800 Subject: [PATCH] exceptions: make the exception handler stack per-thread. This prevents the weird failures I saw on macOS in #17856; instead, it should fail on *all* platforms with Unhandled exception ("epan/proto.c:8800: failed assertion "DISSECTOR_ASSERT_NOT_REACHED"", group=1, code=6) (which it does on macOS 11.6/Xcode 12.5.1 and Windows 10/VS 2019 16.11.8; according to https://en.wikipedia.org/w/index.php?title=Thread-local_storage&oldid=1064900318#C_and_C++ the major UN*X C compilers support __thread and the major Windows C compilers support __declspec(thread).). @jvalverde: on branches that require C11/C++11 support, we could perhaps just use _Thread_local for C and thread_local for C++. Note that is optional in C11, and macOS 11.6/Xcode 12.5.1 does not appear to include it.) This does not *fix* the aforementioned issue; to do *that* we need to do TRY in the register-dissectors thread code. I'm committing this separately because it fixes a bug in our exception package that could cause all sorts of randomness now and in the future - what we're doing now is Just Wrong. (Yes, there's code to support per-thread exception handler stacks *on platforms with pthreads*, but this is simpler *and* also works on Windows.) --- epan/except.c | 2 +- include/ws_attributes.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/epan/except.c b/epan/except.c index b37cbdb04b..a9bf83fb6a 100644 --- a/epan/except.c +++ b/epan/except.c @@ -143,7 +143,7 @@ static void (*uh_catcher_ptr)(except_t *) = unhandled_catcher; * the size_t issue doesn't exists here. Pheew.. */ static void *(*allocator)(size_t) = (void *(*)(size_t)) g_malloc; static void (*deallocator)(void *) = g_free; -static struct except_stacknode *stack_top; +static WS_THREAD_LOCAL struct except_stacknode *stack_top; #define get_top() (stack_top) #define set_top(T) (stack_top = (T)) diff --git a/include/ws_attributes.h b/include/ws_attributes.h index c1082d1530..f3ecf598f1 100644 --- a/include/ws_attributes.h +++ b/include/ws_attributes.h @@ -75,6 +75,23 @@ extern "C" { #define WS_RETNONNULL #endif +/* + * WS_THREAD_LOCAL means "this variable should go in thread-local + * storage. + * + * Based on + * + * https://en.wikipedia.org/w/index.php?title=Thread-local_storage&oldid=1064900318#C_and_C++ + * + * the major UN*X C compilers support __thread and the major Windows C + * compilers support __declspec(thread). + */ +#ifdef _WIN32 + #define WS_THREAD_LOCAL __declspec(thread) +#else + #define WS_THREAD_LOCAL __thread +#endif + #ifdef __cplusplus } #endif /* __cplusplus */