From 706bfea476a013bb8cf7566666699eb331876d7f Mon Sep 17 00:00:00 2001 From: Ilya Verbin <iverbin@tarantool.org> Date: Thu, 22 Dec 2022 17:10:33 +0300 Subject: [PATCH] core: unblock fatal (crashing) signals in all threads Currently all non-main threads have all the signals blocked, however according to `man pthread_sigmask': > If SIGBUS, SIGFPE, SIGILL, or SIGSEGV are generated while they > are blocked, the result is undefined, unless the signal was > generated by kill(2), sigqueue(3), or raise(3). On macOS they are actually blocked, causing the faulting instruction to loop indefinitely. While on Linux they are not blocked, however the signal handler registered by sigaction is not executed. Don't block them. Closes #8023 Closes #8083 NO_DOC=bugfix --- changelogs/unreleased/gh-8083-fatal-signal-handler.md | 5 +++++ src/lib/core/errinj.h | 1 + src/lib/core/fiber.c | 1 + src/tt_pthread.h | 10 ++++++++-- test/app-luatest/gh_8083_fatal_signal_handler_test.lua | 3 ++- test/box/errinj.result | 1 + 6 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 changelogs/unreleased/gh-8083-fatal-signal-handler.md diff --git a/changelogs/unreleased/gh-8083-fatal-signal-handler.md b/changelogs/unreleased/gh-8083-fatal-signal-handler.md new file mode 100644 index 0000000000..86fb63db63 --- /dev/null +++ b/changelogs/unreleased/gh-8083-fatal-signal-handler.md @@ -0,0 +1,5 @@ +## bugfix/core + +* Fixed Tarantool being stuck during a crash on macOS (gh-8023). + +* Fixed a bug that prevents crash report being collected (gh-8083). diff --git a/src/lib/core/errinj.h b/src/lib/core/errinj.h index 6861b9c5d6..6606f651d7 100644 --- a/src/lib/core/errinj.h +++ b/src/lib/core/errinj.h @@ -119,6 +119,7 @@ struct errinj { _(ERRINJ_REPLICASET_VCLOCK, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_REPLICA_JOIN_DELAY, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_SIGILL_MAIN_THREAD, ERRINJ_BOOL, {.bparam = false}) \ + _(ERRINJ_SIGILL_NONMAIN_THREAD, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_SIO_READ_MAX, ERRINJ_INT, {.iparam = -1}) \ _(ERRINJ_SNAP_COMMIT_DELAY, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_SNAP_COMMIT_FAIL, ERRINJ_BOOL, {.bparam = false}) \ diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c index 2a6dc541cb..2159d8048d 100644 --- a/src/lib/core/fiber.c +++ b/src/lib/core/fiber.c @@ -1732,6 +1732,7 @@ void *cord_thread_func(void *p) ct_arg->is_started = true; tt_pthread_cond_signal(&ct_arg->start_cond); tt_pthread_mutex_unlock(&ct_arg->start_mutex); + ERROR_INJECT_SIGILL(ERRINJ_SIGILL_NONMAIN_THREAD); void *res = f(arg); /* * cord()->on_exit initially holds NULL. This field is diff --git a/src/tt_pthread.h b/src/tt_pthread.h index 70f6050912..39c863a985 100644 --- a/src/tt_pthread.h +++ b/src/tt_pthread.h @@ -264,12 +264,18 @@ tt_pthread_error(e__); \ }) -/** Make sure the created thread blocks all signals, - * they are handled in the main thread. +/** + * Make sure the created thread blocks all signals, they are handled in the main + * thread. Except SIGILL, SIGBUS, SIGFPE and SIGSEGV, that cannot be blocked and + * are handled by the thread that triggered them (see crash_signal_init). */ #define tt_pthread_create(thread, attr, run, arg) \ ({ sigset_t set, oldset; \ sigfillset(&set); \ + sigdelset(&set, SIGILL); \ + sigdelset(&set, SIGBUS); \ + sigdelset(&set, SIGFPE); \ + sigdelset(&set, SIGSEGV); \ pthread_sigmask(SIG_BLOCK, &set, &oldset); \ int e__ = pthread_create(thread, attr, run, arg);\ pthread_sigmask(SIG_SETMASK, &oldset, NULL); \ diff --git a/test/app-luatest/gh_8083_fatal_signal_handler_test.lua b/test/app-luatest/gh_8083_fatal_signal_handler_test.lua index b7b2f0db18..8e401ea71d 100644 --- a/test/app-luatest/gh_8083_fatal_signal_handler_test.lua +++ b/test/app-luatest/gh_8083_fatal_signal_handler_test.lua @@ -1,5 +1,6 @@ local t = require('luatest') -local g = t.group('gh-8083', {{errinj = 'ERRINJ_SIGILL_MAIN_THREAD'}}) +local g = t.group('gh-8083', {{errinj = 'ERRINJ_SIGILL_MAIN_THREAD'}, + {errinj = 'ERRINJ_SIGILL_NONMAIN_THREAD'}}) g.before_each(function(cg) local server = require('luatest.server') diff --git a/test/box/errinj.result b/test/box/errinj.result index b4d7982f41..316462b751 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -94,6 +94,7 @@ evals - ERRINJ_REPLICASET_VCLOCK: false - ERRINJ_REPLICA_JOIN_DELAY: false - ERRINJ_SIGILL_MAIN_THREAD: false + - ERRINJ_SIGILL_NONMAIN_THREAD: false - ERRINJ_SIO_READ_MAX: -1 - ERRINJ_SNAP_COMMIT_DELAY: false - ERRINJ_SNAP_COMMIT_FAIL: false -- GitLab