Add crash reason and address to microdumps.

This will allow us to provide the right information for webview renderer
crashes. At the moment the crash information for the browser process is
captured (from the debuggerd output) instead.

BUG=754715

Change-Id: I409546311b6e38fe1cf804097c18d7bb2a015d83
Reviewed-on: https://chromium-review.googlesource.com/612381
Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
Tobias Sargeant 2017-08-11 18:11:16 +01:00 committed by Tobias Sargeant
parent 1b704857f1
commit 38cbbfed71
4 changed files with 111 additions and 0 deletions

View file

@ -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));

View file

@ -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);
}

View file

@ -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 &&

View file

@ -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; }