Introduce SetFirstChanceHandler with more strict signature

Eventually, I want to remove the current version of
SetFirstChanceHandler. That is why I changed the name of the current
callback type to FirstChanceHandlerDeprecated.

I also made sure that it is not possible to have two different
FirstChanceHandlers set at the same time.

This is the first of a set of CLs to clean up the API between Chrome,
BreakPad, and V8. See more information in the tracking bug.

R=mark@chromium.org

Bug: chromium:921971
Change-Id: Ia8c2fd9bd875c36dd7ae8bb4a02e538556bc67a1
Reviewed-on: https://chromium-review.googlesource.com/c/1411776
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Andreas Haas 2019-01-15 15:15:14 +01:00 committed by Mark Mentovai
parent b988fa74ec
commit 9b06049ed9
3 changed files with 40 additions and 3 deletions

View file

@ -213,6 +213,7 @@ pthread_mutex_t g_handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER;
ExceptionHandler::CrashContext g_crash_context_; ExceptionHandler::CrashContext g_crash_context_;
FirstChanceHandler g_first_chance_handler_ = nullptr; FirstChanceHandler g_first_chance_handler_ = nullptr;
FirstChanceHandlerDeprecated g_first_chance_handler_deprecated_ = nullptr;
} // namespace } // namespace
// Runs before crashing: normal context. // Runs before crashing: normal context.
@ -338,6 +339,11 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
return; 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. // All the exception signals are blocked at this point.
pthread_mutex_lock(&g_handler_stack_mutex_); pthread_mutex_lock(&g_handler_stack_mutex_);
@ -791,7 +797,13 @@ bool ExceptionHandler::WriteMinidumpForChild(pid_t child,
} }
void SetFirstChanceExceptionHandler(FirstChanceHandler callback) { void SetFirstChanceExceptionHandler(FirstChanceHandler callback) {
g_first_chance_handler_deprecated_ = nullptr;
g_first_chance_handler_ = callback; g_first_chance_handler_ = callback;
} }
void SetFirstChanceExceptionHandler(FirstChanceHandlerDeprecated callback) {
g_first_chance_handler_ = nullptr;
g_first_chance_handler_deprecated_ = callback;
}
} // namespace google_breakpad } // namespace google_breakpad

View file

@ -273,10 +273,14 @@ class ExceptionHandler {
AppMemoryList app_memory_list_; AppMemoryList app_memory_list_;
}; };
typedef bool (*FirstChanceHandler)(int, siginfo_t*, void*);
typedef bool (*FirstChanceHandler)(int, void*, void*);
void SetFirstChanceExceptionHandler(FirstChanceHandler callback); void SetFirstChanceExceptionHandler(FirstChanceHandler callback);
typedef bool (*FirstChanceHandlerDeprecated)(int, void*, void*);
// Deprecated. Use SetFirstChanceExceptionHandler(FirstChanceHandler callback)
// instead.
void SetFirstChanceExceptionHandler(FirstChanceHandlerDeprecated callback);
} // namespace google_breakpad } // namespace google_breakpad
#endif // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_ #endif // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_

View file

@ -528,9 +528,30 @@ TEST(ExceptionHandlerTest, StackedHandlersUnhandledToBottom) {
namespace { namespace {
const int kSimpleFirstChanceReturnStatus = 42; const int kSimpleFirstChanceReturnStatus = 42;
bool SimpleFirstChanceHandler(int, void*, void*) { bool SimpleFirstChanceHandlerDeprecated(int, void*, void*) {
_exit(kSimpleFirstChanceReturnStatus); _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) { TEST(ExceptionHandlerTest, FirstChanceHandlerRuns) {