Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Unified Diff: src/client/linux/handler/exception_handler.cc

Issue 1354923002: Linux ExceptionHandler: don't allocate the CrashContext on the stack (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/client/linux/handler/exception_handler.cc
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index 9b20fe25195fde766403c7ca7cc41b880252a0d9..5bd2d8ccc6aed4693fca8aa746c7779775d6dc51 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -212,6 +212,12 @@ void InstallDefaultHandler(int sig) {
std::vector<ExceptionHandler*>* g_handler_stack_ = NULL;
pthread_mutex_t g_handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER;
+// sizeof(CrashContext) can be too big w.r.t the size of alternatate stack
+// for SignalHandler(). Keep the crash context as a .bss field. Exception
+// handlers are serialized by the |g_handler_stack_mutex_| and at most one at a
+// time can use |g_crash_context_|.
+ExceptionHandler::CrashContext g_crash_context_;
+
} // namespace
// Runs before crashing: normal context.
@@ -239,6 +245,11 @@ ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor,
#endif
pthread_mutex_lock(&g_handler_stack_mutex_);
+
+ // Pre-fault the crash context struct. This is to avoid failing due to OOM
Mark Mentovai 2015/09/18 22:13:20 Smart.
+ // if handling an exception when the process ran out of virtual memory.
+ memset(&g_crash_context_, 0, sizeof(g_crash_context_));
+
if (!g_handler_stack_)
g_handler_stack_ = new std::vector<ExceptionHandler*>;
if (install_handler) {
@@ -424,36 +435,37 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) {
if (signal_trusted || (signal_pid_trusted && info->si_pid == getpid())) {
sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
}
- CrashContext context;
+
// Fill in all the holes in the struct to make Valgrind happy.
- memset(&context, 0, sizeof(context));
- memcpy(&context.siginfo, info, sizeof(siginfo_t));
- memcpy(&context.context, uc, sizeof(struct ucontext));
+ memset(&g_crash_context_, 0, sizeof(g_crash_context_));
Mark Mentovai 2015/09/18 22:13:20 Necessary? You already wrote zeroes into it when y
Primiano Tucci (use gerrit) 2015/09/18 22:22:40 Right, should be safe from the production code any
Mark Mentovai 2015/09/18 22:34:56 Primiano Tucci wrote:
+ memcpy(&g_crash_context_.siginfo, info, sizeof(siginfo_t));
+ memcpy(&g_crash_context_.context, uc, sizeof(struct ucontext));
#if defined(__aarch64__)
- struct ucontext *uc_ptr = (struct ucontext*)uc;
- struct fpsimd_context *fp_ptr =
+ struct ucontext* uc_ptr = (struct ucontext*)uc;
+ struct fpsimd_context* fp_ptr =
(struct fpsimd_context*)&uc_ptr->uc_mcontext.__reserved;
if (fp_ptr->head.magic == FPSIMD_MAGIC) {
- memcpy(&context.float_state, fp_ptr, sizeof(context.float_state));
+ memcpy(&g_crash_context_.float_state, fp_ptr,
+ sizeof(g_crash_context_.float_state));
}
-#elif !defined(__ARM_EABI__) && !defined(__mips__)
+#elif !defined(__ARM_EABI__) && !defined(__mips__)
// FP state is not part of user ABI on ARM Linux.
// In case of MIPS Linux FP state is already part of struct ucontext
// and 'float_state' is not a member of CrashContext.
- struct ucontext *uc_ptr = (struct ucontext*)uc;
+ struct ucontext* uc_ptr = (struct ucontext*)uc;
if (uc_ptr->uc_mcontext.fpregs) {
- memcpy(&context.float_state,
- uc_ptr->uc_mcontext.fpregs,
- sizeof(context.float_state));
+ memcpy(&g_crash_context_.float_state, uc_ptr->uc_mcontext.fpregs,
+ sizeof(g_crash_context_.float_state));
}
#endif
- context.tid = syscall(__NR_gettid);
+ g_crash_context_.tid = syscall(__NR_gettid);
if (crash_handler_ != NULL) {
- if (crash_handler_(&context, sizeof(context), callback_context_)) {
+ if (crash_handler_(&g_crash_context_, sizeof(g_crash_context_),
+ callback_context_)) {
return true;
}
}
- return GenerateDump(&context);
+ return GenerateDump(&g_crash_context_);
}
// This is a public interface to HandleSignal that allows the client to
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698