Changed the handling for hardware-caused terminal signals:
* No longer send a SIGKILL when a page fault occurred, there was no signal handler, and the debugger told us to continue as usual. Instead we send a SIGSEGV. Instead in handle_signal() when not in the main thread and there's no handler for the signal, we first send the main thread a SIGKILL before letting the thread die. So in cases where the main thread caused an unhandled page fault, the team will die from the SIGSEGV, now. This fixes bug #2773. * For the other hardware-caused signals we do now do the same as in case of page faults, i.e. we first check whether the thread has a handler for the signal in question. If so, we don't notify the debugger, but send the signal right away. * B_GENERAL_PROTECTION_FAULT is translated to SIGILL now. Seems better than SIGKILL. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27757 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -756,7 +756,7 @@ unexpected_exception(struct iframe* frame)
|
|||||||
|
|
||||||
case 13: // General Protection Exception (#GP)
|
case 13: // General Protection Exception (#GP)
|
||||||
type = B_GENERAL_PROTECTION_FAULT;
|
type = B_GENERAL_PROTECTION_FAULT;
|
||||||
signal = SIGKILL;
|
signal = SIGILL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16: // x87 FPU Floating-Point Error (#MF)
|
case 16: // x87 FPU Floating-Point Error (#MF)
|
||||||
@@ -780,9 +780,18 @@ unexpected_exception(struct iframe* frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IFRAME_IS_USER(frame)) {
|
if (IFRAME_IS_USER(frame)) {
|
||||||
|
struct sigaction action;
|
||||||
|
struct thread* thread = thread_get_current_thread();
|
||||||
|
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
||||||
if (user_debug_exception_occurred(type, signal))
|
// If the thread has a signal handler for the signal, we simply send it
|
||||||
|
// the signal. Otherwise we notify the user debugger first.
|
||||||
|
if (sigaction(signal, NULL, &action) == 0
|
||||||
|
&& action.sa_handler != SIG_DFL
|
||||||
|
&& action.sa_handler != SIG_IGN) {
|
||||||
|
send_signal(thread->id, SIGSEGV);
|
||||||
|
} else if (user_debug_exception_occurred(type, signal))
|
||||||
send_signal(team_get_current_team_id(), signal);
|
send_signal(team_get_current_team_id(), signal);
|
||||||
} else {
|
} else {
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|||||||
@@ -383,12 +383,18 @@ handle_signals(struct thread *thread)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case SIGQUIT:
|
case SIGSEGV:
|
||||||
|
case SIGFPE:
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
case SIGTRAP:
|
case SIGTRAP:
|
||||||
|
// If this is the main thread, we just fall through and let
|
||||||
|
// this signal kill the team. Otherwise we send a SIGKILL to
|
||||||
|
// the main thread first, since the signal will kill this
|
||||||
|
// thread only.
|
||||||
|
if (thread != thread->team->main_thread)
|
||||||
|
send_signal(thread->team->main_thread->id, SIGKILL);
|
||||||
|
case SIGQUIT:
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
case SIGFPE:
|
|
||||||
case SIGSEGV:
|
|
||||||
case SIGPOLL:
|
case SIGPOLL:
|
||||||
case SIGPROF:
|
case SIGPROF:
|
||||||
case SIGSYS:
|
case SIGSYS:
|
||||||
|
|||||||
@@ -4288,9 +4288,9 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser,
|
|||||||
// TODO: the fault_callback is a temporary solution for vm86
|
// TODO: the fault_callback is a temporary solution for vm86
|
||||||
if (thread->fault_callback == NULL
|
if (thread->fault_callback == NULL
|
||||||
|| thread->fault_callback(address, faultAddress, isWrite)) {
|
|| thread->fault_callback(address, faultAddress, isWrite)) {
|
||||||
// If the thread has a signal handler for SIGSEGV we simply send
|
// If the thread has a signal handler for SIGSEGV, we simply
|
||||||
// it the signal. Otherwise we notify the user debugger. If
|
// send it the signal. Otherwise we notify the user debugger
|
||||||
// anything goes wrong, we kill the team.
|
// first.
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
if (sigaction(SIGSEGV, NULL, &action) == 0
|
if (sigaction(SIGSEGV, NULL, &action) == 0
|
||||||
&& action.sa_handler != SIG_DFL
|
&& action.sa_handler != SIG_DFL
|
||||||
@@ -4298,7 +4298,7 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser,
|
|||||||
send_signal(thread->id, SIGSEGV);
|
send_signal(thread->id, SIGSEGV);
|
||||||
} else if (user_debug_exception_occurred(B_SEGMENT_VIOLATION,
|
} else if (user_debug_exception_occurred(B_SEGMENT_VIOLATION,
|
||||||
SIGSEGV)) {
|
SIGSEGV)) {
|
||||||
send_signal(team_get_current_team_id(), SIGKILL);
|
send_signal(thread->id, SIGSEGV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user