Compare commits
5 Commits
master-lar
...
chrome_43
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c86860f5e2 | ||
![]() |
ef04c53283 | ||
![]() |
897c1bb4d6 | ||
![]() |
7ac616335d | ||
![]() |
5b47d9d474 |
@@ -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,14 +358,15 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&g_handler_stack_mutex_);
|
pthread_mutex_unlock(&g_handler_stack_mutex_);
|
||||||
|
|
||||||
if (info->si_pid || sig == SIGABRT) {
|
// info->si_code <= 0 iff SI_FROMUSER (SI_FROMKERNEL otherwise).
|
||||||
|
if (info->si_code <= 0 || sig == SIGABRT) {
|
||||||
// This signal was triggered by somebody sending us the signal with kill().
|
// This signal was triggered by somebody sending us the signal with kill().
|
||||||
// In order to retrigger it, we have to queue a new signal by calling
|
// In order to retrigger it, we have to queue a new signal by calling
|
||||||
// kill() ourselves. The special case (si_pid == 0 && sig == SIGABRT) is
|
// kill() ourselves. The special case (si_pid == 0 && sig == SIGABRT) is
|
||||||
|
Reference in New Issue
Block a user