mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +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)
|
: _core_mem_alloc(nullptr)
|
||||||
{
|
{
|
||||||
/* catch control-c */
|
/* catch control-c */
|
||||||
lx_sigaction(LX_SIGINT, sigint_handler);
|
lx_sigaction(LX_SIGINT, sigint_handler, false);
|
||||||
|
|
||||||
/* catch SIGCHLD */
|
/* catch SIGCHLD */
|
||||||
lx_sigaction(LX_SIGCHLD, sigchld_handler);
|
lx_sigaction(LX_SIGCHLD, sigchld_handler, false);
|
||||||
|
|
||||||
/* create resource directory under /tmp */
|
/* create resource directory under /tmp */
|
||||||
lx_mkdir(resource_path(), S_IRWXU);
|
lx_mkdir(resource_path(), S_IRWXU);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/native_thread.h>
|
#include <base/internal/native_thread.h>
|
||||||
|
#include <base/internal/stack.h>
|
||||||
|
|
||||||
/* Linux syscall bindings */
|
/* Linux syscall bindings */
|
||||||
#include <linux_syscalls.h>
|
#include <linux_syscalls.h>
|
||||||
@ -26,17 +27,22 @@ using namespace Genode;
|
|||||||
|
|
||||||
static void empty_signal_handler(int) { }
|
static void empty_signal_handler(int) { }
|
||||||
|
|
||||||
static char signal_stack[0x2000] __attribute__((aligned(0x1000)));
|
|
||||||
|
|
||||||
void Thread::_thread_start()
|
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
|
* Set signal handler such that canceled system calls get not transparently
|
||||||
* retried after a signal gets received.
|
* 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
|
* 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,
|
* We reset the signal handler to SIG_DFL and trigger exception again,
|
||||||
* i.e., terminate the process.
|
* i.e., terminate the process.
|
||||||
*/
|
*/
|
||||||
lx_sigaction(signum, nullptr);
|
lx_sigaction(signum, nullptr, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lx_exception_signal_handlers()
|
void lx_exception_signal_handlers()
|
||||||
{
|
{
|
||||||
lx_sigaction(LX_SIGILL, exception_signal_handler);
|
/* use alternate stack in fatal-signal handlers */
|
||||||
lx_sigaction(LX_SIGBUS, exception_signal_handler);
|
lx_sigaction(LX_SIGILL, exception_signal_handler, true);
|
||||||
lx_sigaction(LX_SIGFPE, exception_signal_handler);
|
lx_sigaction(LX_SIGBUS, exception_signal_handler, true);
|
||||||
lx_sigaction(LX_SIGSEGV, exception_signal_handler);
|
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 void thread_exit_signal_handler(int) { lx_exit(0); }
|
||||||
|
|
||||||
|
|
||||||
static char signal_stack[0x2000] __attribute__((aligned(0x1000)));
|
|
||||||
|
|
||||||
void Thread::_thread_start()
|
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
|
* Set signal handler such that canceled system calls get not
|
||||||
* transparently retried after a signal gets received.
|
* transparently retried after a signal gets received.
|
||||||
*/
|
*/
|
||||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
lx_sigaction(LX_SIGUSR1, empty_signal_handler, false);
|
||||||
|
|
||||||
Thread * const thread = Thread::myself();
|
|
||||||
|
|
||||||
/* inform core about the new thread and process ID of the new thread */
|
/* inform core about the new thread and process ID of the new thread */
|
||||||
Linux_native_cpu_client native_cpu(thread->_cpu_session->native_cpu());
|
Linux_native_cpu_client native_cpu(thread->_cpu_session->native_cpu());
|
||||||
@ -141,7 +143,7 @@ void Thread::start()
|
|||||||
*/
|
*/
|
||||||
static bool threadlib_initialized = false;
|
static bool threadlib_initialized = false;
|
||||||
if (!threadlib_initialized) {
|
if (!threadlib_initialized) {
|
||||||
lx_sigaction(LX_SIGCANCEL, thread_exit_signal_handler);
|
lx_sigaction(LX_SIGCANCEL, thread_exit_signal_handler, false);
|
||||||
threadlib_initialized = true;
|
threadlib_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ __attribute__((constructor(101))) void lx_hybrid_init()
|
|||||||
* Set signal handler such that canceled system calls get not
|
* Set signal handler such that canceled system calls get not
|
||||||
* transparently retried after a signal gets received.
|
* transparently retried after a signal gets received.
|
||||||
*/
|
*/
|
||||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
lx_sigaction(LX_SIGUSR1, empty_signal_handler, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Genode {
|
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
|
* Set signal handler such that canceled system calls get not
|
||||||
* transparently retried after a signal gets received.
|
* 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)
|
* 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 */
|
/* assign 'Native_thread::Meta_data' pointer to TLS entry */
|
||||||
pthread_setspecific(tls_key(), meta_data);
|
pthread_setspecific(tls_key(), meta_data);
|
||||||
|
@ -245,7 +245,7 @@ extern "C" void lx_restore_rt (void);
|
|||||||
/**
|
/**
|
||||||
* Simplified binding for sigaction system call
|
* 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;
|
struct kernel_sigaction act;
|
||||||
act.handler = handler;
|
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.
|
* when leaving the signal handler and it should call the rt_sigreturn syscall.
|
||||||
*/
|
*/
|
||||||
enum { SA_RESTORER = 0x04000000 };
|
enum { SA_RESTORER = 0x04000000 };
|
||||||
act.flags = SA_RESTORER | SA_ONSTACK;
|
act.flags = SA_RESTORER;
|
||||||
act.restorer = lx_restore_rt;
|
act.restorer = lx_restore_rt;
|
||||||
#else
|
#else
|
||||||
act.flags = SA_ONSTACK;
|
act.flags = 0;
|
||||||
act.restorer = 0;
|
act.restorer = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* use alternate signal stack if requested */
|
||||||
|
act.flags |= altstack ? SA_ONSTACK : 0;
|
||||||
|
|
||||||
lx_sigemptyset(&act.mask);
|
lx_sigemptyset(&act.mask);
|
||||||
|
|
||||||
return lx_syscall(SYS_rt_sigaction, signum, &act, 0UL, _NSIG/8);
|
return lx_syscall(SYS_rt_sigaction, signum, &act, 0UL, _NSIG/8);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user