forked from OSchip/llvm-project
[Sanitizer] Use COMMON_FLAG macro to describe common runtime flags.
Summary: Introduce a single place where we specify flag type, name, default value, and description. This removes a large amount of boilerplate and ensures we won't leave flags uninitialized. Test Plan: regression test suite Reviewers: kcc Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D6851 llvm-svn: 225239
This commit is contained in:
parent
a872f3f676
commit
bdbdd3fd4e
|
@ -64,6 +64,7 @@ set(SANITIZER_HEADERS
|
|||
sanitizer_deadlock_detector.h
|
||||
sanitizer_deadlock_detector_interface.h
|
||||
sanitizer_flags.h
|
||||
sanitizer_flags.inc
|
||||
sanitizer_internal_defs.h
|
||||
sanitizer_lfstack.h
|
||||
sanitizer_libc.h
|
||||
|
|
|
@ -35,153 +35,16 @@ IntrusiveList<FlagDescription> flag_descriptions;
|
|||
#endif
|
||||
|
||||
void CommonFlags::SetDefaults() {
|
||||
symbolize = true;
|
||||
external_symbolizer_path = 0;
|
||||
allow_addr2line = false;
|
||||
strip_path_prefix = "";
|
||||
fast_unwind_on_check = false;
|
||||
fast_unwind_on_fatal = false;
|
||||
fast_unwind_on_malloc = true;
|
||||
handle_ioctl = false;
|
||||
malloc_context_size = 1;
|
||||
log_path = "stderr";
|
||||
verbosity = 0;
|
||||
detect_leaks = true;
|
||||
leak_check_at_exit = true;
|
||||
allocator_may_return_null = false;
|
||||
print_summary = true;
|
||||
check_printf = true;
|
||||
mmap_limit_mb = 0;
|
||||
hard_rss_limit_mb = 0;
|
||||
// TODO(glider): tools may want to set different defaults for handle_segv.
|
||||
handle_segv = SANITIZER_NEEDS_SEGV;
|
||||
allow_user_segv_handler = false;
|
||||
use_sigaltstack = true;
|
||||
detect_deadlocks = false;
|
||||
clear_shadow_mmap_threshold = 64 * 1024;
|
||||
color = "auto";
|
||||
legacy_pthread_cond = false;
|
||||
intercept_tls_get_addr = false;
|
||||
coverage = false;
|
||||
coverage_pcs = true; // On by default, but works only if coverage==true.
|
||||
coverage_bitset = false;
|
||||
coverage_direct = SANITIZER_ANDROID;
|
||||
coverage_dir = ".";
|
||||
full_address_space = false;
|
||||
suppressions = "";
|
||||
print_suppressions = true;
|
||||
disable_coredump = (SANITIZER_WORDSIZE == 64);
|
||||
symbolize_inline_frames = true;
|
||||
stack_trace_format = "DEFAULT";
|
||||
#define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
|
||||
#include "sanitizer_flags.inc"
|
||||
#undef COMMON_FLAG
|
||||
}
|
||||
|
||||
void CommonFlags::ParseFromString(const char *str) {
|
||||
ParseFlag(str, &symbolize, "symbolize",
|
||||
"If set, use the online symbolizer from common sanitizer runtime to turn "
|
||||
"virtual addresses to file/line locations.");
|
||||
ParseFlag(str, &external_symbolizer_path, "external_symbolizer_path",
|
||||
"Path to external symbolizer. If empty, the tool will search $PATH for "
|
||||
"the symbolizer.");
|
||||
ParseFlag(str, &allow_addr2line, "allow_addr2line",
|
||||
"If set, allows online symbolizer to run addr2line binary to symbolize "
|
||||
"stack traces (addr2line will only be used if llvm-symbolizer binary is "
|
||||
"unavailable.");
|
||||
ParseFlag(str, &strip_path_prefix, "strip_path_prefix",
|
||||
"Strips this prefix from file paths in error reports.");
|
||||
ParseFlag(str, &fast_unwind_on_check, "fast_unwind_on_check",
|
||||
"If available, use the fast frame-pointer-based unwinder on "
|
||||
"internal CHECK failures.");
|
||||
ParseFlag(str, &fast_unwind_on_fatal, "fast_unwind_on_fatal",
|
||||
"If available, use the fast frame-pointer-based unwinder on fatal "
|
||||
"errors.");
|
||||
ParseFlag(str, &fast_unwind_on_malloc, "fast_unwind_on_malloc",
|
||||
"If available, use the fast frame-pointer-based unwinder on "
|
||||
"malloc/free.");
|
||||
ParseFlag(str, &handle_ioctl, "handle_ioctl",
|
||||
"Intercept and handle ioctl requests.");
|
||||
ParseFlag(str, &malloc_context_size, "malloc_context_size",
|
||||
"Max number of stack frames kept for each allocation/deallocation.");
|
||||
ParseFlag(str, &log_path, "log_path",
|
||||
"Write logs to \"log_path.pid\". The special values are \"stdout\" and "
|
||||
"\"stderr\". The default is \"stderr\".");
|
||||
ParseFlag(str, &verbosity, "verbosity",
|
||||
"Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).");
|
||||
ParseFlag(str, &detect_leaks, "detect_leaks",
|
||||
"Enable memory leak detection.");
|
||||
ParseFlag(str, &leak_check_at_exit, "leak_check_at_exit",
|
||||
"Invoke leak checking in an atexit handler. Has no effect if "
|
||||
"detect_leaks=false, or if __lsan_do_leak_check() is called before the "
|
||||
"handler has a chance to run.");
|
||||
ParseFlag(str, &allocator_may_return_null, "allocator_may_return_null",
|
||||
"If false, the allocator will crash instead of returning 0 on "
|
||||
"out-of-memory.");
|
||||
ParseFlag(str, &print_summary, "print_summary",
|
||||
"If false, disable printing error summaries in addition to error "
|
||||
"reports.");
|
||||
ParseFlag(str, &check_printf, "check_printf",
|
||||
"Check printf arguments.");
|
||||
ParseFlag(str, &handle_segv, "handle_segv",
|
||||
"If set, registers the tool's custom SEGV handler (both SIGBUS and "
|
||||
"SIGSEGV on OSX).");
|
||||
ParseFlag(str, &allow_user_segv_handler, "allow_user_segv_handler",
|
||||
"If set, allows user to register a SEGV handler even if the tool "
|
||||
"registers one.");
|
||||
ParseFlag(str, &use_sigaltstack, "use_sigaltstack",
|
||||
"If set, uses alternate stack for signal handling.");
|
||||
ParseFlag(str, &detect_deadlocks, "detect_deadlocks",
|
||||
"If set, deadlock detection is enabled.");
|
||||
ParseFlag(str, &clear_shadow_mmap_threshold,
|
||||
"clear_shadow_mmap_threshold",
|
||||
"Large shadow regions are zero-filled using mmap(NORESERVE) instead of "
|
||||
"memset(). This is the threshold size in bytes.");
|
||||
ParseFlag(str, &color, "color",
|
||||
"Colorize reports: (always|never|auto).");
|
||||
ParseFlag(str, &legacy_pthread_cond, "legacy_pthread_cond",
|
||||
"Enables support for dynamic libraries linked with libpthread 2.2.5.");
|
||||
ParseFlag(str, &intercept_tls_get_addr, "intercept_tls_get_addr",
|
||||
"Intercept __tls_get_addr.");
|
||||
ParseFlag(str, &help, "help", "Print the flag descriptions.");
|
||||
ParseFlag(str, &mmap_limit_mb, "mmap_limit_mb",
|
||||
"Limit the amount of mmap-ed memory (excluding shadow) in Mb; "
|
||||
"not a user-facing flag, used mosly for testing the tools");
|
||||
ParseFlag(str, &hard_rss_limit_mb, "hard_rss_limit_mb",
|
||||
"RSS limit in Mb."
|
||||
" If non-zero, a background thread is spawned at startup"
|
||||
" which periodically reads RSS and aborts the process if the"
|
||||
" limit is reached");
|
||||
ParseFlag(str, &coverage, "coverage",
|
||||
"If set, coverage information will be dumped at program shutdown (if the "
|
||||
"coverage instrumentation was enabled at compile time).");
|
||||
ParseFlag(str, &coverage_pcs, "coverage_pcs",
|
||||
"If set (and if 'coverage' is set too), the coverage information "
|
||||
"will be dumped as a set of PC offsets for every module.");
|
||||
ParseFlag(str, &coverage_bitset, "coverage_bitset",
|
||||
"If set (and if 'coverage' is set too), the coverage information "
|
||||
"will also be dumped as a bitset to a separate file.");
|
||||
ParseFlag(str, &coverage_direct, "coverage_direct",
|
||||
"If set, coverage information will be dumped directly to a memory "
|
||||
"mapped file. This way data is not lost even if the process is "
|
||||
"suddenly killed.");
|
||||
ParseFlag(str, &coverage_dir, "coverage_dir",
|
||||
"Target directory for coverage dumps. Defaults to the current "
|
||||
"directory.");
|
||||
ParseFlag(str, &full_address_space, "full_address_space",
|
||||
"Sanitize complete address space; "
|
||||
"by default kernel area on 32-bit platforms will not be sanitized");
|
||||
ParseFlag(str, &suppressions, "suppressions", "Suppressions file name.");
|
||||
ParseFlag(str, &print_suppressions, "print_suppressions",
|
||||
"Print matched suppressions at exit.");
|
||||
ParseFlag(str, &disable_coredump, "disable_coredump",
|
||||
"Disable core dumping. By default, disable_core=1 on 64-bit to avoid "
|
||||
"dumping a 16T+ core file. Ignored on OSes that don't dump core by"
|
||||
"default and for sanitizers that don't reserve lots of virtual memory.");
|
||||
ParseFlag(str, &symbolize_inline_frames, "symbolize_inline_frames",
|
||||
"Print inlined frames in stacktraces. Defaults to true.");
|
||||
ParseFlag(str, &stack_trace_format, "stack_trace_format",
|
||||
"Format string used to render stack frames. "
|
||||
"See sanitizer_stacktrace_printer.h for the format description. "
|
||||
"Use DEFAULT to get default format.");
|
||||
|
||||
#define COMMON_FLAG(Type, Name, DefaultValue, Description) \
|
||||
ParseFlag(str, &Name, #Name, Description);
|
||||
#include "sanitizer_flags.inc"
|
||||
#undef COMMON_FLAG
|
||||
// Do a sanity check for certain flags.
|
||||
if (malloc_context_size < 1)
|
||||
malloc_context_size = 1;
|
||||
|
|
|
@ -28,48 +28,12 @@ void ParseFlag(const char *env, const char **flag,
|
|||
const char *name, const char *descr);
|
||||
|
||||
struct CommonFlags {
|
||||
bool symbolize;
|
||||
const char *external_symbolizer_path;
|
||||
bool allow_addr2line;
|
||||
const char *strip_path_prefix;
|
||||
bool fast_unwind_on_check;
|
||||
bool fast_unwind_on_fatal;
|
||||
bool fast_unwind_on_malloc;
|
||||
bool handle_ioctl;
|
||||
int malloc_context_size;
|
||||
const char *log_path;
|
||||
int verbosity;
|
||||
bool detect_leaks;
|
||||
bool leak_check_at_exit;
|
||||
bool allocator_may_return_null;
|
||||
bool print_summary;
|
||||
bool check_printf;
|
||||
bool handle_segv;
|
||||
bool allow_user_segv_handler;
|
||||
bool use_sigaltstack;
|
||||
bool detect_deadlocks;
|
||||
uptr clear_shadow_mmap_threshold;
|
||||
const char *color;
|
||||
bool legacy_pthread_cond;
|
||||
bool intercept_tls_get_addr;
|
||||
bool help;
|
||||
uptr mmap_limit_mb;
|
||||
uptr hard_rss_limit_mb;
|
||||
bool coverage;
|
||||
bool coverage_pcs;
|
||||
bool coverage_bitset;
|
||||
bool coverage_direct;
|
||||
const char *coverage_dir;
|
||||
bool full_address_space;
|
||||
const char *suppressions;
|
||||
bool print_suppressions;
|
||||
bool disable_coredump;
|
||||
bool symbolize_inline_frames;
|
||||
const char *stack_trace_format;
|
||||
#define COMMON_FLAG(Type, Name, DefaultValue, Description) Type Name;
|
||||
#include "sanitizer_flags.inc"
|
||||
#undef COMMON_FLAG
|
||||
|
||||
void SetDefaults();
|
||||
void ParseFromString(const char *str);
|
||||
|
||||
void CopyFrom(const CommonFlags &other);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
//===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file describes common flags available in all sanitizers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef COMMON_FLAG
|
||||
#error "Define COMMON_FLAG prior to including this file!"
|
||||
#endif
|
||||
|
||||
// COMMON_FLAG(Type, Name, DefaultValue, Description)
|
||||
// Supported types: bool, const char *, int, uptr.
|
||||
// Default value must be a compile-time constant.
|
||||
// Description must be a string literal.
|
||||
|
||||
COMMON_FLAG(
|
||||
bool, symbolize, true,
|
||||
"If set, use the online symbolizer from common sanitizer runtime to turn "
|
||||
"virtual addresses to file/line locations.")
|
||||
COMMON_FLAG(
|
||||
const char *, external_symbolizer_path, 0,
|
||||
"Path to external symbolizer. If empty, the tool will search $PATH for "
|
||||
"the symbolizer.")
|
||||
COMMON_FLAG(
|
||||
bool, allow_addr2line, false,
|
||||
"If set, allows online symbolizer to run addr2line binary to symbolize "
|
||||
"stack traces (addr2line will only be used if llvm-symbolizer binary is "
|
||||
"unavailable.")
|
||||
COMMON_FLAG(const char *, strip_path_prefix, "",
|
||||
"Strips this prefix from file paths in error reports.")
|
||||
COMMON_FLAG(bool, fast_unwind_on_check, false,
|
||||
"If available, use the fast frame-pointer-based unwinder on "
|
||||
"internal CHECK failures.")
|
||||
COMMON_FLAG(bool, fast_unwind_on_fatal, false,
|
||||
"If available, use the fast frame-pointer-based unwinder on fatal "
|
||||
"errors.")
|
||||
COMMON_FLAG(bool, fast_unwind_on_malloc, true,
|
||||
"If available, use the fast frame-pointer-based unwinder on "
|
||||
"malloc/free.")
|
||||
COMMON_FLAG(bool, handle_ioctl, false, "Intercept and handle ioctl requests.")
|
||||
COMMON_FLAG(int, malloc_context_size, 1,
|
||||
"Max number of stack frames kept for each allocation/deallocation.")
|
||||
COMMON_FLAG(
|
||||
const char *, log_path, "stderr",
|
||||
"Write logs to \"log_path.pid\". The special values are \"stdout\" and "
|
||||
"\"stderr\". The default is \"stderr\".")
|
||||
COMMON_FLAG(
|
||||
int, verbosity, 0,
|
||||
"Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).")
|
||||
COMMON_FLAG(bool, detect_leaks, true, "Enable memory leak detection.")
|
||||
COMMON_FLAG(
|
||||
bool, leak_check_at_exit, true,
|
||||
"Invoke leak checking in an atexit handler. Has no effect if "
|
||||
"detect_leaks=false, or if __lsan_do_leak_check() is called before the "
|
||||
"handler has a chance to run.")
|
||||
COMMON_FLAG(bool, allocator_may_return_null, false,
|
||||
"If false, the allocator will crash instead of returning 0 on "
|
||||
"out-of-memory.")
|
||||
COMMON_FLAG(bool, print_summary, true,
|
||||
"If false, disable printing error summaries in addition to error "
|
||||
"reports.")
|
||||
COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
|
||||
COMMON_FLAG(bool, handle_segv, SANITIZER_NEEDS_SEGV,
|
||||
"If set, registers the tool's custom SEGV handler (both SIGBUS and "
|
||||
"SIGSEGV on OSX).")
|
||||
COMMON_FLAG(bool, allow_user_segv_handler, false,
|
||||
"If set, allows user to register a SEGV handler even if the tool "
|
||||
"registers one.")
|
||||
COMMON_FLAG(bool, use_sigaltstack, true,
|
||||
"If set, uses alternate stack for signal handling.")
|
||||
COMMON_FLAG(bool, detect_deadlocks, false,
|
||||
"If set, deadlock detection is enabled.")
|
||||
COMMON_FLAG(
|
||||
uptr, clear_shadow_mmap_threshold, 64 * 1024,
|
||||
"Large shadow regions are zero-filled using mmap(NORESERVE) instead of "
|
||||
"memset(). This is the threshold size in bytes.")
|
||||
COMMON_FLAG(const char *, color, "auto",
|
||||
"Colorize reports: (always|never|auto).")
|
||||
COMMON_FLAG(
|
||||
bool, legacy_pthread_cond, false,
|
||||
"Enables support for dynamic libraries linked with libpthread 2.2.5.")
|
||||
COMMON_FLAG(bool, intercept_tls_get_addr, false, "Intercept __tls_get_addr.")
|
||||
COMMON_FLAG(bool, help, false, "Print the flag descriptions.")
|
||||
COMMON_FLAG(uptr, mmap_limit_mb, 0,
|
||||
"Limit the amount of mmap-ed memory (excluding shadow) in Mb; "
|
||||
"not a user-facing flag, used mosly for testing the tools")
|
||||
COMMON_FLAG(uptr, hard_rss_limit_mb, 0,
|
||||
"RSS limit in Mb."
|
||||
" If non-zero, a background thread is spawned at startup"
|
||||
" which periodically reads RSS and aborts the process if the"
|
||||
" limit is reached")
|
||||
COMMON_FLAG(
|
||||
bool, coverage, false,
|
||||
"If set, coverage information will be dumped at program shutdown (if the "
|
||||
"coverage instrumentation was enabled at compile time).")
|
||||
// On by default, but works only if coverage == true.
|
||||
COMMON_FLAG(bool, coverage_pcs, true,
|
||||
"If set (and if 'coverage' is set too), the coverage information "
|
||||
"will be dumped as a set of PC offsets for every module.")
|
||||
COMMON_FLAG(bool, coverage_bitset, false,
|
||||
"If set (and if 'coverage' is set too), the coverage information "
|
||||
"will also be dumped as a bitset to a separate file.")
|
||||
COMMON_FLAG(bool, coverage_direct, SANITIZER_ANDROID,
|
||||
"If set, coverage information will be dumped directly to a memory "
|
||||
"mapped file. This way data is not lost even if the process is "
|
||||
"suddenly killed.")
|
||||
COMMON_FLAG(const char *, coverage_dir, ".",
|
||||
"Target directory for coverage dumps. Defaults to the current "
|
||||
"directory.")
|
||||
COMMON_FLAG(bool, full_address_space, false,
|
||||
"Sanitize complete address space; "
|
||||
"by default kernel area on 32-bit platforms will not be sanitized")
|
||||
COMMON_FLAG(const char *, suppressions, "", "Suppressions file name.")
|
||||
COMMON_FLAG(bool, print_suppressions, true,
|
||||
"Print matched suppressions at exit.")
|
||||
COMMON_FLAG(
|
||||
bool, disable_coredump, (SANITIZER_WORDSIZE == 64),
|
||||
"Disable core dumping. By default, disable_core=1 on 64-bit to avoid "
|
||||
"dumping a 16T+ core file. Ignored on OSes that don't dump core by"
|
||||
"default and for sanitizers that don't reserve lots of virtual memory.")
|
||||
COMMON_FLAG(bool, symbolize_inline_frames, true,
|
||||
"Print inlined frames in stacktraces. Defaults to true.")
|
||||
COMMON_FLAG(const char *, stack_trace_format, "DEFAULT",
|
||||
"Format string used to render stack frames. "
|
||||
"See sanitizer_stacktrace_printer.h for the format description. "
|
||||
"Use DEFAULT to get default format.")
|
Loading…
Reference in New Issue