* Check the thread debug signal ignore masks before notifying the debugger

of a signal.
* Added sigaction_etc(). It's just a sigaction() for which the thread
  in question can be specified.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11704 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2005-03-12 21:45:49 +00:00
parent 293a59b0e9
commit 20b656f066
2 changed files with 68 additions and 21 deletions
+3
View File
@@ -21,6 +21,9 @@ extern "C" {
extern int handle_signals(struct thread *t, cpu_status *state); extern int handle_signals(struct thread *t, cpu_status *state);
extern bool is_kill_signal_pending(void); extern bool is_kill_signal_pending(void);
extern int sigaction_etc(thread_id threadID, int signal,
const struct sigaction *act, struct sigaction *oact);
extern int _user_send_signal(pid_t tid, uint sig); extern int _user_send_signal(pid_t tid, uint sig);
extern int _user_sigprocmask(int how, const sigset_t *set, sigset_t *oldSet); extern int _user_sigprocmask(int how, const sigset_t *set, sigset_t *oldSet);
extern int _user_sigaction(int sig, const struct sigaction *action, struct sigaction *oldAction); extern int _user_sigaction(int sig, const struct sigaction *action, struct sigaction *oldAction);
+60 -16
View File
@@ -41,10 +41,23 @@ const char * const sigstr[NSIG] = {
static bool static bool
notify_debugger(int signal, struct sigaction *handler, bool deadly, notify_debugger(struct thread *thread, int signal, struct sigaction *handler,
cpu_status *state) bool deadly, cpu_status *state)
{ {
bool result; bool result;
uint64 signalMask = SIGNAL_TO_MASK(signal);
// first check the ignore signal masks the debugger specified for the thread
if (thread->debug_info.ignore_signals_once & signalMask) {
thread->debug_info.ignore_signals_once &= ~signalMask;
return true;
}
if (thread->debug_info.ignore_signals & signalMask)
return true;
// deliver the event
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(*state); restore_interrupts(*state);
@@ -108,7 +121,7 @@ handle_signals(struct thread *thread, cpu_status *state)
// notify the debugger // notify the debugger
if (debugSignal) if (debugSignal)
notify_debugger(sig, handler, false, state); notify_debugger(thread, sig, handler, false, state);
continue; continue;
} }
if (handler->sa_handler == SIG_DFL) { if (handler->sa_handler == SIG_DFL) {
@@ -121,16 +134,19 @@ handle_signals(struct thread *thread, cpu_status *state)
case SIGTTOU: case SIGTTOU:
case SIGCONT: case SIGCONT:
// notify the debugger // notify the debugger
if (debugSignal) if (debugSignal) {
notify_debugger(sig, handler, false, state); notify_debugger(thread, sig, handler, false, state);
}
continue; continue;
case SIGSTOP: case SIGSTOP:
// notify the debugger // notify the debugger
if (debugSignal) { if (debugSignal) {
if (!notify_debugger(sig, handler, false, state)) if (!notify_debugger(thread, sig, handler, false,
state)) {
continue; continue;
} }
}
thread->next_state = B_THREAD_SUSPENDED; thread->next_state = B_THREAD_SUSPENDED;
global_resched = 1; global_resched = 1;
@@ -152,9 +168,11 @@ handle_signals(struct thread *thread, cpu_status *state)
// notify the debugger // notify the debugger
if (debugSignal && sig != SIGKILL if (debugSignal && sig != SIGKILL
&& sig != SIGKILLTHR) { && sig != SIGKILLTHR) {
if (!notify_debugger(sig, handler, true, state)) if (!notify_debugger(thread, sig, handler, true,
state)) {
continue; continue;
} }
}
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(*state); restore_interrupts(*state);
@@ -173,7 +191,7 @@ handle_signals(struct thread *thread, cpu_status *state)
// notify the debugger // notify the debugger
if (debugSignal) { if (debugSignal) {
if (!notify_debugger(sig, handler, false, state)) if (!notify_debugger(thread, sig, handler, false, state))
continue; continue;
} }
@@ -413,11 +431,18 @@ sigprocmask(int how, const sigset_t *set, sigset_t *oldSet)
} }
/** \brief Similar to sigaction(), just for a specified thread.
*
* A \a threadID is < 0 specifies the current thread.
*
*/
int int
sigaction(int signal, const struct sigaction *act, struct sigaction *oact) sigaction_etc(thread_id threadID, int signal, const struct sigaction *act,
struct sigaction *oact)
{ {
struct thread *thread; struct thread *thread;
cpu_status state; cpu_status state;
status_t error = B_OK;
if (signal < 1 || signal > MAX_SIGNO if (signal < 1 || signal > MAX_SIGNO
|| signal == SIGKILL || signal == SIGKILLTHR || signal == SIGSTOP) || signal == SIGKILL || signal == SIGKILLTHR || signal == SIGSTOP)
@@ -426,25 +451,44 @@ sigaction(int signal, const struct sigaction *act, struct sigaction *oact)
state = disable_interrupts(); state = disable_interrupts();
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
thread = thread_get_current_thread(); thread = (threadID < 0
? thread_get_current_thread()
: thread_get_thread_struct_locked(threadID));
if (oact) if (thread) {
memcpy(oact, &thread->sig_action[signal - 1], sizeof(struct sigaction)); if (oact) {
if (act) memcpy(oact, &thread->sig_action[signal - 1],
memcpy(&thread->sig_action[signal - 1], act, sizeof(struct sigaction)); sizeof(struct sigaction));
}
if (act) {
memcpy(&thread->sig_action[signal - 1], act,
sizeof(struct sigaction));
}
if (act && act->sa_handler == SIG_IGN) if (act && act->sa_handler == SIG_IGN)
thread->sig_pending &= ~SIGNAL_TO_MASK(signal); thread->sig_pending &= ~SIGNAL_TO_MASK(signal);
else if (act && act->sa_handler == SIG_DFL) { else if (act && act->sa_handler == SIG_DFL) {
if (signal == SIGCONT || signal == SIGCHLD || signal == SIGWINCH) if (signal == SIGCONT || signal == SIGCHLD
|| signal == SIGWINCH) {
thread->sig_pending &= ~SIGNAL_TO_MASK(signal); thread->sig_pending &= ~SIGNAL_TO_MASK(signal);
}
} /*else } /*else
dprintf("### custom signal handler set\n");*/ dprintf("### custom signal handler set\n");*/
} else
error = B_BAD_THREAD_ID;
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
restore_interrupts(state); restore_interrupts(state);
return 0; return error;
}
int
sigaction(int signal, const struct sigaction *act, struct sigaction *oact)
{
return sigaction_etc(-1, signal, act, oact);
} }