From cc603e99b5ebdd437616ca8bf66711fe79ae839a Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov <eugeni.stepanov@gmail.com> Date: Fri, 21 Dec 2012 10:50:00 +0000 Subject: [PATCH] User manual chapter on MemorySanitizer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170879 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/MemorySanitizer.rst | 164 +++++++++++++++++++++++++++++++++++++++ docs/UsersManual.rst | 13 ++++ 2 files changed, 177 insertions(+) create mode 100644 docs/MemorySanitizer.rst diff --git a/docs/MemorySanitizer.rst b/docs/MemorySanitizer.rst new file mode 100644 index 00000000000..7bf21367915 --- /dev/null +++ b/docs/MemorySanitizer.rst @@ -0,0 +1,164 @@ +================ +MemorySanitizer +================ + +.. contents:: + :local: + +Introduction +============ + +MemorySanitizer is a detector of uninitialized reads. It consists of a +compiler instrumentation module and a run-time library. + +Typical slowdown introduced by MemorySanitizer is **3x**. + +How to build +============ + +Follow the `clang build instructions <../get_started.html>`_. CMake +build is supported. + +Usage +===== + +Simply compile and link your program with ``-fsanitize=memory`` flag. +The MemorySanitizer run-time library should be linked to the final +executable, so make sure to use ``clang`` (not ``ld``) for the final +link step. When linking shared libraries, the MemorySanitizer run-time +is not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it +with MemorySanitizer). To get a reasonable performance add ``-O1`` or +higher. To get meaninful stack traces in error messages add +``-fno-omit-frame-pointer``. To get perfect stack traces you may need +to disable inlining (just use ``-O1``) and tail call elimination +(``-fno-optimize-sibling-calls``). + +.. code-block:: console + % cat umr.cc + #include <stdio.h> + + int main(int argc, char** argv) { + int* a = new int[10]; + a[5] = 0; + if (a[argc]) + printf("xx\n"); + return 0; + } + + % clang -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer -g -O2 umr.cc + +If a bug is detected, the program will print an error message to +stderr and exit with a non-zero exit code. Currently, MemorySanitizer +does not symbolize its output by default, so you may need to use a +separate script to symbolize the result offline (this will be fixed in +future). + +.. code-block:: console + + % ./a.out 2>log + % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt + ==30106== WARNING: MemorySanitizer: UMR (uninitialized-memory-read) + #0 0x7f45944b418a in main umr.cc:6 + #1 0x7f45938b676c in __libc_start_main libc-start.c:226 + Exiting + +By default, MemorySanitizer exits on the first detected error. + +``__has_feature(memory_sanitizer)`` +------------------------------------ + +In some cases one may need to execute different code depending on +whether MemorySanitizer is enabled. :ref:`\_\_has\_feature +<langext-__has_feature-__has_extension>` can be used for this purpose. + +.. code-block:: c + + #if defined(__has_feature) + # if __has_feature(memory_sanitizer) + // code that builds only under MemorySanitizer + # endif + #endif + +Origin Tracking +=============== + +MemorySanitizer can track origins of unitialized values, similar to +Valgrind's --track-origins option. This feature is enabled by +``-fsanitize-memory-track-origins`` Clang option. With the code from +the example above, + +.. code-block:: console + + % clang -fsanitize=memory -fsanitize-memory-track-origins -fPIE -pie -fno-omit-frame-pointer -g -O2 umr.cc + % ./a.out 2>log + % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt + ==14425== WARNING: MemorySanitizer: UMR (uninitialized-memory-read) + ==14425== WARNING: Trying to symbolize code, but external symbolizer is not initialized! + #0 0x7f8bdda3824b in main umr.cc:6 + #1 0x7f8bdce3a76c in __libc_start_main libc-start.c:226 + raw origin id: 2030043137 + ORIGIN: heap allocation: + #0 0x7f8bdda4034b in operator new[](unsigned long) msan_new_delete.cc:39 + #1 0x7f8bdda3814d in main umr.cc:4 + #2 0x7f8bdce3a76c in __libc_start_main libc-start.c:226 + Exiting + +Origin tracking has proved to be very useful for debugging UMR +reports. It slows down program execution by a factor of 1.5x-2x on top +of the usual MemorySanitizer slowdown. + +Handling external code +============================ + +MemorySanitizer requires that all program code is instrumented. This +also includes any libraries that the program depends on, even libc. +Failing to achieve this may result in false UMR reports. + +Full MemorySanitizer instrumentation is very difficult to achieve. To +make it easier, MemorySanitizer runtime library includes 70+ +interceptors for the most common libc functions. They make it possible +to run MemorySanitizer-instrumented programs linked with +uninstrumented libc. For example, the authors were able to bootstrap +MemorySanitizer-instrumented Clang compiler by linking it with +self-built instrumented libcxx (as a replacement for libstdc++). + +In the case when rebuilding all program dependencies with +MemorySanitizer is problematic, an experimental MSanDR tool can be +used. It is a DynamoRio-based tool that uses dynamic instrumentation +to avoid false positives due to uninstrumented code. The tool simply +marks memory from instrumented libraries as fully initialized. See +`http://code.google.com/p/memory-sanitizer/wiki/Running#Running_with_the_dynamic_tool` +for more information. + +Supported Platforms +=================== + +MemorySanitizer is supported on + +* Linux x86\_64 (tested on Ubuntu 10.04 and 12.04); + +Limitations +=========== + +* MemorySanitizer uses 2x more real memory than a native run, 3x with + origin tracking. +* MemorySanitizer maps (but not reserves) 64 Terabytes of virtual + address space. This means that tools like ``ulimit`` may not work as + usually expected. +* Static linking is not supported. +* Non-position-independent executables are not supported. +* Depending on the version of Linux kernel, running without ASLR may + be not supported. Note that GDB disables ASLR by default. To debug + instrumented programs, use "set disable-randomization off". + +Current Status +============== + +MemorySanitizer is an experimental tool. It is known to work on large +real-world programs, like Clang/LLVM itself. + +More Information +================ + +`http://code.google.com/p/memory-sanitizer <http://code.google.com/p/memory-sanitizer/>`_ + diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst index f92eb9c5bc2..4d6c4e90559 100644 --- a/docs/UsersManual.rst +++ b/docs/UsersManual.rst @@ -855,6 +855,11 @@ are listed below. - .. _opt_fsanitize_thread: ``-fsanitize=thread``: :doc:`ThreadSanitizer`, a data race detector. + - .. _opt_fsanitize_memory: + + ``-fsanitize=memory``: :doc:`MemorySanitizer`, + an *experimental* detector of uninitialized reads. Not ready for + widespread use. - .. _opt_fsanitize_undefined: ``-fsanitize=undefined``: Fast and compatible undefined behavior @@ -917,6 +922,14 @@ are listed below. - ``-fsanitize=use-after-scope``: Check for use-after-scope errors (accesing local variable after it went out of scope). + Extra features of MemorySanitizer (require explicit + ``-fsanitize=memory``): + + - ``-fsanitize-memory-track-origins``: Enables origin tracking in + MemorySanitizer. Adds a second stack trace to MemorySanitizer + reports pointing to the allocation the uninitialized bits came + from. Slows down execution by additional 1.5x-2x. + The ``-fsanitize=`` argument must also be provided when linking, in order to link to the appropriate runtime library. It is not possible to combine the ``-fsanitize=address`` and ``-fsanitize=thread`` -- GitLab