Save errno in signal handlers

This commit is contained in:
Alexey Milovidov 2020-03-01 17:23:43 +03:00
parent db7d7a6104
commit 7c13b65e41
3 changed files with 16 additions and 0 deletions

View File

@ -88,10 +88,14 @@ using signal_function = void(int, siginfo_t*, void*);
static void writeSignalIDtoSignalPipe(int sig)
{
auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
char buf[buf_size];
DB::WriteBufferFromFileDescriptor out(signal_pipe.fds_rw[1], buf_size, buf);
DB::writeBinary(sig, out);
out.next();
errno = saved_errno;
}
/** Signal handler for HUP / USR1 */
@ -110,6 +114,8 @@ static void terminateRequestedSignalHandler(int sig, siginfo_t * info, void * co
*/
static void signalHandler(int sig, siginfo_t * info, void * context)
{
auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
char buf[buf_size];
DB::WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], buf_size, buf);
@ -134,6 +140,8 @@ static void signalHandler(int sig, siginfo_t * info, void * context)
::sleep(10);
call_default_signal_handler(sig);
}
errno = saved_errno;
}

View File

@ -21,6 +21,8 @@ namespace
{
void writeTraceInfo(TraceType trace_type, int /* sig */, siginfo_t * info, void * context)
{
auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
int overrun_count = 0;
#if defined(OS_LINUX)
if (info)
@ -33,6 +35,8 @@ namespace
const StackTrace stack_trace(signal_context);
ext::Singleton<TraceCollector>()->collect(trace_type, stack_trace, overrun_count);
errno = saved_errno;
}
[[maybe_unused]] const UInt32 TIMER_PRECISION = 1e9;

View File

@ -47,6 +47,8 @@ namespace
void signalHandler(int, siginfo_t * info, void * context)
{
auto saved_errno = errno; /// We must restore previous value of errno in signal handler.
/// In case malicious user is sending signals manually (for unknown reason).
/// If we don't check - it may break our synchronization.
if (info->si_pid != expected_pid)
@ -69,6 +71,8 @@ namespace
/// We cannot do anything if write failed.
(void)res;
errno = saved_errno;
}
/// Wait for data in pipe and read it.