[PATCH] Add register dumping support to SuspendedThreadsList.

Sergey Matveev earthdok at google.com
Thu Mar 28 23:24:06 PDT 2013


Hi kcc, glider, samsonov,

An interface for obtaining register contexts from suspended threads. Tailored
for LSan use.

http://llvm-reviews.chandlerc.com/D593

Files:
  lib/sanitizer_common/sanitizer_stoptheworld.h
  lib/sanitizer_common/sanitizer_stoptheworld_linux.cc

Index: lib/sanitizer_common/sanitizer_stoptheworld.h
===================================================================
--- lib/sanitizer_common/sanitizer_stoptheworld.h
+++ lib/sanitizer_common/sanitizer_stoptheworld.h
@@ -20,21 +20,21 @@
 namespace __sanitizer {
 typedef int SuspendedThreadID;
 
-// Holds the list of suspended threads. Also provides register dumping
-// functionality (to be implemented).
+// Holds the list of suspended threads and provides an interface to dump their
+// register contexts.
 class SuspendedThreadsList {
  public:
   SuspendedThreadsList()
     : thread_ids_(1024) {}
-  SuspendedThreadID GetThreadID(uptr index) {
+  SuspendedThreadID GetThreadID(uptr index) const {
     CHECK_LT(index, thread_ids_.size());
     return thread_ids_[index];
   }
-  void DumpRegisters(uptr index) const {
-    UNIMPLEMENTED();
-  }
-  uptr thread_count() { return thread_ids_.size(); }
-  bool Contains(SuspendedThreadID thread_id) {
+  int GetRegistersAndSP(uptr index, uptr *buffer, uptr *sp) const;
+  // The buffer in GetRegistersAndSP should be at least this big.
+  static uptr RegisterCount();
+  uptr thread_count() const { return thread_ids_.size(); }
+  bool Contains(SuspendedThreadID thread_id) const {
     for (uptr i = 0; i < thread_ids_.size(); i++) {
       if (thread_ids_[i] == thread_id)
         return true;
Index: lib/sanitizer_common/sanitizer_stoptheworld_linux.cc
===================================================================
--- lib/sanitizer_common/sanitizer_stoptheworld_linux.cc
+++ lib/sanitizer_common/sanitizer_stoptheworld_linux.cc
@@ -24,6 +24,7 @@
 #include <sys/prctl.h> // for PR_* definitions
 #include <sys/ptrace.h> // for PTRACE_* definitions
 #include <sys/types.h> // for pid_t
+#include <sys/user.h> // for user_regst_struct
 #include <sys/wait.h> // for signal-related stuff
 
 #include "sanitizer_common.h"
@@ -324,6 +325,29 @@
   sigprocmask(SIG_SETMASK, &old_sigset, &old_sigset);
 }
 
+// Platform-specific methods from SuspendedThreadsList.
+int SuspendedThreadsList::GetRegistersAndSP(uptr index,
+                                            uptr *buffer,
+                                            uptr *sp) const {
+  pid_t tid = GetThreadID(index);
+  user_regs_struct regs;
+  if (internal_ptrace(PTRACE_GETREGS, tid, NULL, &regs) != 0) {
+    Report("Could not get registers from thread %d (errno %d).\n",
+           tid, errno);
+    return -1;
+  }
+#if __WORDSIZE == 32
+    *sp = regs.esp;
+#else
+    *sp = regs.rsp;
+#endif
+  internal_memcpy(buffer, &regs, sizeof(regs));
+  return 0;
+}
+
+uptr SuspendedThreadsList::RegisterCount() {
+  return sizeof(user_regs_struct) / sizeof(uptr);
+}
 }  // namespace __sanitizer
 
 #endif  // __linux__
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D593.1.patch
Type: text/x-patch
Size: 2740 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130328/a3b17e12/attachment.bin>


More information about the llvm-commits mailing list