]> granicus.if.org Git - clang/commitdiff
[msan] -fsanitize-memory-track-origins=[level] flag and docs.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Thu, 20 Mar 2014 14:58:36 +0000 (14:58 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Thu, 20 Mar 2014 14:58:36 +0000 (14:58 +0000)
This change turns -fsanitize-memory-track-origins into
-fsanitize-memory-track-origins=[level] flag (keeping the old one for
compatibility). Possible levels are 0 (off), 1 (default) and 2 (incredibly
detailed). See docs (part of this patch) for more info.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204346 91177308-0d34-0410-b5e6-96231b3b80d8

docs/MemorySanitizer.rst
docs/UsersManual.rst
include/clang/Driver/Options.td
include/clang/Driver/SanitizerArgs.h
include/clang/Frontend/CodeGenOptions.def
lib/Driver/SanitizerArgs.cpp
lib/Frontend/CompilerInvocation.cpp
test/Driver/fsanitize.c

index f769cc9bf1be1c398ea034457da6df479f118238..9d6c22d8af085772f26715aa8dd34d1ef1ec74cc 100644 (file)
@@ -56,12 +56,10 @@ 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)
+    % ./a.out
+    WARNING: MemorySanitizer: use-of-uninitialized-value
         #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.
 
@@ -101,6 +99,13 @@ checks for certain source files and functions. All "Use of uninitialized value"
 warnings will be suppressed and all values loaded from memory will be
 considered fully initialized.
 
+Report symbolization
+====================
+
+MemorySanitizer uses an external symbolizer to print files and line numbers in
+reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
+or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
+
 Origin Tracking
 ===============
 
@@ -112,29 +117,59 @@ the example above,
 .. code-block:: console
 
     % clang -fsanitize=memory -fsanitize-memory-track-origins -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
+    % ./a.out
+    WARNING: MemorySanitizer: use-of-uninitialized-value
+        #0 0x7f7893912f0b in main umr2.cc:6
+        #1 0x7f789249b76c in __libc_start_main libc-start.c:226
+
+      Uninitialized value was created by a heap allocation
+        #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
+        #1 0x7f7893912e06 in main umr2.cc:4
+
+Origin tracking has proved to be very useful for debugging MemorySanitizer
 reports. It slows down program execution by a factor of 1.5x-2x on top
 of the usual MemorySanitizer slowdown.
 
+MemorySanitizer can provide even more information with
+``-fsanitize-memory-track-origins=2`` flag. In this mode reports
+include information about intermediate stores the uninitialized value went
+through.
+
+.. code-block:: console
+
+    % cat umr2.cc
+    #include <stdio.h>
+
+    int main(int argc, char** argv) {
+      int* a = new int[10];
+      a[5] = 0;
+      volatile int b = a[argc];
+      if (b)
+        printf("xx\n");
+      return 0;
+    }
+
+    % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc
+    % ./a.out
+    WARNING: MemorySanitizer: use-of-uninitialized-value
+        #0 0x7f7893912f0b in main umr2.cc:7
+        #1 0x7f789249b76c in __libc_start_main libc-start.c:226
+
+      Uninitialized value was stored to memory at
+        #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484
+        #1 0x7f7893912ecd in main umr2.cc:6
+
+      Uninitialized value was created by a heap allocation
+        #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
+        #1 0x7f7893912e06 in main umr2.cc:4
+
+
 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.
+Failing to achieve this may result in false reports.
 
 Full MemorySanitizer instrumentation is very difficult to achieve. To
 make it easier, MemorySanitizer runtime library includes 70+
index e58093831bf5165a8f9f4a9808a9145e3461b83f..43a8717c9be6594863297beb8ef3cabfc6882986 100644 (file)
@@ -968,12 +968,17 @@ are listed below.
    Extra features of MemorySanitizer (require explicit
    ``-fsanitize=memory``):
 
-   -  ``-fsanitize-memory-track-origins``: Enables origin tracking in
+   -  ``-fsanitize-memory-track-origins[=level]``: Enables origin tracking in
       MemorySanitizer. Adds a second section to MemorySanitizer
       reports pointing to the heap or stack allocation the
       uninitialized bits came from. Slows down execution by additional
       1.5x-2x.
 
+      Possible values for level are 0 (off), 1 (default), 2. Level 2 adds more
+      sections to MemorySanitizer reports describing the order of memory stores
+      the uninitialized value went through. Beware, this mode may use a lot of
+      extra memory.
+
    Extra features of UndefinedBehaviorSanitizer:
 
    -  ``-fno-sanitize-recover``: By default, after a sanitizer diagnoses
index 84a863ca554bfacee4a038f80e71eb8c3732120d..b3afd7a0b8eb49c776704653a16b44219944cc44 100644 (file)
@@ -485,11 +485,15 @@ def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
 def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
                              Group<f_clang_Group>,
                              HelpText<"Don't use blacklist file for sanitizers">;
+def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
+                                        Group<f_clang_Group>, Flags<[CC1Option]>,
+                                        HelpText<"Enable origins tracking in MemorySanitizer">;
 def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins">,
                                      Group<f_clang_Group>, Flags<[CC1Option]>,
                                      HelpText<"Enable origins tracking in MemorySanitizer">;
 def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
