Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80fd81452d | ||
|
|
1ff31641a5 | ||
|
|
21d9c3f9b9 | ||
|
|
959c06153a |
@@ -188,6 +188,24 @@ void RestoreAlternateStackLocked() {
|
|||||||
stack_installed = false;
|
stack_installed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InstallDefaultHandler(int sig) {
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
// Android L+ expose signal and sigaction symbols that override the system
|
||||||
|
// ones. There is a bug in these functions where a request to set the handler
|
||||||
|
// to SIG_DFL is ignored. In that case, an infinite loop is entered as the
|
||||||
|
// signal is repeatedly sent to breakpad's signal handler.
|
||||||
|
// To work around this, directly call the system's sigaction.
|
||||||
|
struct kernel_sigaction sa;
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sys_sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_handler_ = SIG_DFL;
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
sys_rt_sigaction(sig, &sa, NULL, sizeof(kernel_sigset_t));
|
||||||
|
#else
|
||||||
|
signal(sig, SIG_DFL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// The global exception handler stack. This is needed because there may exist
|
// The global exception handler stack. This is needed because there may exist
|
||||||
// multiple ExceptionHandler instances in a process. Each will have itself
|
// multiple ExceptionHandler instances in a process. Each will have itself
|
||||||
// registered in this stack.
|
// registered in this stack.
|
||||||
@@ -283,7 +301,7 @@ void ExceptionHandler::RestoreHandlersLocked() {
|
|||||||
|
|
||||||
for (int i = 0; i < kNumHandledSignals; ++i) {
|
for (int i = 0; i < kNumHandledSignals; ++i) {
|
||||||
if (sigaction(kExceptionSignals[i], &old_handlers[i], NULL) == -1) {
|
if (sigaction(kExceptionSignals[i], &old_handlers[i], NULL) == -1) {
|
||||||
signal(kExceptionSignals[i], SIG_DFL);
|
InstallDefaultHandler(kExceptionSignals[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handlers_installed = false;
|
handlers_installed = false;
|
||||||
@@ -323,7 +341,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
|
|||||||
if (sigaction(sig, &cur_handler, NULL) == -1) {
|
if (sigaction(sig, &cur_handler, NULL) == -1) {
|
||||||
// When resetting the handler fails, try to reset the
|
// When resetting the handler fails, try to reset the
|
||||||
// default one to avoid an infinite loop here.
|
// default one to avoid an infinite loop here.
|
||||||
signal(sig, SIG_DFL);
|
InstallDefaultHandler(sig);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&g_handler_stack_mutex_);
|
pthread_mutex_unlock(&g_handler_stack_mutex_);
|
||||||
return;
|
return;
|
||||||
@@ -340,7 +358,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
|
|||||||
// previously installed handler. Then, when the signal is retriggered, it will
|
// previously installed handler. Then, when the signal is retriggered, it will
|
||||||
// be delivered to the appropriate handler.
|
// be delivered to the appropriate handler.
|
||||||
if (handled) {
|
if (handled) {
|
||||||
signal(sig, SIG_DFL);
|
InstallDefaultHandler(sig);
|
||||||
} else {
|
} else {
|
||||||
RestoreHandlersLocked();
|
RestoreHandlersLocked();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user