aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/linux/handler/exception_handler.cc12
-rw-r--r--src/client/linux/handler/exception_handler.h8
-rw-r--r--src/client/linux/handler/exception_handler_unittest.cc23
3 files changed, 40 insertions, 3 deletions
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index b895f6d7..0d7cd9cf 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -213,6 +213,7 @@ pthread_mutex_t g_handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER;
ExceptionHandler::CrashContext g_crash_context_;
FirstChanceHandler g_first_chance_handler_ = nullptr;
+FirstChanceHandlerDeprecated g_first_chance_handler_deprecated_ = nullptr;
} // namespace
// Runs before crashing: normal context.
@@ -338,6 +339,11 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
return;
}
+ if (g_first_chance_handler_deprecated_ != nullptr &&
+ g_first_chance_handler_deprecated_(sig, info, uc)) {
+ return;
+ }
+
// All the exception signals are blocked at this point.
pthread_mutex_lock(&g_handler_stack_mutex_);
@@ -791,7 +797,13 @@ bool ExceptionHandler::WriteMinidumpForChild(pid_t child,
}
void SetFirstChanceExceptionHandler(FirstChanceHandler callback) {
+ g_first_chance_handler_deprecated_ = nullptr;
g_first_chance_handler_ = callback;
}
+void SetFirstChanceExceptionHandler(FirstChanceHandlerDeprecated callback) {
+ g_first_chance_handler_ = nullptr;
+ g_first_chance_handler_deprecated_ = callback;
+}
+
} // namespace google_breakpad
diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h
index 1695a2b7..1ddeac88 100644
--- a/src/client/linux/handler/exception_handler.h
+++ b/src/client/linux/handler/exception_handler.h
@@ -273,10 +273,14 @@ class ExceptionHandler {
AppMemoryList app_memory_list_;
};
-
-typedef bool (*FirstChanceHandler)(int, void*, void*);
+typedef bool (*FirstChanceHandler)(int, siginfo_t*, void*);
void SetFirstChanceExceptionHandler(FirstChanceHandler callback);
+typedef bool (*FirstChanceHandlerDeprecated)(int, void*, void*);
+// Deprecated. Use SetFirstChanceExceptionHandler(FirstChanceHandler callback)
+// instead.
+void SetFirstChanceExceptionHandler(FirstChanceHandlerDeprecated callback);
+
} // namespace google_breakpad
#endif // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_
diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc
index 329d0147..2e4eb09a 100644
--- a/src/client/linux/handler/exception_handler_unittest.cc
+++ b/src/client/linux/handler/exception_handler_unittest.cc
@@ -528,9 +528,30 @@ TEST(ExceptionHandlerTest, StackedHandlersUnhandledToBottom) {
namespace {
const int kSimpleFirstChanceReturnStatus = 42;
-bool SimpleFirstChanceHandler(int, void*, void*) {
+bool SimpleFirstChanceHandlerDeprecated(int, void*, void*) {
_exit(kSimpleFirstChanceReturnStatus);
}
+
+bool SimpleFirstChanceHandler(int, siginfo_t*, void*) {
+ _exit(kSimpleFirstChanceReturnStatus);
+}
+}
+
+TEST(ExceptionHandlerTest, FirstChanceHandlerRunsDeprecated) {
+ AutoTempDir temp_dir;
+
+ const pid_t child = fork();
+ if (child == 0) {
+ ExceptionHandler handler(
+ MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);
+ google_breakpad::SetFirstChanceExceptionHandler(
+ SimpleFirstChanceHandlerDeprecated);
+ DoNullPointerDereference();
+ }
+ int status;
+ ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
+ ASSERT_TRUE(WIFEXITED(status));
+ ASSERT_EQ(kSimpleFirstChanceReturnStatus, WEXITSTATUS(status));
}
TEST(ExceptionHandlerTest, FirstChanceHandlerRuns) {