Merge trunk r1438 to the chrome_43 branch.
Workaround Android sigaction bug On Android L+, signal and sigaction symbols are provided by libsigchain that override the system's versions. There is a bug in these functions where they essentially ignore requests to install SIG_DFL. Workaround this issue by explicitly performing a syscall to __NR_rt_sigaction to install SIG_DFL on Android. BUG=473973 Patch by Chris Hopman <cjhopman@chromium.org> Review URL: https://breakpad.appspot.com/1804002/ git-svn-id: http://google-breakpad.googlecode.com/svn/branches/chrome_43@1440 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
5b47d9d474
commit
7ac616335d
@ -188,6 +188,24 @@ void RestoreAlternateStackLocked() {
|
||||
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 sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
syscall(__NR_sigaction, sig, &sa, NULL);
|
||||
#else
|
||||
signal(sig, SIG_DFL);
|
||||
#endif
|
||||
}
|
||||
|
||||
// The global exception handler stack. This is needed because there may exist
|
||||
// multiple ExceptionHandler instances in a process. Each will have itself
|
||||
// registered in this stack.
|
||||
@ -283,7 +301,7 @@ void ExceptionHandler::RestoreHandlersLocked() {
|
||||
|
||||
for (int i = 0; i < kNumHandledSignals; ++i) {
|
||||
if (sigaction(kExceptionSignals[i], &old_handlers[i], NULL) == -1) {
|
||||
signal(kExceptionSignals[i], SIG_DFL);
|
||||
InstallDefaultHandler(kExceptionSignals[i]);
|
||||
}
|
||||
}
|
||||
handlers_installed = false;
|
||||
@ -323,7 +341,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
|
||||
if (sigaction(sig, &cur_handler, NULL) == -1) {
|
||||
// When resetting the handler fails, try to reset the
|
||||
// default one to avoid an infinite loop here.
|
||||
signal(sig, SIG_DFL);
|
||||
InstallDefaultHandler(sig);
|
||||
}
|
||||
pthread_mutex_unlock(&g_handler_stack_mutex_);
|
||||
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
|
||||
// be delivered to the appropriate handler.
|
||||
if (handled) {
|
||||
signal(sig, SIG_DFL);
|
||||
InstallDefaultHandler(sig);
|
||||
} else {
|
||||
RestoreHandlersLocked();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user