-                                        Group<f_clang_Group>;
+                                        Group<f_clang_Group>, Flags<[CC1Option]>,
+                                        HelpText<"Disable origins tracking in MemorySanitizer">;
 def fsanitize_recover : Flag<["-"], "fsanitize-recover">,
                         Group<f_clang_Group>;
 def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
index d12e5faf4e6557ee84d95813b2baba27596ae476..2080e1c468e7922b83f2c5855156ab7b57135f1a 100644 (file)
@@ -48,7 +48,7 @@ class SanitizerArgs {
   unsigned Kind;
 
   std::string BlacklistFile;
-  bool MsanTrackOrigins;
+  int MsanTrackOrigins;
   bool AsanZeroBaseShadow;
   bool UbsanTrapOnError;
 
index 400591a08ac23f2538a0b21abd8892a8683d7937..9c9847314dc26ca173642c6bb8bbb0d76c6176fb 100644 (file)
@@ -98,7 +98,7 @@ CODEGENOPT(StructPathTBAA    , 1, 0) ///< Whether or not to use struct-path TBAA
 CODEGENOPT(SaveTempLabels    , 1, 0) ///< Save temporary labels.
 CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
                                                  ///< offset in AddressSanitizer.
-CODEGENOPT(SanitizeMemoryTrackOrigins, 1, 0) ///< Enable tracking origins in
+CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
                                              ///< MemorySanitizer
 CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
                                                /// -fsanitize-undefined-trap-on-error
index a4b32df9e374f2ec50121084887dfb264d159261..d66f3b4a0137ac4b48b54de75bdc34cbfdaf2edb 100644 (file)
@@ -11,6 +11,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -23,7 +24,7 @@ using namespace llvm::opt;
 void SanitizerArgs::clear() {
   Kind = 0;
   BlacklistFile = "";
-  MsanTrackOrigins = false;
+  MsanTrackOrigins = 0;
   AsanZeroBaseShadow = false;
   UbsanTrapOnError = false;
 }
@@ -146,12 +147,27 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
       BlacklistFile = BLPath;
   }
 
-  // Parse -f(no-)sanitize-memory-track-origins options.
-  if (NeedsMsan)
-    MsanTrackOrigins =
-      Args.hasFlag(options::OPT_fsanitize_memory_track_origins,
-                   options::OPT_fno_sanitize_memory_track_origins,
-                   /* Default */false);
+  // Parse -f[no-]sanitize-memory-track-origins[=level] options.
+  if (NeedsMsan) {
+    if (Arg *A =
+            Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
+                            options::OPT_fsanitize_memory_track_origins,
+                            options::OPT_fno_sanitize_memory_track_origins)) {
+      if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
+        MsanTrackOrigins = 1;
+      } else if (A->getOption().matches(
+                     options::OPT_fno_sanitize_memory_track_origins)) {
+        MsanTrackOrigins = 0;
+      } else {
+        StringRef S = A->getValue();
+        if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
+            MsanTrackOrigins > 2) {
+          D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+        }
+      }
+    }
+  }
+
   if (NeedsAsan)
     AsanZeroBaseShadow =
         (TC.getTriple().getEnvironment() == llvm::Triple::Android);
@@ -175,7 +191,8 @@ void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
   }
 
   if (MsanTrackOrigins)
-    CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
+    CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
+                                         llvm::utostr(MsanTrackOrigins)));
 
   // Workaround for PR16386.
   if (needsMsanRt())
index 79d81511c3779443d367c289759ee18d2780a1be..f31c8c09336b52b8e42413a27895281c2fbdf10b 100644 (file)
@@ -451,9 +451,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
   Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
   Opts.SanitizeMemoryTrackOrigins =
-    Args.hasArg(OPT_fsanitize_memory_track_origins);
+      getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
   Opts.SanitizeUndefinedTrapOnError =
-    Args.hasArg(OPT_fsanitize_undefined_trap_on_error);
+      Args.hasArg(OPT_fsanitize_undefined_trap_on_error);
   Opts.SSPBufferSize =
       getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags);
   Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
index eebcc1b81f09ba6e3b843a02b3fc1998fb065e9e..aa9dfa22bbe076b2d0a85c1535048704b14e394e 100644 (file)
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -pie %s -### 2>&1
 // OK
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -pie %s -### 2>&1
-// OK
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=1 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fno-sanitize-memory-track-origins -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=0 -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+
+// CHECK-TRACK-ORIGINS-1: -fsanitize-memory-track-origins=1
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fno-sanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=0 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -fno-sanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-memory-track-origins=0 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-sanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-memory-track-origins=0 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// CHECK-NO-TRACK-ORIGINS-NOT: sanitize-memory-track-origins
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-2
+// CHECK-TRACK-ORIGINS-2: -fsanitize-memory-track-origins=2
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=3 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-3
+// CHECK-TRACK-ORIGINS-3: error: invalid value '3' in '-fsanitize-memory-track-origins=3'
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr -fno-sanitize=vptr -fsanitize=undefined,address %s -### 2>&1
 // OK