[llvm-commits] [compiler-rt] r169076 - in /compiler-rt/trunk/lib/sanitizer_common: sanitizer_linux.cc sanitizer_mac.cc sanitizer_procmaps.h

Alexander Potapenko glider at google.com
Fri Nov 30 18:39:46 PST 2012


Author: glider
Date: Fri Nov 30 20:39:45 2012
New Revision: 169076

URL: http://llvm.org/viewvc/llvm-project?rev=169076&view=rev
Log:
Add caching to the MemoryMappingLayout class on Linux. This is necessary for the cases when a sandbox prevents ASan from reading the mappings
from /proc/self/maps.
The mappings are currently being cached on each access to /proc/self/maps. In the future we'll need to add an API that allows the client to notify ASan about the sandbox.


Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h

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=169076&r1=169075&r2=169076&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Fri Nov 30 20:39:45 2012
@@ -16,6 +16,7 @@
 #include "sanitizer_common.h"
 #include "sanitizer_internal_defs.h"
 #include "sanitizer_libc.h"
+#include "sanitizer_mutex.h"
 #include "sanitizer_placement_new.h"
 #include "sanitizer_procmaps.h"
 
@@ -217,13 +218,23 @@
 }
 
 // ----------------- sanitizer_procmaps.h
+char *MemoryMappingLayout::cached_proc_self_maps_buff_ = NULL;
+uptr MemoryMappingLayout::cached_proc_self_maps_buff_mmaped_size_ = 0;
+uptr MemoryMappingLayout::cached_proc_self_maps_buff_len_ = 0;
+StaticSpinMutex MemoryMappingLayout::cache_lock_;
+
 MemoryMappingLayout::MemoryMappingLayout() {
   proc_self_maps_buff_len_ =
       ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_,
                        &proc_self_maps_buff_mmaped_size_, 1 << 26);
-  CHECK_GT(proc_self_maps_buff_len_, 0);
+  if (proc_self_maps_buff_mmaped_size_ == 0) {
+    LoadFromCache();
+    CHECK_GT(proc_self_maps_buff_len_, 0);
+  }
   // internal_write(2, proc_self_maps_buff_, proc_self_maps_buff_len_);
   Reset();
+  // FIXME: in the future we may want to cache the mappings on demand only.
+  CacheMemoryMappings();
 }
 
 MemoryMappingLayout::~MemoryMappingLayout() {
@@ -234,6 +245,39 @@
   current_ = proc_self_maps_buff_;
 }
 
+// static
+void MemoryMappingLayout::CacheMemoryMappings() {
+  SpinMutexLock l(&cache_lock_);
+  // Don't invalidate the cache if the mappings are unavailable.
+  char *old_proc_self_maps_buff_ = cached_proc_self_maps_buff_;
+  uptr old_proc_self_maps_buff_mmaped_size_ =
+      cached_proc_self_maps_buff_mmaped_size_;
+  uptr old_proc_self_maps_buff_len_ = cached_proc_self_maps_buff_len_;
+  cached_proc_self_maps_buff_len_ =
+      ReadFileToBuffer("/proc/self/maps", &cached_proc_self_maps_buff_,
+                       &cached_proc_self_maps_buff_mmaped_size_, 1 << 26);
+  if (cached_proc_self_maps_buff_mmaped_size_ == 0) {
+    cached_proc_self_maps_buff_ = old_proc_self_maps_buff_;
+    cached_proc_self_maps_buff_mmaped_size_ =
+        old_proc_self_maps_buff_mmaped_size_;
+    cached_proc_self_maps_buff_len_ = old_proc_self_maps_buff_len_;
+  } else {
+    if (old_proc_self_maps_buff_mmaped_size_) {
+      UnmapOrDie(old_proc_self_maps_buff_,
+                 old_proc_self_maps_buff_mmaped_size_);
+    }
+  }
+}
+
+void MemoryMappingLayout::LoadFromCache() {
+  SpinMutexLock l(&cache_lock_);
+  if (cached_proc_self_maps_buff_) {
+    proc_self_maps_buff_ = cached_proc_self_maps_buff_;
+    proc_self_maps_buff_len_ = cached_proc_self_maps_buff_len_;
+    proc_self_maps_buff_mmaped_size_ = cached_proc_self_maps_buff_mmaped_size_;
+  }
+}
+
 // Parse a hex value in str and update str.
 static uptr ParseHex(char **str) {
   uptr x = 0;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=169076&r1=169075&r2=169076&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Fri Nov 30 20:39:45 2012
@@ -162,6 +162,15 @@
   current_filetype_ = 0;
 }
 
+// static
+void MemoryMappingLayout::CacheMemoryMappings() {
+  // No-op on Mac for now.
+}
+
+void MemoryMappingLayout::LoadFromCache() {
+  // No-op on Mac for now.
+}
+
 // Next and NextSegmentLoad were inspired by base/sysinfo.cc in
 // Google Perftools, http://code.google.com/p/google-perftools.
 

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=169076&r1=169075&r2=169076&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h Fri Nov 30 20:39:45 2012
@@ -15,6 +15,7 @@
 #define SANITIZER_PROCMAPS_H
 
 #include "sanitizer_internal_defs.h"
+#include "sanitizer_mutex.h"
 
 namespace __sanitizer {
 
@@ -39,9 +40,14 @@
   // address 'addr'. Returns true on success.
   bool GetObjectNameAndOffset(uptr addr, uptr *offset,
                               char filename[], uptr filename_size);
+  // In some cases, e.g. when running under a sandbox on Linux, ASan is unable
+  // to obtain the memory mappings. It should fall back to pre-cached data
+  // instead of aborting.
+  static void CacheMemoryMappings();
   ~MemoryMappingLayout();
 
  private:
+  void LoadFromCache();
   // Default implementation of GetObjectNameAndOffset.
   // Quite slow, because it iterates through the whole process map for each
   // lookup.
@@ -77,6 +83,12 @@
   uptr proc_self_maps_buff_mmaped_size_;
   uptr proc_self_maps_buff_len_;
   char *current_;
+
+  // Static mappings cache.
+  static char *cached_proc_self_maps_buff_;
+  static uptr cached_proc_self_maps_buff_mmaped_size_;
+  static uptr cached_proc_self_maps_buff_len_;
+  static StaticSpinMutex cache_lock_;  // protects the cache contents.
 # elif defined __APPLE__
   template<u32 kLCSegment, typename SegmentCommand>
   bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset,





More information about the llvm-commits mailing list