From 67364c1326644c953caf34c92edc91117c71282c Mon Sep 17 00:00:00 2001 From: "ted.mielczarek@gmail.com" Date: Tue, 18 Sep 2012 18:51:56 +0000 Subject: Allow generating minidumps from live process on Linux via ExceptionHandler Original patch by Chris Jones at https://bugzilla.mozilla.org/show_bug.cgi?id=544936 and https://bugzilla.mozilla.org/show_bug.cgi?id=555309 R=mark at https://breakpad.appspot.com/449003/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1043 4c0a9323-5329-0410-9bdc-e9ce6186880e --- .../linux/minidump_writer/minidump_writer.cc | 33 +++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src/client/linux/minidump_writer/minidump_writer.cc') diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index b081b298..02055640 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -686,6 +686,7 @@ class MinidumpWriter { // signal handler with the alternative stack, which would be deeply // unhelpful. if (static_cast(thread.thread_id) == GetCrashThread() && + ucontext_ && !dumper_->IsPostMortem()) { const void* stack; size_t stack_len; @@ -776,8 +777,13 @@ class MinidumpWriter { PopSeccompStackFrame(cpu.get(), thread, stack_copy); thread.thread_context = cpu.location(); if (dumper_->threads()[i] == GetCrashThread()) { - assert(dumper_->IsPostMortem()); crashing_thread_context_ = cpu.location(); + if (!dumper_->IsPostMortem()) { + // This is the crashing thread of a live process, but + // no context was provided, so set the crash address + // while the instruction pointer is already here. + dumper_->set_crash_address(GetInstructionPointer(info)); + } } } @@ -1092,6 +1098,10 @@ class MinidumpWriter { uintptr_t GetInstructionPointer() { return ucontext_->uc_mcontext.gregs[REG_EIP]; } + + uintptr_t GetInstructionPointer(const ThreadInfo& info) { + return info.regs.eip; + } #elif defined(__x86_64) uintptr_t GetStackPointer() { return ucontext_->uc_mcontext.gregs[REG_RSP]; @@ -1100,6 +1110,10 @@ class MinidumpWriter { uintptr_t GetInstructionPointer() { return ucontext_->uc_mcontext.gregs[REG_RIP]; } + + uintptr_t GetInstructionPointer(const ThreadInfo& info) { + return info.regs.rip; + } #elif defined(__ARM_EABI__) uintptr_t GetStackPointer() { return ucontext_->uc_mcontext.arm_sp; @@ -1108,6 +1122,10 @@ class MinidumpWriter { uintptr_t GetInstructionPointer() { return ucontext_->uc_mcontext.arm_pc; } + + uintptr_t GetInstructionPointer(const ThreadInfo& info) { + return info.regs.uregs[15]; + } #else #error "This code has not been ported to your platform yet." #endif @@ -1435,6 +1453,19 @@ bool WriteMinidump(int minidump_fd, pid_t crashing_process, MappingList(), AppMemoryList()); } +bool WriteMinidump(const char* minidump_path, pid_t process, + pid_t process_blamed_thread) { + LinuxPtraceDumper dumper(process); + // MinidumpWriter will set crash address + dumper.set_crash_signal(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED); + dumper.set_crash_thread(process_blamed_thread); + MinidumpWriter writer(minidump_path, -1, NULL, MappingList(), + AppMemoryList(), &dumper); + if (!writer.Init()) + return false; + return writer.Dump(); +} + bool WriteMinidump(const char* minidump_path, pid_t crashing_process, const void* blob, size_t blob_size, const MappingList& mappings, -- cgit v1.2.1