aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/linux')
-rw-r--r--src/client/linux/microdump_writer/microdump_writer.cc11
-rw-r--r--src/client/linux/microdump_writer/microdump_writer_unittest.cc27
-rw-r--r--src/client/linux/minidump_writer/linux_dumper.cc72
-rw-r--r--src/client/linux/minidump_writer/linux_dumper.h1
4 files changed, 111 insertions, 0 deletions
diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc
index 3764eec2..5c3c751d 100644
--- a/src/client/linux/microdump_writer/microdump_writer.cc
+++ b/src/client/linux/microdump_writer/microdump_writer.cc
@@ -181,6 +181,7 @@ class MicrodumpWriter {
DumpProductInformation();
DumpOSInformation();
DumpProcessType();
+ DumpCrashReason();
DumpGPUInformation();
#if !defined(__LP64__)
DumpFreeSpace();
@@ -298,6 +299,16 @@ class MicrodumpWriter {
LogCommitLine();
}
+ void DumpCrashReason() {
+ LogAppend("R ");
+ LogAppend(dumper_->crash_signal());
+ LogAppend(" ");
+ LogAppend(dumper_->GetCrashSignalString());
+ LogAppend(" ");
+ LogAppend(dumper_->crash_address());
+ LogCommitLine();
+ }
+
void DumpOSInformation() {
const uint8_t n_cpus = static_cast<uint8_t>(sysconf(_SC_NPROCESSORS_CONF));
diff --git a/src/client/linux/microdump_writer/microdump_writer_unittest.cc b/src/client/linux/microdump_writer/microdump_writer_unittest.cc
index cbcd1399..c2fea022 100644
--- a/src/client/linux/microdump_writer/microdump_writer_unittest.cc
+++ b/src/client/linux/microdump_writer/microdump_writer_unittest.cc
@@ -65,6 +65,7 @@ MicrodumpExtraInfo MakeMicrodumpExtraInfo(
info.build_fingerprint = build_fingerprint;
info.product_info = product_info;
info.gpu_fingerprint = gpu_fingerprint;
+ info.process_type = "Browser";
return info;
}
@@ -74,6 +75,7 @@ bool ContainsMicrodump(const std::string& buf) {
}
const char kIdentifiableString[] = "_IDENTIFIABLE_";
+const uintptr_t kCrashAddress = 0xdeaddeadu;
void CrashAndGetMicrodump(const MappingList& mappings,
const MicrodumpExtraInfo& microdump_extra_info,
@@ -115,6 +117,8 @@ void CrashAndGetMicrodump(const MappingList& mappings,
getcontext(&context.context);
// Set a non-zero tid to avoid tripping asserts.
context.tid = child;
+ context.siginfo.si_signo = MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED;
+ context.siginfo.si_addr = reinterpret_cast<void*>(kCrashAddress);
// Redirect temporarily stderr to the stderr.log file.
int save_err = dup(STDERR_FILENO);
@@ -172,6 +176,8 @@ void CheckMicrodumpContents(const string& microdump_content,
std::istringstream iss(microdump_content);
bool did_find_os_info = false;
bool did_find_product_info = false;
+ bool did_find_process_type = false;
+ bool did_find_crash_reason = false;
bool did_find_gpu_info = false;
for (string line; std::getline(iss, line);) {
if (line.find("O ") == 0) {
@@ -190,9 +196,28 @@ void CheckMicrodumpContents(const string& microdump_content,
// Check that the build fingerprint is in the right place.
os_info_tokens >> token;
+ ASSERT_FALSE(os_info_tokens.fail());
if (expected_info.build_fingerprint)
ASSERT_EQ(expected_info.build_fingerprint, token);
did_find_os_info = true;
+ } else if (line.find("P ") == 0) {
+ if (expected_info.process_type)
+ ASSERT_EQ(string("P ") + expected_info.process_type, line);
+ did_find_process_type = true;
+ } else if (line.find("R ") == 0) {
+ std::istringstream crash_reason_tokens(line);
+ string token;
+ unsigned crash_reason;
+ string crash_reason_str;
+ intptr_t crash_address;
+ crash_reason_tokens.ignore(2); // Ignore the "R " preamble.
+ crash_reason_tokens >> std::hex >> crash_reason >> crash_reason_str >>
+ crash_address;
+ ASSERT_FALSE(crash_reason_tokens.fail());
+ ASSERT_EQ(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED, crash_reason);
+ ASSERT_EQ("DUMP_REQUESTED", crash_reason_str);
+ ASSERT_EQ(0xDEADDEADu, kCrashAddress);
+ did_find_crash_reason = true;
} else if (line.find("V ") == 0) {
if (expected_info.product_info)
ASSERT_EQ(string("V ") + expected_info.product_info, line);
@@ -205,6 +230,8 @@ void CheckMicrodumpContents(const string& microdump_content,
}
ASSERT_TRUE(did_find_os_info);
ASSERT_TRUE(did_find_product_info);
+ ASSERT_TRUE(did_find_process_type);
+ ASSERT_TRUE(did_find_crash_reason);
ASSERT_TRUE(did_find_gpu_info);
}
diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc
index 141aa07c..0013824b 100644
--- a/src/client/linux/minidump_writer/linux_dumper.cc
+++ b/src/client/linux/minidump_writer/linux_dumper.cc
@@ -50,6 +50,7 @@
#include "common/linux/linux_libc_support.h"
#include "common/linux/memory_mapped_file.h"
#include "common/linux/safe_readlink.h"
+#include "google_breakpad/common/minidump_exception_linux.h"
#include "third_party/lss/linux_syscall_support.h"
#if defined(__ANDROID__)
@@ -336,6 +337,77 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping,
return success;
}
+const char* LinuxDumper::GetCrashSignalString() const {
+ switch (static_cast<unsigned int>(crash_signal_)) {
+ case MD_EXCEPTION_CODE_LIN_SIGHUP:
+ return "SIGHUP";
+ case MD_EXCEPTION_CODE_LIN_SIGINT:
+ return "SIGINT";
+ case MD_EXCEPTION_CODE_LIN_SIGQUIT:
+ return "SIGQUIT";
+ case MD_EXCEPTION_CODE_LIN_SIGILL:
+ return "SIGILL";
+ case MD_EXCEPTION_CODE_LIN_SIGTRAP:
+ return "SIGTRAP";
+ case MD_EXCEPTION_CODE_LIN_SIGABRT:
+ return "SIGABRT";
+ case MD_EXCEPTION_CODE_LIN_SIGBUS:
+ return "SIGBUS";
+ case MD_EXCEPTION_CODE_LIN_SIGFPE:
+ return "SIGFPE";
+ case MD_EXCEPTION_CODE_LIN_SIGKILL:
+ return "SIGKILL";
+ case MD_EXCEPTION_CODE_LIN_SIGUSR1:
+ return "SIGUSR1";
+ case MD_EXCEPTION_CODE_LIN_SIGSEGV:
+ return "SIGSEGV";
+ case MD_EXCEPTION_CODE_LIN_SIGUSR2:
+ return "SIGUSR2";
+ case MD_EXCEPTION_CODE_LIN_SIGPIPE:
+ return "SIGPIPE";
+ case MD_EXCEPTION_CODE_LIN_SIGALRM:
+ return "SIGALRM";
+ case MD_EXCEPTION_CODE_LIN_SIGTERM:
+ return "SIGTERM";
+ case MD_EXCEPTION_CODE_LIN_SIGSTKFLT:
+ return "SIGSTKFLT";
+ case MD_EXCEPTION_CODE_LIN_SIGCHLD:
+ return "SIGCHLD";
+ case MD_EXCEPTION_CODE_LIN_SIGCONT:
+ return "SIGCONT";
+ case MD_EXCEPTION_CODE_LIN_SIGSTOP:
+ return "SIGSTOP";
+ case MD_EXCEPTION_CODE_LIN_SIGTSTP:
+ return "SIGTSTP";
+ case MD_EXCEPTION_CODE_LIN_SIGTTIN:
+ return "SIGTTIN";
+ case MD_EXCEPTION_CODE_LIN_SIGTTOU:
+ return "SIGTTOU";
+ case MD_EXCEPTION_CODE_LIN_SIGURG:
+ return "SIGURG";
+ case MD_EXCEPTION_CODE_LIN_SIGXCPU:
+ return "SIGXCPU";
+ case MD_EXCEPTION_CODE_LIN_SIGXFSZ:
+ return "SIGXFSZ";
+ case MD_EXCEPTION_CODE_LIN_SIGVTALRM:
+ return "SIGVTALRM";
+ case MD_EXCEPTION_CODE_LIN_SIGPROF:
+ return "SIGPROF";
+ case MD_EXCEPTION_CODE_LIN_SIGWINCH:
+ return "SIGWINCH";
+ case MD_EXCEPTION_CODE_LIN_SIGIO:
+ return "SIGIO";
+ case MD_EXCEPTION_CODE_LIN_SIGPWR:
+ return "SIGPWR";
+ case MD_EXCEPTION_CODE_LIN_SIGSYS:
+ return "SIGSYS";
+ case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED:
+ return "DUMP_REQUESTED";
+ default:
+ return "UNKNOWN";
+ }
+}
+
bool LinuxDumper::GetMappingAbsolutePath(const MappingInfo& mapping,
char path[PATH_MAX]) const {
return my_strlcpy(path, root_prefix_, PATH_MAX) < PATH_MAX &&
diff --git a/src/client/linux/minidump_writer/linux_dumper.h b/src/client/linux/minidump_writer/linux_dumper.h
index 3a9a2e8b..389d8a21 100644
--- a/src/client/linux/minidump_writer/linux_dumper.h
+++ b/src/client/linux/minidump_writer/linux_dumper.h
@@ -177,6 +177,7 @@ class LinuxDumper {
int crash_signal() const { return crash_signal_; }
void set_crash_signal(int crash_signal) { crash_signal_ = crash_signal; }
+ const char* GetCrashSignalString() const;
pid_t crash_thread() const { return crash_thread_; }
void set_crash_thread(pid_t crash_thread) { crash_thread_ = crash_thread; }