aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux
diff options
context:
space:
mode:
authorAndrew Ermakovich <andrew@resilio.com>2017-04-21 18:41:24 +0300
committerMike Frysinger <vapier@chromium.org>2017-04-21 17:28:03 +0000
commit67649c61853108eb0c29703f6ff0db42e9d69f10 (patch)
treee447f2c18db26d32314b02e7c94a1644f054c030 /src/client/linux
parentMake minidump name generation on Linux as random as possible (diff)
downloadbreakpad-67649c61853108eb0c29703f6ff0db42e9d69f10.tar.xz
Fixing breakpad on old linux kernel
Try to read the trace's registers by PTRACE_GETREGS if kernel doesn't support PTRACE_GETREGSET. Bug: Change-Id: I881f3a868789747ca217f22a93370c6914881f9a Reviewed-on: https://chromium-review.googlesource.com/484479 Reviewed-by: Mike Frysinger <vapier@chromium.org>
Diffstat (limited to 'src/client/linux')
-rw-r--r--src/client/linux/minidump_writer/linux_ptrace_dumper.cc73
-rw-r--r--src/client/linux/minidump_writer/linux_ptrace_dumper.h9
2 files changed, 53 insertions, 29 deletions
diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
index 30b8f3dd..f181bf92 100644
--- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
+++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
@@ -149,6 +149,46 @@ bool LinuxPtraceDumper::CopyFromProcess(void* dest, pid_t child,
return true;
}
+bool LinuxPtraceDumper::ReadRegisterSet(ThreadInfo* info, pid_t tid)
+{
+#ifdef PTRACE_GETREGSET
+ struct iovec io;
+ info->GetGeneralPurposeRegisters(&io.iov_base, &io.iov_len);
+ if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, (void*)&io) == -1) {
+ return false;
+ }
+
+ info->GetFloatingPointRegisters(&io.iov_base, &io.iov_len);
+ if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_FPREGSET, (void*)&io) == -1) {
+ return false;
+ }
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool LinuxPtraceDumper::ReadRegisters(ThreadInfo* info, pid_t tid) {
+ void* gp_addr;
+ info->GetGeneralPurposeRegisters(&gp_addr, NULL);
+ if (sys_ptrace(PTRACE_GETREGS, tid, NULL, gp_addr) == -1) {
+ return false;
+ }
+
+#if !(defined(__ANDROID__) && defined(__ARM_EABI__))
+ // When running an arm build on an arm64 device, attempting to get the
+ // floating point registers fails. On Android, the floating point registers
+ // aren't written to the cpu context anyway, so just don't get them here.
+ // See http://crbug.com/508324
+ void* fp_addr;
+ info->GetFloatingPointRegisters(&fp_addr, NULL);
+ if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, fp_addr) == -1) {
+ return false;
+ }
+#endif
+ return true;
+}
+
// Read thread info from /proc/$pid/status.
// Fill out the |tgid|, |ppid| and |pid| members of |info|. If unavailable,
// these members are set to -1. Returns true iff all three members are
@@ -188,36 +228,11 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
if (info->ppid == -1 || info->tgid == -1)
return false;
-#ifdef PTRACE_GETREGSET
- struct iovec io;
- info->GetGeneralPurposeRegisters(&io.iov_base, &io.iov_len);
- if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, (void*)&io) == -1) {
- return false;
- }
-
- info->GetFloatingPointRegisters(&io.iov_base, &io.iov_len);
- if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_FPREGSET, (void*)&io) == -1) {
- return false;
- }
-#else // PTRACE_GETREGSET
- void* gp_addr;
- info->GetGeneralPurposeRegisters(&gp_addr, NULL);
- if (sys_ptrace(PTRACE_GETREGS, tid, NULL, gp_addr) == -1) {
- return false;
- }
-
-#if !(defined(__ANDROID__) && defined(__ARM_EABI__))
- // When running an arm build on an arm64 device, attempting to get the
- // floating point registers fails. On Android, the floating point registers
- // aren't written to the cpu context anyway, so just don't get them here.
- // See http://crbug.com/508324
- void* fp_addr;
- info->GetFloatingPointRegisters(&fp_addr, NULL);
- if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, fp_addr) == -1) {
- return false;
+ if (!ReadRegisterSet(info, tid)) {
+ if (!ReadRegisters(info, tid)) {
+ return false;
+ }
}
-#endif
-#endif // PTRACE_GETREGSET
#if defined(__i386)
#if !defined(bit_FXSAVE) // e.g. Clang
diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.h b/src/client/linux/minidump_writer/linux_ptrace_dumper.h
index 2ce834b0..cee58178 100644
--- a/src/client/linux/minidump_writer/linux_ptrace_dumper.h
+++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.h
@@ -85,6 +85,15 @@ class LinuxPtraceDumper : public LinuxDumper {
private:
// Set to true if all threads of the crashed process are suspended.
bool threads_suspended_;
+
+ // Read the tracee's registers on kernel with PTRACE_GETREGSET support.
+ // Returns false if PTRACE_GETREGSET is not defined.
+ // Returns true on success.
+ bool ReadRegisterSet(ThreadInfo* info, pid_t tid);
+
+ // Read the tracee's registers on kernel with PTRACE_GETREGS support.
+ // Returns true on success.
+ bool ReadRegisters(ThreadInfo* info, pid_t tid);
};
} // namespace google_breakpad