mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-27 22:24:18 +01:00
linux_core_dumper: support NT_SIGINFO for reading crashing address
The current core dumper only parses NT_PRSTATUS notes. With signal details, this note only includes three fields: signo, code, and errno. We set exception_code to signo and exception_flag to code. The errno value isn't set by the kernel, so there's no need to save it. However, we never fill in exception_address which means all converted crashes look like they happen at address 0. This implies a NULL jump which is usually not the case, so it's just confusing. The prstatus structure doesn't offer anything directly that tracks this. Starting with linux-3.7, the kernel writes out the full siginfo structure in the NT_SIGINFO note. So lets support that to pull out si_addr which, for a bunch of common signals, is the value we want in exception_address. The size of the siginfo_t structure should be locked to 128 bytes at build time for all architectures, so this should hopefully be stable. Bug: google-breakpad:790 Change-Id: I458bad4787b1a8b73fad8fe068e9f23bec957599 Reviewed-on: https://chromium-review.googlesource.com/c/1497661 Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
19a8433a60
commit
59d89be2d6
@ -165,6 +165,7 @@ bool LinuxCoreDumper::EnumerateThreads() {
|
||||
// -------------------------------------------------------------------
|
||||
// 1st thread CORE NT_PRSTATUS
|
||||
// process-wide CORE NT_PRPSINFO
|
||||
// process-wide CORE NT_SIGINFO
|
||||
// process-wide CORE NT_AUXV
|
||||
// 1st thread CORE NT_FPREGSET
|
||||
// 1st thread LINUX NT_PRXFPREG
|
||||
@ -219,6 +220,28 @@ bool LinuxCoreDumper::EnumerateThreads() {
|
||||
thread_infos_.push_back(info);
|
||||
break;
|
||||
}
|
||||
case NT_SIGINFO: {
|
||||
if (description.length() != sizeof(siginfo_t)) {
|
||||
fprintf(stderr, "Found NT_SIGINFO descriptor of unexpected size\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const siginfo_t* info =
|
||||
reinterpret_cast<const siginfo_t*>(description.data());
|
||||
|
||||
// Set crash_address when si_addr is valid for the signal.
|
||||
switch (info->si_signo) {
|
||||
case MD_EXCEPTION_CODE_LIN_SIGBUS:
|
||||
case MD_EXCEPTION_CODE_LIN_SIGFPE:
|
||||
case MD_EXCEPTION_CODE_LIN_SIGILL:
|
||||
case MD_EXCEPTION_CODE_LIN_SIGSEGV:
|
||||
case MD_EXCEPTION_CODE_LIN_SIGSYS:
|
||||
case MD_EXCEPTION_CODE_LIN_SIGTRAP:
|
||||
crash_address_ = reinterpret_cast<uintptr_t>(info->si_addr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if defined(__i386) || defined(__x86_64)
|
||||
case NT_FPREGSET: {
|
||||
if (thread_infos_.empty())
|
||||
|
Loading…
Reference in New Issue
Block a user