genode/repos/base-linux/src/core/thread_linux.cc
Christian Helmuth 14f1ac497e linux: improve exception-signal handling
First, we use an alternate stack for signal handling now. The stack is
shared among all threads of the component, which is okay as we only
handle exceptions with log output and pass on to the default handler
(that terminates the execution). The primary motivation for the
alternate stack is the detection of SIGSEGV due to stack overflows.

Also, hybrid components now handle exception signals by logging and the
support for multi-threaded applications was improved.

Fixes #1935
2016-04-11 11:53:00 +02:00

69 lines
1.6 KiB
C++

/*
* \brief Implementation of the core-internal Thread API via Linux threads
* \author Norman Feske
* \date 2006-06-13
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Linux syscall bindings */
#include <linux_syscalls.h>
using namespace Genode;
static void empty_signal_handler(int) { }
static char signal_stack[0x2000] __attribute__((aligned(0x1000)));
void Thread_base::_thread_start()
{
lx_sigaltstack(signal_stack, sizeof(signal_stack));
/*
* Set signal handler such that canceled system calls get not transparently
* retried after a signal gets received.
*/
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
/*
* Deliver SIGCHLD signals to no thread other than the main thread. Core's
* main thread will handle the signals while executing the 'wait_for_exit'
* function, which is known to not hold any locks that would interfere with
* the handling of the signal.
*/
lx_sigsetmask(LX_SIGCHLD, false);
Thread_base::myself()->entry();
Thread_base::myself()->_join_lock.unlock();
sleep_forever();
}
void Thread_base::_init_platform_thread(size_t, Type) { }
void Thread_base::_deinit_platform_thread() { }
void Thread_base::start()
{
native_thread().tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
native_thread().pid = lx_getpid();
}
void Thread_base::cancel_blocking() { }