[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
This commit is contained in:
parent
d8de5b6868
commit
2bfcaabdec
|
@ -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
|
||||
% ./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
|
||||
|
||||
Origin tracking has proved to be very useful for debugging UMR
|
||||
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+
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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">,
|
||||
|
|
|
@ -48,7 +48,7 @@ class SanitizerArgs {
|
|||
unsigned Kind;
|
||||
|
||||
std::string BlacklistFile;
|
||||
bool MsanTrackOrigins;
|
||||
int MsanTrackOrigins;
|
||||
bool AsanZeroBaseShadow;
|
||||
bool UbsanTrapOnError;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue