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 0000000000000000000000000000000000000000..86fb63db638b2b379cecb1d89a5f8e00dbe50e19 --- /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 6861b9c5d6ca636a51efe1af8011f5390d25aedf..6606f651d7b5fc5bad14578694e235ec0fb9af7f 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 2a6dc541cb30bdab0c4ea7dcc3b40b8cfbc52bc8..2159d8048d8b35fab083d8691917a45e5484b0f0 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 70f6050912010bcaf0da5ce27a1ea6093dbc9762..39c863a985bd65a2320ba29b7a49d44476e9be9c 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 b7b2f0db189fe35c2a24bffac0f7852ac179ad3c..8e401ea71d9cf6f68882fda317d50a79662ee2c0 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 b4d7982f413bdc5808df1de4626ef0fecdaf8f54..316462b75189f58f84ca4fdf256d99ebaeaea868 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