[compiler-rt] r189789 - [TSan] Move the /proc/self/maps parsing logic to sanitizer_common

Alexander Potapenko glider at google.com
Tue Sep 3 04:09:16 PDT 2013


Author: glider
Date: Tue Sep  3 06:09:16 2013
New Revision: 189789

URL: http://llvm.org/viewvc/llvm-project?rev=189789&view=rev
Log:
[TSan] Move the /proc/self/maps parsing logic to sanitizer_common 

Provide a generic way for the tools to generate memory profiles from contents of /proc/self/maps


Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=189789&r1=189788&r2=189789&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Tue Sep  3 06:09:16 2013
@@ -403,6 +403,30 @@ static bool IsDecimal(char c) {
   return c >= '0' && c <= '9';
 }
 
+static bool IsHex(char c) {
+  return (c >= '0' && c <= '9')
+      || (c >= 'a' && c <= 'f');
+}
+
+static uptr ReadHex(const char *p) {
+  uptr v = 0;
+  for (; IsHex(p[0]); p++) {
+    if (p[0] >= '0' && p[0] <= '9')
+      v = v * 16 + p[0] - '0';
+    else
+      v = v * 16 + p[0] - 'a' + 10;
+  }
+  return v;
+}
+
+static uptr ReadDecimal(const char *p) {
+  uptr v = 0;
+  for (; IsDecimal(p[0]); p++)
+    v = v * 10 + p[0] - '0';
+  return v;
+}
+
+
 bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,
                                char filename[], uptr filename_size,
                                uptr *protection) {
@@ -473,6 +497,30 @@ bool MemoryMappingLayout::GetObjectNameA
                                        protection);
 }
 
+void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) {
+  char *smaps = 0;
+  uptr smaps_cap = 0;
+  uptr smaps_len = ReadFileToBuffer("/proc/self/smaps",
+      &smaps, &smaps_cap, 64<<20);
+  uptr total = 0;
+  uptr start = 0;
+  bool file = false;
+  const char *pos = smaps;
+  while (pos < smaps + smaps_len) {
+    if (IsHex(pos[0])) {
+      start = ReadHex(pos);
+      for (; *pos != '/' && *pos > '\n'; pos++) {}
+      file = *pos == '/';
+    } else if (internal_strncmp(pos, "Rss:", 4) == 0) {
+      for (; *pos < '0' || *pos > '9'; pos++) {}
+      uptr rss = ReadDecimal(pos) * 1024;
+      cb(start, rss, file, stats, stats_size);
+    }
+    while (*pos++ != '\n') {}
+  }
+  UnmapOrDie(smaps, smaps_cap);
+}
+
 enum MutexState {
   MtxUnlocked = 0,
   MtxLocked = 1,

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h?rev=189789&r1=189788&r2=189789&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h Tue Sep  3 06:09:16 2013
@@ -32,7 +32,7 @@ class MemoryMappingLayout {
   }
 };
 
-#else  // _WIN32
+#else  // SANITIZER_WINDOWS
 #if SANITIZER_LINUX
 struct ProcSelfMapsBuff {
   char *data;
@@ -118,7 +118,15 @@ class MemoryMappingLayout {
 # endif
 };
 
-#endif  // _WIN32
+typedef void (*fill_profile_f)(uptr start, uptr rss, bool file,
+                               /*out*/uptr *stats, uptr stats_size);
+
+// Parse the contents of /proc/self/smaps and generate a memory profile.
+// |cb| is a tool-specific callback that fills the |stats| array containing
+// |stats_size| elements.
+void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size);
+
+#endif  // SANITIZER_WINDOWS
 
 }  // namespace __sanitizer
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=189789&r1=189788&r2=189789&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Tue Sep  3 06:09:16 2013
@@ -72,70 +72,33 @@ ScopedInRtl::~ScopedInRtl() {
 }
 #endif
 
-static bool ishex(char c) {
-  return (c >= '0' && c <= '9')
-      || (c >= 'a' && c <= 'f');
-}
-
-static uptr readhex(const char *p) {
-  uptr v = 0;
-  for (; ishex(p[0]); p++) {
-    if (p[0] >= '0' && p[0] <= '9')
-      v = v * 16 + p[0] - '0';
-    else
-      v = v * 16 + p[0] - 'a' + 10;
-  }
-  return v;
-}
-
-static uptr readdec(const char *p) {
-  uptr v = 0;
-  for (; p[0] >= '0' && p[0] <= '9' ; p++)
-    v = v * 10 + p[0] - '0';
-  return v;
+void FillProfileCallback(uptr start, uptr rss, bool file,
+                         uptr *mem, uptr stats_size) {
+  CHECK_EQ(7, stats_size);
+  mem[6] += rss;  // total
+  start >>= 40;
+  if (start < 0x10)  // shadow
+    mem[0] += rss;
+  else if (start >= 0x20 && start < 0x30)  // compat modules
+    mem[file ? 1 : 2] += rss;
+  else if (start >= 0x7e)  // modules
+    mem[file ? 1 : 2] += rss;
+  else if (start >= 0x60 && start < 0x62)  // traces
+    mem[3] += rss;
+  else if (start >= 0x7d && start < 0x7e)  // heap
+    mem[4] += rss;
+  else  // other
+    mem[5] += rss;
 }
 
 void WriteMemoryProfile(char *buf, uptr buf_size) {
-  char *smaps = 0;
-  uptr smaps_cap = 0;
-  uptr smaps_len = ReadFileToBuffer("/proc/self/smaps",
-      &smaps, &smaps_cap, 64<<20);
-  uptr mem[6] = {};
-  uptr total = 0;
-  uptr start = 0;
-  bool file = false;
-  const char *pos = smaps;
-  while (pos < smaps + smaps_len) {
-    if (ishex(pos[0])) {
-      start = readhex(pos);
-      for (; *pos != '/' && *pos > '\n'; pos++) {}
-      file = *pos == '/';
-    } else if (internal_strncmp(pos, "Rss:", 4) == 0) {
-      for (; *pos < '0' || *pos > '9'; pos++) {}
-      uptr rss = readdec(pos) * 1024;
-      total += rss;
-      start >>= 40;
-      if (start < 0x10)  // shadow
-        mem[0] += rss;
-      else if (start >= 0x20 && start < 0x30)  // compat modules
-        mem[file ? 1 : 2] += rss;
-      else if (start >= 0x7e)  // modules
-        mem[file ? 1 : 2] += rss;
-      else if (start >= 0x60 && start < 0x62)  // traces
-        mem[3] += rss;
-      else if (start >= 0x7d && start < 0x7e)  // heap
-        mem[4] += rss;
-      else  // other
-        mem[5] += rss;
-    }
-    while (*pos++ != '\n') {}
-  }
-  UnmapOrDie(smaps, smaps_cap);
+  uptr mem[7] = {};
+  __sanitizer::GetMemoryProfile(FillProfileCallback, mem, 7);
   char *buf_pos = buf;
   char *buf_end = buf + buf_size;
   buf_pos += internal_snprintf(buf_pos, buf_end - buf_pos,
       "RSS %zd MB: shadow:%zd file:%zd mmap:%zd trace:%zd heap:%zd other:%zd\n",
-      total >> 20, mem[0] >> 20, mem[1] >> 20, mem[2] >> 20,
+      mem[6] >> 20, mem[0] >> 20, mem[1] >> 20, mem[2] >> 20,
       mem[3] >> 20, mem[4] >> 20, mem[5] >> 20);
   struct mallinfo mi = __libc_mallinfo();
   buf_pos += internal_snprintf(buf_pos, buf_end - buf_pos,





More information about the llvm-commits mailing list