Skip to content
Snippets Groups Projects
Commit 706bfea4 authored by Ilya Verbin's avatar Ilya Verbin Committed by Vladimir Davydov
Browse files

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
parent 6c3ce7a6
No related branches found
No related tags found
No related merge requests found
## bugfix/core
* Fixed Tarantool being stuck during a crash on macOS (gh-8023).
* Fixed a bug that prevents crash report being collected (gh-8083).
......@@ -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}) \
......
......@@ -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
......
......@@ -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); \
......
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')
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment