about summary refs log tree commit diff homepage
path: root/lib
diff options
context:
space:
mode:
authorDan Liew <daniel.liew@imperial.ac.uk>2016-11-18 21:42:57 +0000
committerDan Liew <daniel.liew@imperial.ac.uk>2017-01-19 10:55:58 +0000
commit1ffda389d8d20c212884b8a669ebb4cb24f1fa01 (patch)
treec7602e6408f16163cad0d0611cbc302ed64c40e5 /lib
parentde7e2b94a5f9ee05496e6a65e7370d7270b38799 (diff)
downloadklee-1ffda389d8d20c212884b8a669ebb4cb24f1fa01.tar.gz
Fix `Feature/MemoryLimit.c` test when building KLEE with ASan.
When building with ASan the `mallinfo()` function is intercepted.
However the currently implementation is just a stub that always
returns 0. So instead use the public API of the sanitizer runtime
to get the amount of currently allocated memory when KLEE is built
with ASan.

Unfortunately it appears that the way to detect building with ASan
differs between Clang and GCC. There was also a sanitizer runtime
API change too.

This was tested with

* Clang 3.4, 3.5, and 3.9.0
* GCC 4.8, 4.9, 5.2, 5.4 and, 6.2.1.
Diffstat (limited to 'lib')
-rw-r--r--lib/Support/MemoryUsage.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/Support/MemoryUsage.cpp b/lib/Support/MemoryUsage.cpp
index d141593a..f1757ad3 100644
--- a/lib/Support/MemoryUsage.cpp
+++ b/lib/Support/MemoryUsage.cpp
@@ -22,9 +22,74 @@
 #include <malloc/malloc.h>
 #endif
 
+// ASan Support
+//
+// When building with ASan the `mallinfo()` function is intercepted and always
+// reports zero so we can't use that to report KLEE's memory usage. Instead we
+// will use ASan's public interface to query how much memory has been
+// allocated.
+//
+// Unfortunately the interface is dependent on the compiler version. It is also
+// unfortunate that the way to detect compilation with ASan differs between
+// compilers. The preprocessor code below tries to determine if ASan is enabled
+// and if so which interface should be used.
+//
+// If ASan is enabled the `KLEE_ASAN_BUILD` macro will be defined other it will
+// be undefined. If `KLEE_ASAN_BUILD` is defined then the
+// `ASAN_GET_ALLOCATED_MEM_FUNCTION` macro will defined to the name of the ASan
+// function that can be called to get memory allocation
+
+// Make sure we start with the macro being undefined.
+#undef KLEE_ASAN_BUILD
+
+// Clang and ASan
+#if defined(__has_feature)
+#  if __has_feature(address_sanitizer)
+#     if __has_include("sanitizer/allocator_interface.h")
+#       include <sanitizer/allocator_interface.h>
+        // Modern interface
+#       define ASAN_GET_ALLOCATED_MEM_FUNCTION __sanitizer_get_current_allocated_bytes
+#     else
+#       include <sanitizer/asan_interface.h>
+        // Deprecated interface.
+#       define ASAN_GET_ALLOCATED_MEM_FUNCTION __asan_get_current_allocated_bytes
+#     endif /* has_include("sanitizer/allocator_interface.h") */
+#    define KLEE_ASAN_BUILD
+#  endif /* __has_feature(address_sanitizer) */
+#endif /* defined(__has_feature) */
+
+// For GCC and ASan
+#ifndef KLEE_ASAN_BUILD
+#  if defined(__SANITIZE_ADDRESS__)
+     // HACK: GCC doesn't ship `allocator_interface.h`  or `asan_interface.h` so
+     // just provide the proto-types here.
+     extern "C" {
+       size_t __sanitizer_get_current_allocated_bytes();
+       size_t __asan_get_current_allocated_bytes(); // Deprecated.
+     }
+     // HACK: Guess which function to use based on GCC version
+#    if __GNUC__ > 4
+       // Tested with gcc 5.2, 5.4, and 6.2.1
+       // Modern interface
+#      define ASAN_GET_ALLOCATED_MEM_FUNCTION __sanitizer_get_current_allocated_bytes
+#    else
+       // Tested with gcc 4.8 and 4.9
+       // Deprecated interface
+#      define ASAN_GET_ALLOCATED_MEM_FUNCTION __asan_get_current_allocated_bytes
+#    endif
+#    define KLEE_ASAN_BUILD
+#  endif /* defined(__SANITIZE_ADDRESS__) */
+#endif /* ndef KLEE_ASAN_BUILD */
+
 using namespace klee;
 
 size_t util::GetTotalMallocUsage() {
+#ifdef KLEE_ASAN_BUILD
+  // When building with ASan on Linux `mallinfo()` just returns 0 so use ASan runtime
+  // function instead to get used memory.
+  return ASAN_GET_ALLOCATED_MEM_FUNCTION();
+#endif
+
 #ifdef HAVE_GPERFTOOLS_MALLOC_EXTENSION_H
   size_t value = 0;
   MallocExtension::instance()->GetNumericProperty(