summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-03-20 14:58:36 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-03-20 14:58:36 +0000
commit2bfcaabdec0cac95ed118958e759652e3cc55cde (patch)
tree7577a5a609f8845c883cb7337c44feb7ecdbdb74 /clang
parentd8de5b68681a06a45aace49892f45a015f5ee2ba (diff)
downloadbcm5719-llvm-2bfcaabdec0cac95ed118958e759652e3cc55cde.tar.gz
bcm5719-llvm-2bfcaabdec0cac95ed118958e759652e3cc55cde.zip
[msan] -fsanitize-memory-track-origins=[level] flag and docs.
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. llvm-svn: 204346
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/MemorySanitizer.rst73
-rw-r--r--clang/docs/UsersManual.rst7
-rw-r--r--clang/include/clang/Driver/Options.td6
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h2
-rw-r--r--clang/include/clang/Frontend/CodeGenOptions.def2
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp33
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp4
-rw-r--r--clang/test/Driver/fsanitize.c23
8 files changed, 115 insertions, 35 deletions
diff --git a/clang/docs/MemorySanitizer.rst b/clang/docs/MemorySanitizer.rst
index f769cc9bf1b..9d6c22d8af0 100644
--- a/clang/docs/MemorySanitizer.rst
+++ b/clang/docs/MemorySanitizer.rst
@@ -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+
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index e58093831bf..43a8717c9be 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -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
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 84a863ca554..b3afd7a0b8e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -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">,
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index d12e5faf4e6..2080e1c468e 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -48,7 +48,7 @@ class SanitizerArgs {
unsigned Kind;
std::string BlacklistFile;
- bool MsanTrackOrigins;
+ int MsanTrackOrigins;
bool AsanZeroBaseShadow;
bool UbsanTrapOnError;
diff --git a/clang/include/clang/Frontend/CodeGenOptions.def b/clang/include/clang/Frontend/CodeGenOptions.def
index 400591a08ac..9c9847314dc 100644
--- a/clang/include/clang/Frontend/CodeGenOptions.def
+++ b/clang/include/clang/Frontend/CodeGenOptions.def
@@ -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
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index a4b32df9e37..d66f3b4a013 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -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())
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 79d81511c37..f31c8c09336 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -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);
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index eebcc1b81f0..aa9dfa22bbe 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -76,8 +76,27 @@
// 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
OpenPOWER on IntegriCloud