[llvm-commits] [compiler-rt] r147581 - in /compiler-rt/trunk/lib/asan: Makefile.old asan_internal.h asan_linux.cc asan_printf.cc asan_rtl.cc asan_stack.cc asan_thread.cc

Kostya Serebryany kcc at google.com
Wed Jan 4 16:44:34 PST 2012


Author: kcc
Date: Wed Jan  4 18:44:33 2012
New Revision: 147581

URL: http://llvm.org/viewvc/llvm-project?rev=147581&view=rev
Log:
[asan] implement our own /proc/self/maps reader and use it on linux instead of sysinfo.h

Modified:
    compiler-rt/trunk/lib/asan/Makefile.old
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_printf.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/asan_stack.cc
    compiler-rt/trunk/lib/asan/asan_thread.cc

Modified: compiler-rt/trunk/lib/asan/Makefile.old
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/Makefile.old?rev=147581&r1=147580&r2=147581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/Makefile.old (original)
+++ compiler-rt/trunk/lib/asan/Makefile.old Wed Jan  4 18:44:33 2012
@@ -264,7 +264,6 @@
 $(BIN)/%$(SUFF).o: %.cc $(RTL_HDR) $(MAKEFILE)
 	$(CXX) $(PIE) $(CFLAGS) -fPIC -c -O2 -fno-exceptions -funwind-tables \
 		-o $@ -g $< -Ithird_party \
-		-DASAN_USE_SYSINFO=1 \
 		-DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \
 		-DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \
 		-DASAN_FLEXIBLE_MAPPING_AND_OFFSET=$(ASAN_FLEXIBLE_MAPPING_AND_OFFSET) \
@@ -272,7 +271,6 @@
 
 $(BIN)/%$(SUFF).o: %.c $(RTL_HDR) $(MAKEFILE)
 	$(CC) $(PIE) $(CFLAGS) -fPIC -c -O2 -o $@ -g $< -Ithird_party \
-		-DASAN_USE_SYSINFO=1 \
 		$(ASAN_FLAGS)
 
 ifeq ($(OS),darwin)

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=147581&r1=147580&r2=147581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Wed Jan  4 18:44:33 2012
@@ -45,8 +45,12 @@
 
 // If set, sysinfo/sysinfo.h will be used to iterate over /proc/maps.
 #ifndef ASAN_USE_SYSINFO
+#ifdef __linux__
+# define ASAN_USE_SYSINFO 0
+#else
 # define ASAN_USE_SYSINFO 1
 #endif
+#endif
 
 // If set, asan will install its own SEGV signal handler.
 #ifndef ASAN_NEEDS_SEGV
@@ -99,10 +103,18 @@
 ssize_t AsanWrite(int fd, const void *buf, size_t count);
 int AsanClose(int fd);
 
+// Opens the file 'file_name" and reads up to 'max_len' bytes.
+// The resulting buffer is mmaped and stored in '*buff'.
+// The size of the mmaped region is stored in '*buff_size',
+// Returns the number of read bytes or -1 if file can not be opened.
+ssize_t ReadFileToBuffer(const char *file_name, char **buff,
+                         size_t *buff_size, size_t max_len);
+
 // asan_printf.cc
 void RawWrite(const char *buffer);
 int SNPrint(char *buffer, size_t length, const char *format, ...);
 void Printf(const char *format, ...);
+int SScanf(const char *str, const char *format, ...);
 void Report(const char *format, ...);
 
 // Don't use std::min and std::max, to minimize dependency on libstdc++.

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=147581&r1=147580&r2=147581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Wed Jan  4 18:44:33 2012
@@ -13,12 +13,15 @@
 //===----------------------------------------------------------------------===//
 #ifdef __linux__
 
+#include "asan_interceptors.h"
 #include "asan_internal.h"
+#include "asan_procmaps.h"
 
 #include <sys/mman.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <stdio.h>
 #include <unistd.h>
 
 extern char _DYNAMIC[];
