From 1ffda389d8d20c212884b8a669ebb4cb24f1fa01 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 18 Nov 2016 21:42:57 +0000 Subject: 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. --- lib/Support/MemoryUsage.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'lib/Support') 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 #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 + // Modern interface +# define ASAN_GET_ALLOCATED_MEM_FUNCTION __sanitizer_get_current_allocated_bytes +# else +# include + // 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( -- cgit 1.4.1