aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux/handler/minidump_generator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/linux/handler/minidump_generator.cc')
-rw-r--r--src/client/linux/handler/minidump_generator.cc37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/client/linux/handler/minidump_generator.cc b/src/client/linux/handler/minidump_generator.cc
index b212d44f..ea1b54a1 100644
--- a/src/client/linux/handler/minidump_generator.cc
+++ b/src/client/linux/handler/minidump_generator.cc
@@ -78,8 +78,14 @@ struct WriterArgument {
// Signal number when crash happed. Can be 0 if this is a requested dump.
int signo;
- // Signal contex when crash happed. Can be NULL if this is a requested dump.
- const struct sigcontext *sig_ctx;
+ // The ebp of the signal handler frame. Can be zero if this
+ // is a requested dump.
+ uintptr_t sighandler_ebp;
+
+ // Signal context when crash happed. Can be NULL if this is a requested dump.
+ // This is actually an out parameter, but it will be filled in at the start
+ // of the writer thread.
+ struct sigcontext *sig_ctx;
// Used to get information about the threads.
LinuxThread *thread_lister;
@@ -272,10 +278,10 @@ bool WriteCrashedThreadStream(MinidumpFileWriter *minidump_writer,
UntypedMDRVA memory(minidump_writer);
if (!WriteThreadStack(writer_args->sig_ctx->ebp,
- writer_args->sig_ctx->esp,
- writer_args->thread_lister,
- &memory,
- &thread->stack))
+ writer_args->sig_ctx->esp,
+ writer_args->thread_lister,
+ &memory,
+ &thread->stack))
return false;
TypedMDRVA<MDRawContextX86> context(minidump_writer);
@@ -714,12 +720,15 @@ int Write(void *argument) {
if (!writer_args->thread_lister->SuspendAllThreads())
return -1;
- if (writer_args->sig_ctx != NULL) {
+ if (writer_args->sighandler_ebp != 0 &&
+ writer_args->thread_lister->FindSigContext(writer_args->sighandler_ebp,
+ &writer_args->sig_ctx)) {
writer_args->crashed_stack_bottom =
- writer_args->thread_lister->GetThreadStackBottom(writer_args->sig_ctx->ebp);
+ writer_args->thread_lister->GetThreadStackBottom(
+ writer_args->sig_ctx->ebp);
int crashed_pid = FindCrashingThread(writer_args->crashed_stack_bottom,
- writer_args->requester_pid,
- writer_args->thread_lister);
+ writer_args->requester_pid,
+ writer_args->thread_lister);
if (crashed_pid > 0)
writer_args->crashed_pid = crashed_pid;
}
@@ -769,7 +778,8 @@ void MinidumpGenerator::AllocateStack() {
bool MinidumpGenerator::WriteMinidumpToFile(const char *file_pathname,
int signo,
- const struct sigcontext *sig_ctx) const {
+ uintptr_t sighandler_ebp,
+ struct sigcontext **sig_ctx) const {
assert(file_pathname != NULL);
assert(stack_ != NULL);
@@ -786,12 +796,15 @@ bool MinidumpGenerator::WriteMinidumpToFile(const char *file_pathname,
argument.requester_pid = getpid();
argument.crashed_pid = getpid();
argument.signo = signo;
- argument.sig_ctx = sig_ctx;
+ argument.sighandler_ebp = sighandler_ebp;
+ argument.sig_ctx = NULL;
int cloned_pid = clone(Write, stack_.get() + kStackSize,
CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_UNTRACED,
(void*)&argument);
waitpid(cloned_pid, NULL, __WALL);
+ if (sig_ctx != NULL)
+ *sig_ctx = argument.sig_ctx;
return true;
}