[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:
Sergey Matveev 2013-05-06 11:27:58 +00:00
parent 509c240ce5
commit 0c8ed9ce44
8 changed files with 69 additions and 43 deletions

View File

@ -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"

View File

@ -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;

View File

@ -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?

View File

@ -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

View File

@ -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

View File

@ -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); \
}

View File

@ -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)

View File

@ -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