mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
libc: support to execute signal on separate stack
With the commit LibC signals will be executed on a separate stack and not anymore on the kernel or user stack. Fixes #5305
This commit is contained in:
parent
992b412be2
commit
0c5df0036c
@ -22,6 +22,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
/* libc-internal includes */
|
||||
#include <internal/call_func.h>
|
||||
#include <internal/types.h>
|
||||
|
||||
namespace Libc { struct Signal; }
|
||||
@ -60,6 +61,52 @@ struct Libc::Signal : Noncopyable
|
||||
|
||||
pid_t const _local_pid;
|
||||
|
||||
void * _signal_stack { };
|
||||
jmp_buf _signal_context { };
|
||||
|
||||
struct Signal_arguments
|
||||
{
|
||||
Signal & signal;
|
||||
Pending & pending;
|
||||
|
||||
Signal_arguments(Signal &signal, Pending &pending)
|
||||
: signal(signal), pending(pending) { }
|
||||
};
|
||||
|
||||
static void _signal_entry(Signal_arguments &arg)
|
||||
{
|
||||
arg.signal._execute_signal_handler(arg.pending.n);
|
||||
arg.signal._charged_signals[arg.pending.n].destruct();
|
||||
|
||||
_longjmp(arg.signal._signal_context, 1);
|
||||
}
|
||||
|
||||
void _execute_on_signal_stack(Pending &pending)
|
||||
{
|
||||
if (!_signal_stack) {
|
||||
auto myself = Thread::myself();
|
||||
if (myself)
|
||||
_signal_stack = { myself->alloc_secondary_stack("signal", 16 * 1024) };
|
||||
}
|
||||
|
||||
if (!_signal_stack) {
|
||||
error("signal stack allocation failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/* save continuation of current stack */
|
||||
if (!_setjmp(_signal_context)) {
|
||||
|
||||
Signal_arguments arg(*this, pending);
|
||||
|
||||
/* _setjmp() returned directly -> switch to signal stack */
|
||||
call_func(_signal_stack, (void *)_signal_entry, (void *)&arg);
|
||||
|
||||
/* never reached */
|
||||
}
|
||||
/* _setjmp() returned after _longjmp() */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Signal(pid_t local_pid) : _local_pid(local_pid) { }
|
||||
@ -87,8 +134,7 @@ struct Libc::Signal : Noncopyable
|
||||
_nesting_level++;
|
||||
|
||||
_pending_signals.for_each([&] (Pending &pending) {
|
||||
_execute_signal_handler(pending.n);
|
||||
_charged_signals[pending.n].destruct();
|
||||
_execute_on_signal_stack(pending);
|
||||
});
|
||||
|
||||
_nesting_level--;
|
||||
|
Loading…
Reference in New Issue
Block a user