mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
Kernel: Fill some siginfo and ucontext fields on SA_SIGINFO
There's no reason to fill in any of these fields if SA_SIGINFO is not given, as the signal handler won't be reading from them at all.
This commit is contained in:
parent
4bd01b7fe9
commit
e14e919b78
Notes:
sideshowbarker
2024-07-17 17:57:10 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/e14e919b78 Pull-request: https://github.com/SerenityOS/serenity/pull/12762
@ -54,6 +54,7 @@ typedef struct __ucontext {
|
||||
#define SI_TIMER 0x40000002
|
||||
#define SI_ASYNCIO 0x40000003
|
||||
#define SI_MESGQ 0x40000004
|
||||
#define SI_NOINFO 0x40000042
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -451,6 +451,7 @@ public:
|
||||
ErrorOr<void> send_signal(u8 signal, Process* sender);
|
||||
|
||||
u8 termination_signal() const { return m_protected_values.termination_signal; }
|
||||
u8 termination_status() const { return m_protected_values.termination_status; }
|
||||
|
||||
u16 thread_count() const
|
||||
{
|
||||
|
@ -738,6 +738,7 @@ void Thread::send_signal(u8 signal, [[maybe_unused]] Process* sender)
|
||||
}
|
||||
|
||||
m_pending_signals |= 1 << (signal - 1);
|
||||
m_signal_senders[signal] = sender ? sender->pid() : pid();
|
||||
m_have_any_unmasked_pending_signals.store((pending_signals_for_state() & ~m_signal_mask) != 0, AK::memory_order_release);
|
||||
m_signal_blocker_set.unblock_all_blockers_whose_conditions_are_met();
|
||||
|
||||
@ -983,6 +984,8 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
|
||||
}
|
||||
|
||||
auto& action = m_process->m_signal_action_data[signal];
|
||||
auto sender_pid = m_signal_senders[signal];
|
||||
auto sender = Process::from_pid(sender_pid);
|
||||
|
||||
if (!current_trap() && !action.handler_or_sigaction.is_null()) {
|
||||
// We're trying dispatch a handled signal to a user process that was scheduled
|
||||
@ -1074,30 +1077,85 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
|
||||
.uc_link = nullptr,
|
||||
.uc_sigmask = old_signal_mask,
|
||||
.uc_stack = {
|
||||
.ss_sp = nullptr,
|
||||
.ss_flags = 0,
|
||||
.ss_size = 0,
|
||||
.ss_sp = bit_cast<void*>(stack),
|
||||
.ss_flags = action.flags & SA_ONSTACK,
|
||||
.ss_size = use_alternative_stack ? m_alternative_signal_stack_size : 0,
|
||||
},
|
||||
.uc_mcontext = {},
|
||||
};
|
||||
copy_kernel_registers_into_ptrace_registers(static_cast<PtraceRegisters&>(ucontext.uc_mcontext), state);
|
||||
|
||||
auto fill_signal_info_for_signal = [&](siginfo& signal_info) {
|
||||
if (signal == SIGCHLD) {
|
||||
if (!sender) {
|
||||
signal_info.si_code = CLD_EXITED;
|
||||
return;
|
||||
}
|
||||
auto const* thread = sender->thread_list().with([](auto& list) { return list.is_empty() ? nullptr : list.first(); });
|
||||
if (!thread) {
|
||||
signal_info.si_code = CLD_EXITED;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (thread->m_state) {
|
||||
case State::Dead:
|
||||
if (sender->should_generate_coredump() && sender->is_dumpable()) {
|
||||
signal_info.si_code = CLD_DUMPED;
|
||||
signal_info.si_status = sender->termination_signal();
|
||||
return;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case State::Dying:
|
||||
if (sender->termination_signal() == 0) {
|
||||
signal_info.si_code = CLD_EXITED;
|
||||
signal_info.si_status = sender->termination_status();
|
||||
return;
|
||||
}
|
||||
signal_info.si_code = CLD_KILLED;
|
||||
signal_info.si_status = sender->termination_signal();
|
||||
return;
|
||||
case State::Runnable:
|
||||
case State::Running:
|
||||
case State::Blocked:
|
||||
signal_info.si_code = CLD_CONTINUED;
|
||||
return;
|
||||
case State::Stopped:
|
||||
signal_info.si_code = CLD_STOPPED;
|
||||
return;
|
||||
case State::Invalid:
|
||||
// Something is wrong, but we're just an observer.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
signal_info.si_code = SI_NOINFO;
|
||||
};
|
||||
|
||||
siginfo signal_info {
|
||||
.si_signo = signal,
|
||||
.si_code = 0, // FIXME: Signal-specific value, fill this in.
|
||||
// Filled in below by fill_signal_info_for_signal.
|
||||
.si_code = 0,
|
||||
// Set for SI_TIMER, we don't have the data here.
|
||||
.si_errno = 0,
|
||||
// FIXME: Plumb sender information here.
|
||||
.si_pid = 0,
|
||||
.si_uid = 0,
|
||||
// FIXME: Fill these in.
|
||||
.si_pid = sender_pid.value(),
|
||||
.si_uid = sender ? sender->uid().value() : 0,
|
||||
// Set for SIGILL, SIGFPE, SIGSEGV and SIGBUS
|
||||
// FIXME: We don't generate these signals in a way that can be handled.
|
||||
.si_addr = 0,
|
||||
// Set for SIGCHLD.
|
||||
.si_status = 0,
|
||||
// Set for SIGPOLL, we don't have SIGPOLL.
|
||||
.si_band = 0,
|
||||
// Set for SI_QUEUE, SI_TIMER, SI_ASYNCIO and SI_MESGQ
|
||||
// We do not generate any of these.
|
||||
.si_value = {
|
||||
.sival_int = 0,
|
||||
},
|
||||
};
|
||||
|
||||
if (action.flags & SA_SIGINFO)
|
||||
fill_signal_info_for_signal(signal_info);
|
||||
|
||||
#if ARCH(I386)
|
||||
constexpr static FlatPtr thread_red_zone_size = 0;
|
||||
#elif ARCH(X86_64)
|
||||
|
@ -1220,6 +1220,7 @@ private:
|
||||
VirtualAddress m_thread_specific_data;
|
||||
Optional<Memory::VirtualRange> m_thread_specific_range;
|
||||
Array<Optional<u32>, NSIG> m_signal_action_masks;
|
||||
Array<ProcessID, NSIG> m_signal_senders;
|
||||
Blocker* m_blocker { nullptr };
|
||||
Kernel::Mutex* m_blocking_mutex { nullptr };
|
||||
u32 m_lock_requested_count { 0 };
|
||||
|
Loading…
Reference in New Issue
Block a user