@@ -96,6 +99,57 @@
   return close(fd);
 }
 
+AsanProcMaps::AsanProcMaps() {
+  proc_self_maps_buff_len_ =
+      ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_,
+                       &proc_self_maps_buff_mmaped_size_, 1 << 20);
+  CHECK(proc_self_maps_buff_len_ > 0);
+  // AsanWrite(2, proc_self_maps_buff_, proc_self_maps_buff_len_);
+  Reset();
+}
+
+AsanProcMaps::~AsanProcMaps() {
+  AsanUnmapOrDie(proc_self_maps_buff_, proc_self_maps_buff_mmaped_size_);
+}
+
+void AsanProcMaps::Reset() {
+  current_ = proc_self_maps_buff_;
+}
+
+bool AsanProcMaps::Next(uint64_t *start, uint64_t *end,
+                        uint64_t *offset, char filename[],
+                        size_t filename_size) {
+  char *last = proc_self_maps_buff_ + proc_self_maps_buff_len_;
+  if (current_ >= last) return false;
+  int consumed = 0;
+  char flags[10];
+  int major, minor;
+  uint64_t inode;
+  char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
+  if (next_line == NULL)
+    next_line = last;
+  if (SScanf(current_,
+             "%llx-%llx %4s %llx %x:%x %lld %n",
+             start, end, flags, offset, &major, &minor,
+             &inode, &consumed) != 7)
+    return false;
+  current_ += consumed;
+  // Skip spaces.
+  while (current_ < next_line && *current_ == ' ')
+    current_++;
+  // Fill in the filename.
+  size_t i = 0;
+  while (current_ < next_line) {
+    if (filename && i < filename_size - 1)
+      filename[i++] = *current_;
+    current_++;
+  }
+  if (filename && i < filename_size)
+    filename[i] = 0;
+  current_ = next_line + 1;
+  return true;
+}
+
 }  // namespace __asan
 
 #endif  // __linux__

Modified: compiler-rt/trunk/lib/asan/asan_printf.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_printf.cc?rev=147581&r1=147580&r2=147581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_printf.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_printf.cc Wed Jan  4 18:44:33 2012
@@ -18,6 +18,7 @@
 #include "asan_interceptors.h"
 
 #include <stdarg.h>
+#include <stdio.h>
 
 namespace __asan {
 
@@ -178,4 +179,12 @@
   RawWrite(buffer);
 }
 
+int SScanf(const char *str, const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  int res = vsscanf(str, format, args);
+  va_end(args);
+  return res;
+}
+
 }  // namespace __asan

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=147581&r1=147580&r2=147581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed Jan  4 18:44:33 2012
@@ -18,6 +18,7 @@
 #include "asan_lock.h"
 #include "asan_mac.h"
 #include "asan_mapping.h"
+#include "asan_procmaps.h"
 #include "asan_stack.h"
 #include "asan_stats.h"
 #include "asan_thread.h"
@@ -119,22 +120,19 @@
   Printf("\n");
 }
 
