mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2025-12-22 05:36:26 +01:00
Make Linux signal handler more robust.
Breakpad can be used on processes where a mistaken library saves then restores one of our signal handlers with 'signal' instead of 'sigaction'. This loses the SA_SIGINFO flag associated with the Breakpad handler, and in some cases (e.g. Android/ARM kernels), the values of the 'info' and 'uc' parameters that ExceptionHandler::SignalHandler() receives will be completely bogus, leading to a crash when the function is executed (and of course, no minidump generation). To work-around this, have SignalHandler() check the state of the flag. If it is incorrectly unset, re-register with 'sigaction' and the correct flag, then return. The signal will be re-thrown, and this time the function will be called with the correct values. Review URL: https://breakpad.appspot.com/481002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1067 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
b52be69e59
commit
f72b9c6ff4
2 changed files with 60 additions and 0 deletions
|
|
@ -317,6 +317,37 @@ TEST(ExceptionHandlerTest, RedeliveryToDefaultHandler) {
|
|||
ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));
|
||||
}
|
||||
|
||||
// Check that saving and restoring the signal handler with 'signal'
|
||||
// instead of 'sigaction' doesn't make the Breakpad signal handler
|
||||
// crash. See comments in ExceptionHandler::SignalHandler for full
|
||||
// details.
|
||||
TEST(ExceptionHandlerTest, RedeliveryOnBadSignalHandlerFlag) {
|
||||
AutoTempDir temp_dir;
|
||||
const pid_t child = fork();
|
||||
if (child == 0) {
|
||||
// Install the RaiseSIGKILL handler for SIGSEGV.
|
||||
ASSERT_TRUE(InstallRaiseSIGKILL());
|
||||
|
||||
// Create a new exception handler, this installs a new SIGSEGV
|
||||
// handler, after saving the old one.
|
||||
ExceptionHandler handler(
|
||||
MinidumpDescriptor(temp_dir.path()), NULL,
|
||||
DoneCallbackReturnFalse, NULL, true, -1);
|
||||
|
||||
// Install the default SIGSEGV handler, saving the current one.
|
||||
// Then re-install the current one with 'signal', this loses the
|
||||
// SA_SIGINFO flag associated with the Breakpad handler.
|
||||
sighandler_t old_handler = signal(SIGSEGV, SIG_DFL);
|
||||
ASSERT_NE(old_handler, SIG_ERR);
|
||||
ASSERT_NE(signal(SIGSEGV, old_handler), SIG_ERR);
|
||||
|
||||
// Crash with the exception handler in scope.
|
||||
*reinterpret_cast<volatile int*>(NULL) = 0;
|
||||
}
|
||||
// SIGKILL means Breakpad's signal handler didn't crash.
|
||||
ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
|
||||
}
|
||||
|
||||
TEST(ExceptionHandlerTest, StackedHandlersDeliveredToTop) {
|
||||
AutoTempDir temp_dir;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue