forked from OSchip/llvm-project
[asan] Common flags in ASan.
Some flags that are common to ASan/MSan/TSan/LSan have been moved to sanitizer_common. llvm-svn: 181193
This commit is contained in:
parent
509c240ce5
commit
0c8ed9ce44
|
@ -22,6 +22,7 @@
|
|||
#include "asan_report.h"
|
||||
#include "asan_thread.h"
|
||||
#include "sanitizer_common/sanitizer_allocator.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||
#include "sanitizer_common/sanitizer_list.h"
|
||||
#include "sanitizer_common/sanitizer_stackdepot.h"
|
||||
|
|
|
@ -32,8 +32,6 @@ struct Flags {
|
|||
// Lower value may reduce memory usage but increase the chance of
|
||||
// false negatives.
|
||||
int quarantine_size;
|
||||
// If set, uses in-process symbolizer from common sanitizer runtime.
|
||||
bool symbolize;
|
||||
// Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).
|
||||
int verbosity;
|
||||
// Size (in bytes) of redzones around heap objects.
|
||||
|
@ -47,8 +45,6 @@ struct Flags {
|
|||
int report_globals;
|
||||
// If set, attempts to catch initialization order issues.
|
||||
bool check_initialization_order;
|
||||
// Max number of stack frames kept for each allocation/deallocation.
|
||||
int malloc_context_size;
|
||||
// If set, uses custom wrappers and replacements for libc string functions
|
||||
// to find more errors.
|
||||
bool replace_str;
|
||||
|
@ -93,18 +89,12 @@ struct Flags {
|
|||
// Allow the tool to re-exec the program. This may interfere badly with the
|
||||
// debugger.
|
||||
bool allow_reexec;
|
||||
// Strips this prefix from file paths in error reports.
|
||||
const char *strip_path_prefix;
|
||||
// If set, prints not only thread creation stacks for threads in error report,
|
||||
// but also thread creation stacks for threads that created those threads,
|
||||
// etc. up to main thread.
|
||||
bool print_full_thread_history;
|
||||
// ASan will write logs to "log_path.pid" instead of stderr.
|
||||
const char *log_path;
|
||||
// Use fast (frame-pointer-based) unwinder on fatal errors (if available).
|
||||
bool fast_unwind_on_fatal;
|
||||
// Use fast (frame-pointer-based) unwinder on malloc/free (if available).
|
||||
bool fast_unwind_on_malloc;
|
||||
// Poison (or not) the heap memory on [de]allocation. Zero value is useful
|
||||
// for benchmarking the allocator or instrumentator.
|
||||
bool poison_heap;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "asan_stack.h"
|
||||
#include "asan_thread.h"
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
#include "sanitizer_common/sanitizer_report_decorator.h"
|
||||
#include "sanitizer_common/sanitizer_symbolizer.h"
|
||||
|
||||
|
@ -502,7 +503,8 @@ static void ReportSummary(const char *error_type, StackTrace *stack) {
|
|||
uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
|
||||
SymbolizeCode(pc, &ai, 1);
|
||||
ReportErrorSummary(error_type,
|
||||
StripPathPrefix(ai.file, flags()->strip_path_prefix),
|
||||
StripPathPrefix(ai.file,
|
||||
common_flags()->strip_path_prefix),
|
||||
ai.line, ai.function);
|
||||
}
|
||||
// FIXME: do we need to print anything at all if there is no symbolizer?
|
||||
|
|
|
@ -84,8 +84,10 @@ static const char *MaybeUseAsanDefaultOptionsCompileDefiniton() {
|
|||
}
|
||||
|
||||
static void ParseFlagsFromString(Flags *f, const char *str) {
|
||||
ParseCommonFlagsFromString(str);
|
||||
CHECK((uptr)common_flags()->malloc_context_size <= kStackTraceMax);
|
||||
|
||||
ParseFlag(str, &f->quarantine_size, "quarantine_size");
|
||||
ParseFlag(str, &f->symbolize, "symbolize");
|
||||
ParseFlag(str, &f->verbosity, "verbosity");
|
||||
ParseFlag(str, &f->redzone, "redzone");
|
||||
CHECK_GE(f->redzone, 16);
|
||||
|
@ -94,8 +96,6 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
|
|||
ParseFlag(str, &f->debug, "debug");
|
||||
ParseFlag(str, &f->report_globals, "report_globals");
|
||||
ParseFlag(str, &f->check_initialization_order, "check_initialization_order");
|
||||
ParseFlag(str, &f->malloc_context_size, "malloc_context_size");
|
||||
CHECK((uptr)f->malloc_context_size <= kStackTraceMax);
|
||||
|
||||
ParseFlag(str, &f->replace_str, "replace_str");
|
||||
ParseFlag(str, &f->replace_intrin, "replace_intrin");
|
||||
|
@ -116,12 +116,9 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
|
|||
ParseFlag(str, &f->print_legend, "print_legend");
|
||||
ParseFlag(str, &f->atexit, "atexit");
|
||||
ParseFlag(str, &f->disable_core, "disable_core");
|
||||
ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");
|
||||
ParseFlag(str, &f->allow_reexec, "allow_reexec");
|
||||
ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history");
|
||||
ParseFlag(str, &f->log_path, "log_path");
|
||||
ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal");
|
||||
ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc");
|
||||
ParseFlag(str, &f->poison_heap, "poison_heap");
|
||||
ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch");
|
||||
ParseFlag(str, &f->use_stack_depot, "use_stack_depot");
|
||||
|
@ -129,19 +126,22 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
|
|||
ParseFlag(str, &f->strict_init_order, "strict_init_order");
|
||||
}
|
||||
|
||||
static const char *asan_external_symbolizer;
|
||||
|
||||
void InitializeFlags(Flags *f, const char *env) {
|
||||
internal_memset(f, 0, sizeof(*f));
|
||||
CommonFlags *cf = common_flags();
|
||||
cf->external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
|
||||
cf->symbolize = (cf->external_symbolizer_path != 0);
|
||||
cf->malloc_context_size = kDefaultMallocContextSize;
|
||||
cf->fast_unwind_on_fatal = false;
|
||||
cf->fast_unwind_on_malloc = true;
|
||||
cf->strip_path_prefix = "";
|
||||
|
||||
internal_memset(f, 0, sizeof(*f));
|
||||
f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28;
|
||||
f->symbolize = (asan_external_symbolizer != 0);
|
||||
f->verbosity = 0;
|
||||
f->redzone = 16;
|
||||
f->debug = false;
|
||||
f->report_globals = 1;
|
||||
f->check_initialization_order = false;
|
||||
f->malloc_context_size = kDefaultMallocContextSize;
|
||||
f->replace_str = true;
|
||||
f->replace_intrin = true;
|
||||
f->mac_ignore_invalid_free = false;
|
||||
|
@ -161,17 +161,14 @@ void InitializeFlags(Flags *f, const char *env) {
|
|||
f->print_legend = true;
|
||||
f->atexit = false;
|
||||
f->disable_core = (SANITIZER_WORDSIZE == 64);
|
||||
f->strip_path_prefix = "";
|
||||
f->allow_reexec = true;
|
||||
f->print_full_thread_history = true;
|
||||
f->log_path = 0;
|
||||
f->fast_unwind_on_fatal = false;
|
||||
f->fast_unwind_on_malloc = true;
|
||||
f->poison_heap = true;
|
||||
// Turn off alloc/dealloc mismatch checker on Mac for now.
|
||||
// TODO(glider): Fix known issues and enable this back.
|
||||
f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0);;
|
||||
f->use_stack_depot = true; // Only affects allocator2.
|
||||
f->use_stack_depot = true;
|
||||
f->strict_memcmp = true;
|
||||
f->strict_init_order = false;
|
||||
|
||||
|
@ -371,7 +368,8 @@ static void PrintAddressSpaceLayout() {
|
|||
}
|
||||
Printf("\n");
|
||||
Printf("red_zone=%zu\n", (uptr)flags()->redzone);
|
||||
Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
|
||||
Printf("malloc_context_size=%zu\n",
|
||||
(uptr)common_flags()->malloc_context_size);
|
||||
|
||||
Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
|
||||
Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
|
||||
|
@ -430,8 +428,6 @@ void __asan_init() {
|
|||
SetCheckFailedCallback(AsanCheckFailed);
|
||||
SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
|
||||
|
||||
// Check if external symbolizer is defined before parsing the flags.
|
||||
asan_external_symbolizer = GetEnv("ASAN_SYMBOLIZER_PATH");
|
||||
// Initialize flags. This must be done early, because most of the
|
||||
// initialization steps look at flags().
|
||||
const char *options = GetEnv("ASAN_OPTIONS");
|
||||
|
@ -509,9 +505,10 @@ void __asan_init() {
|
|||
|
||||
InstallSignalHandlers();
|
||||
// Start symbolizer process if necessary.
|
||||
if (flags()->symbolize && asan_external_symbolizer &&
|
||||
asan_external_symbolizer[0]) {
|
||||
InitializeExternalSymbolizer(asan_external_symbolizer);
|
||||
const char* external_symbolizer = common_flags()->external_symbolizer_path;
|
||||
if (common_flags()->symbolize && external_symbolizer &&
|
||||
external_symbolizer[0]) {
|
||||
InitializeExternalSymbolizer(external_symbolizer);
|
||||
}
|
||||
|
||||
// On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "asan_internal.h"
|
||||
#include "asan_flags.h"
|
||||
#include "asan_stack.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
|
@ -24,8 +25,8 @@ static bool MaybeCallAsanSymbolize(const void *pc, char *out_buffer,
|
|||
}
|
||||
|
||||
void PrintStack(StackTrace *stack) {
|
||||
stack->PrintStack(stack->trace, stack->size, flags()->symbolize,
|
||||
flags()->strip_path_prefix, MaybeCallAsanSymbolize);
|
||||
stack->PrintStack(stack->trace, stack->size, common_flags()->symbolize,
|
||||
common_flags()->strip_path_prefix, MaybeCallAsanSymbolize);
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
#ifndef ASAN_STACK_H
|
||||
#define ASAN_STACK_H
|
||||
|
||||
#include "sanitizer_common/sanitizer_stacktrace.h"
|
||||
#include "asan_flags.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
#include "sanitizer_common/sanitizer_stacktrace.h"
|
||||
|
||||
namespace __asan {
|
||||
|
||||
|
@ -42,24 +43,24 @@ void PrintStack(StackTrace *stack);
|
|||
|
||||
#define GET_STACK_TRACE_FATAL(pc, bp) \
|
||||
GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp, \
|
||||
flags()->fast_unwind_on_fatal)
|
||||
common_flags()->fast_unwind_on_fatal)
|
||||
|
||||
#define GET_STACK_TRACE_FATAL_HERE \
|
||||
GET_STACK_TRACE(kStackTraceMax, flags()->fast_unwind_on_fatal)
|
||||
#define GET_STACK_TRACE_FATAL_HERE \
|
||||
GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal)
|
||||
|
||||
#define GET_STACK_TRACE_THREAD \
|
||||
#define GET_STACK_TRACE_THREAD \
|
||||
GET_STACK_TRACE(kStackTraceMax, true)
|
||||
|
||||
#define GET_STACK_TRACE_MALLOC \
|
||||
GET_STACK_TRACE(flags()->malloc_context_size, \
|
||||
flags()->fast_unwind_on_malloc)
|
||||
#define GET_STACK_TRACE_MALLOC \
|
||||
GET_STACK_TRACE(common_flags()->malloc_context_size, \
|
||||
common_flags()->fast_unwind_on_malloc)
|
||||
|
||||
#define GET_STACK_TRACE_FREE GET_STACK_TRACE_MALLOC
|
||||
|
||||
#define PRINT_CURRENT_STACK() \
|
||||
{ \
|
||||
GET_STACK_TRACE(kStackTraceMax, \
|
||||
flags()->fast_unwind_on_fatal); \
|
||||
common_flags()->fast_unwind_on_fatal); \
|
||||
PrintStack(&stack); \
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,17 @@
|
|||
|
||||
namespace __sanitizer {
|
||||
|
||||
CommonFlags common_flags_dont_use_directly;
|
||||
|
||||
void ParseCommonFlagsFromString(const char *str) {
|
||||
CommonFlags *f = common_flags();
|
||||
ParseFlag(str, &f->malloc_context_size, "malloc_context_size");
|
||||
ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");
|
||||
ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal");
|
||||
ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc");
|
||||
ParseFlag(str, &f->symbolize, "symbolize");
|
||||
}
|
||||
|
||||
static bool GetFlagValue(const char *env, const char *name,
|
||||
const char **value, int *value_length) {
|
||||
if (env == 0)
|
||||
|
|
|
@ -22,6 +22,29 @@ void ParseFlag(const char *env, bool *flag, const char *name);
|
|||
void ParseFlag(const char *env, int *flag, const char *name);
|
||||
void ParseFlag(const char *env, const char **flag, const char *name);
|
||||
|
||||
struct CommonFlags {
|
||||
// If set, use the online symbolizer from common sanitizer runtime.
|
||||
bool symbolize;
|
||||
// Path to external symbolizer.
|
||||
const char *external_symbolizer_path;
|
||||
// Strips this prefix from file paths in error reports.
|
||||
const char *strip_path_prefix;
|
||||
// Use fast (frame-pointer-based) unwinder on fatal errors (if available).
|
||||
bool fast_unwind_on_fatal;
|
||||
// Use fast (frame-pointer-based) unwinder on malloc/free (if available).
|
||||
bool fast_unwind_on_malloc;
|
||||
// Max number of stack frames kept for each allocation/deallocation.
|
||||
int malloc_context_size;
|
||||
};
|
||||
|
||||
extern CommonFlags common_flags_dont_use_directly;
|
||||
|
||||
inline CommonFlags *common_flags() {
|
||||
return &common_flags_dont_use_directly;
|
||||
}
|
||||
|
||||
void ParseCommonFlagsFromString(const char *str);
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_FLAGS_H
|
||||
|
|
Loading…
Reference in New Issue