mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
linux: place alternate signal stack in stack area
The alternate stack must use the stack area as, e.g., Thread::myself() depends on this property. Hybrid components do not depend on this property and, therefore, use a static stack buffer. Fixes #1935
This commit is contained in:
parent
d8c34237bf
commit
d7ddc83fa9
@ -90,10 +90,10 @@ Platform::Platform()
|
||||
: _core_mem_alloc(nullptr)
|
||||
{
|
||||
/* catch control-c */
|
||||
lx_sigaction(LX_SIGINT, sigint_handler);
|
||||
lx_sigaction(LX_SIGINT, sigint_handler, false);
|
||||
|
||||
/* catch SIGCHLD */
|
||||
lx_sigaction(LX_SIGCHLD, sigchld_handler);
|
||||
lx_sigaction(LX_SIGCHLD, sigchld_handler, false);
|
||||
|
||||
/* create resource directory under /tmp */
|
||||
lx_mkdir(resource_path(), S_IRWXU);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
#include <base/internal/stack.h>
|
||||
|
||||
/* Linux syscall bindings */
|
||||
#include <linux_syscalls.h>
|
||||
@ -26,17 +27,22 @@ using namespace Genode;
|
||||
|
||||
static void empty_signal_handler(int) { }
|
||||
|
||||
static char signal_stack[0x2000] __attribute__((aligned(0x1000)));
|
||||
|
||||
void Thread::_thread_start()
|
||||
{
|
||||
lx_sigaltstack(signal_stack, sizeof(signal_stack));
|
||||
Thread * const thread = Thread::myself();
|
||||
|
||||
/* use primary stack as alternate stack for fatal signals (exceptions) */
|
||||
void *stack_base = (void *)thread->_stack->base();
|
||||
size_t stack_size = thread->_stack->top() - thread->_stack->base();
|
||||
|
||||
lx_sigaltstack(stack_base, stack_size);
|
||||
|
||||
/*
|
||||
* Set signal handler such that canceled system calls get not transparently
|
||||
* retried after a signal gets received.
|
||||
*/
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler, false);
|
||||
|
||||
/*
|
||||
* Deliver SIGCHLD signals to no thread other than the main thread. Core's
|
||||
|
@ -78,17 +78,18 @@ void exception_signal_handler(int signum)
|
||||
* We reset the signal handler to SIG_DFL and trigger exception again,
|
||||
* i.e., terminate the process.
|
||||
*/
|
||||
lx_sigaction(signum, nullptr);
|
||||
lx_sigaction(signum, nullptr, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void lx_exception_signal_handlers()
|
||||
{
|
||||
lx_sigaction(LX_SIGILL, exception_signal_handler);
|
||||
lx_sigaction(LX_SIGBUS, exception_signal_handler);
|
||||
lx_sigaction(LX_SIGFPE, exception_signal_handler);
|
||||
lx_sigaction(LX_SIGSEGV, exception_signal_handler);
|
||||
/* use alternate stack in fatal-signal handlers */
|
||||
lx_sigaction(LX_SIGILL, exception_signal_handler, true);
|
||||
lx_sigaction(LX_SIGBUS, exception_signal_handler, true);
|
||||
lx_sigaction(LX_SIGFPE, exception_signal_handler, true);
|
||||
lx_sigaction(LX_SIGSEGV, exception_signal_handler, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,19 +46,21 @@ static Lock &startup_lock()
|
||||
static void thread_exit_signal_handler(int) { lx_exit(0); }
|
||||
|
||||
|
||||
static char signal_stack[0x2000] __attribute__((aligned(0x1000)));
|
||||
|
||||
void Thread::_thread_start()
|
||||
{
|
||||
lx_sigaltstack(signal_stack, sizeof(signal_stack));
|
||||
Thread * const thread = Thread::myself();
|
||||
|
||||
/* use primary stack as alternate stack for fatal signals (exceptions) */
|
||||
void *stack_base = (void *)thread->_stack->base();
|
||||
size_t stack_size = thread->_stack->top() - thread->_stack->base();
|
||||
|
||||
lx_sigaltstack(stack_base, stack_size);
|
||||
|
||||
/*
|
||||
* Set signal handler such that canceled system calls get not
|
||||
* transparently retried after a signal gets received.
|
||||
*/
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||
|
||||
Thread * const thread = Thread::myself();
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler, false);
|
||||
|
||||
/* inform core about the new thread and process ID of the new thread */
|
||||
Linux_native_cpu_client native_cpu(thread->_cpu_session->native_cpu());
|
||||
@ -141,7 +143,7 @@ void Thread::start()
|
||||
*/
|
||||
static bool threadlib_initialized = false;
|
||||
if (!threadlib_initialized) {
|
||||
lx_sigaction(LX_SIGCANCEL, thread_exit_signal_handler);
|
||||
lx_sigaction(LX_SIGCANCEL, thread_exit_signal_handler, false);
|
||||
threadlib_initialized = true;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ __attribute__((constructor(101))) void lx_hybrid_init()
|
||||
* Set signal handler such that canceled system calls get not
|
||||
* transparently retried after a signal gets received.
|
||||
*/
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler, false);
|
||||
}
|
||||
|
||||
namespace Genode {
|
||||
@ -345,12 +345,12 @@ static void adopt_thread(Native_thread::Meta_data *meta_data)
|
||||
* Set signal handler such that canceled system calls get not
|
||||
* transparently retried after a signal gets received.
|
||||
*/
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler, false);
|
||||
|
||||
/*
|
||||
* Prevent children from becoming zombies. (SIG_IGN = 1)
|
||||
*/
|
||||
lx_sigaction(LX_SIGCHLD, (void (*)(int))1);
|
||||
lx_sigaction(LX_SIGCHLD, (void (*)(int))1, false);
|
||||
|
||||
/* assign 'Native_thread::Meta_data' pointer to TLS entry */
|
||||
pthread_setspecific(tls_key(), meta_data);
|
||||
|
@ -245,7 +245,7 @@ extern "C" void lx_restore_rt (void);
|
||||
/**
|
||||
* Simplified binding for sigaction system call
|
||||
*/
|
||||
inline int lx_sigaction(int signum, void (*handler)(int))
|
||||
inline int lx_sigaction(int signum, void (*handler)(int), bool altstack)
|
||||
{
|
||||
struct kernel_sigaction act;
|
||||
act.handler = handler;
|
||||
@ -258,12 +258,16 @@ inline int lx_sigaction(int signum, void (*handler)(int))
|
||||
* when leaving the signal handler and it should call the rt_sigreturn syscall.
|
||||
*/
|
||||
enum { SA_RESTORER = 0x04000000 };
|
||||
act.flags = SA_RESTORER | SA_ONSTACK;
|
||||
act.flags = SA_RESTORER;
|
||||
act.restorer = lx_restore_rt;
|
||||
#else
|
||||
act.flags = SA_ONSTACK;
|
||||
act.flags = 0;
|
||||
act.restorer = 0;
|
||||
#endif
|
||||
|
||||
/* use alternate signal stack if requested */
|
||||
act.flags |= altstack ? SA_ONSTACK : 0;
|
||||
|
||||
lx_sigemptyset(&act.mask);
|
||||
|
||||
return lx_syscall(SYS_rt_sigaction, signum, &act, 0UL, _NSIG/8);
|
||||
|
Loading…
x
Reference in New Issue
Block a user