-// Opens the file 'file_name" and reads up to 'max_len' bytes.
-// The resulting buffer is mmaped and stored in '*buff'.
-// Returns the number of read bytes or -1 if file can not be opened.
-static ssize_t ReadFileToBuffer(const char *file_name, char **buff,
-                                size_t max_len) {
+ssize_t ReadFileToBuffer(const char *file_name, char **buff,
+                         size_t *buff_size, size_t max_len) {
   const size_t kMinFileLen = kPageSize;
   ssize_t read_len = -1;
   *buff = 0;
-  size_t maped_size = 0;
+  *buff_size = 0;
   // The files we usually open are not seekable, so try different buffer sizes.
   for (size_t size = kMinFileLen; size <= max_len; size *= 2) {
     int fd = AsanOpenReadonly(file_name);
     if (fd < 0) return -1;
-    AsanUnmapOrDie(*buff, maped_size);
-    maped_size = size;
+    AsanUnmapOrDie(*buff, *buff_size);
     *buff = (char*)AsanMmapSomewhereOrDie(size, __FUNCTION__);
+    *buff_size = size;
     read_len = AsanRead(fd, *buff, size);
     AsanClose(fd);
     if (read_len < size)  // We've read the whole file.
@@ -151,7 +149,9 @@
   static bool inited;
   if (!inited) {
     inited = true;
-    len = ReadFileToBuffer("/proc/self/environ", &environ, 1 << 20);
+    size_t environ_size;
+    len = ReadFileToBuffer("/proc/self/environ",
+                           &environ, &environ_size, 1 << 20);
   }
   if (!environ || len <= 0) return NULL;
   size_t namelen = internal_strlen(name);

Modified: compiler-rt/trunk/lib/asan/asan_stack.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stack.cc?rev=147581&r1=147580&r2=147581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_stack.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_stack.cc Wed Jan  4 18:44:33 2012
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 #include "asan_interceptors.h"
 #include "asan_lock.h"
+#include "asan_procmaps.h"
 #include "asan_stack.h"
 #include "asan_thread.h"
 #include "asan_thread_registry.h"
@@ -128,9 +129,27 @@
 
 #else  // ASAN_USE_SYSINFO
 void AsanStackTrace::PrintStack(uintptr_t *addr, size_t size) {
+  AsanProcMaps proc_maps;
   for (size_t i = 0; i < size && addr[i]; i++) {
+    proc_maps.Reset();
     uintptr_t pc = addr[i];
-    Printf("  #%ld 0x%lx\n", i, pc);
+    uint64_t start, end, offset;
+    char filename[4096];
+    bool found = 0;
+    int map_idx = 0;
+    while (proc_maps.Next(&start, &end, &offset,
+                          filename, sizeof(filename))) {
+      if (pc >= start && pc <= end) {
+        found = true;
+        uintptr_t relative_pc = (map_idx == 0) ? pc : (pc - start);
+        Printf("    #%ld 0x%lx (%s+0x%lx)\n", i, pc, filename, relative_pc);
+        break;
+      }
+      map_idx++;
+    }
+    if (!found) {
+      Printf("    #%ld 0x%lx\n", i, pc);
+    }
   }
 }
 #endif  // ASAN_USE_SYSINFO

Modified: compiler-rt/trunk/lib/asan/asan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.cc?rev=147581&r1=147580&r2=147581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.cc Wed Jan  4 18:44:33 2012
@@ -13,14 +13,11 @@
 //===----------------------------------------------------------------------===//
 #include "asan_allocator.h"
 #include "asan_interceptors.h"
+#include "asan_procmaps.h"
 #include "asan_thread.h"
 #include "asan_thread_registry.h"
 #include "asan_mapping.h"
 
-#if ASAN_USE_SYSINFO == 1
-#include "sysinfo/sysinfo.h"
-#endif
-
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <pthread.h>
@@ -126,17 +123,16 @@
   int local;
   CHECK(AddrIsInStack((uintptr_t)&local));
 #else
-#if ASAN_USE_SYSINFO == 1
   if (tid() == 0) {
     // This is the main thread. Libpthread may not be initialized yet.
     struct rlimit rl;
     CHECK(getrlimit(RLIMIT_STACK, &rl) == 0);
 
     // Find the mapping that contains a stack variable.
-    ProcMapsIterator it(0);
-    uint64_t start, end;
+    AsanProcMaps proc_maps;
+    uint64_t start, end, offset;
     uint64_t prev_end = 0;
-    while (it.Next(&start, &end, NULL, NULL, NULL, NULL)) {
+    while (proc_maps.Next(&start, &end, &offset, NULL, 0)) {
       if ((uintptr_t)&rl < end)
         break;
       prev_end = end;
@@ -155,7 +151,6 @@
     CHECK(AddrIsInStack((uintptr_t)&rl));
     return;
   }
-#endif
   pthread_attr_t attr;
   CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
   size_t stacksize = 0;





More information about the llvm-commits mailing list