summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-02-17 18:50:30 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-02-17 18:50:30 +0000
commit4e322ad9fc4cdc0fdd9aa023760ce97eda8da4a5 (patch)
tree189a0eae86722b60bcabc7d36710e34f5888b2fc
parent6d402658705f1a334e6dbddaf4c7b1e5c598a467 (diff)
[LSan] Make parent tool responsible for initializing LSan flags.
Summary: LSan can be combined with a parent tool (for now it's only ASan). Also, we allow LSAN_OPTIONS to override certain common flags. It means we have to parse LSAN_OPTIONS early enough, before the rest of the parent tool (including chunks of sanitizer_common) is initialized. In future, we can use the same approach for UBSan, after we embed it into ASan runtime in a similar way. Test Plan: regression test suite Reviewers: earthdok, eugenis Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D7577 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@229519 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_flags.cc52
-rw-r--r--lib/asan/asan_rtl.cc2
-rw-r--r--lib/lsan/lsan.cc32
-rw-r--r--lib/lsan/lsan_common.cc38
-rw-r--r--lib/lsan/lsan_common.h7
5 files changed, 75 insertions, 56 deletions
diff --git a/lib/asan/asan_flags.cc b/lib/asan/asan_flags.cc
index a7d2f3f1d..efb7767d5 100644
--- a/lib/asan/asan_flags.cc
+++ b/lib/asan/asan_flags.cc
@@ -54,11 +54,7 @@ static void RegisterAsanFlags(FlagParser *parser, Flags *f) {
}
void InitializeFlags() {
- Flags *f = flags();
- FlagParser parser;
- RegisterAsanFlags(&parser, f);
- RegisterCommonFlags(&parser);
-
+ // Set the default values and prepare for parsing ASan and common flags.
SetCommonFlagsDefaults();
{
CommonFlags cf;
@@ -69,28 +65,44 @@ void InitializeFlags() {
cf.intercept_tls_get_addr = true;
OverrideCommonFlags(cf);
}
-
- const int kDefaultQuarantineSizeMb = (ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;
+ Flags *f = flags();
f->SetDefaults();
- // Override from compile definition.
- const char *compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
- parser.ParseString(compile_def);
+ FlagParser asan_parser;
+ RegisterAsanFlags(&asan_parser, f);
+ RegisterCommonFlags(&asan_parser);
+
+ // Set the default values and prepare for parsing LSan flags (which can also
+ // overwrite common flags).
+#if CAN_SANITIZE_LEAKS
+ __lsan::Flags *lf = __lsan::flags();
+ lf->SetDefaults();
+
+ FlagParser lsan_parser;
+ __lsan::RegisterLsanFlags(&lsan_parser, lf);
+ RegisterCommonFlags(&lsan_parser);
+#endif
+
+ // Override from ASan compile definition.
+ const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
+ asan_parser.ParseString(asan_compile_def);
// Override from user-specified string.
- const char *default_options = MaybeCallAsanDefaultOptions();
- parser.ParseString(default_options);
+ const char *asan_default_options = MaybeCallAsanDefaultOptions();
+ asan_parser.ParseString(asan_default_options);
// Override from command line.
- const char *env = GetEnv("ASAN_OPTIONS");
- if (env) parser.ParseString(env);
+ asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
+#if CAN_SANITIZE_LEAKS
+ lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
+#endif
// Let activation flags override current settings. On Android they come
// from a system property. On other platforms this is no-op.
if (!flags()->start_deactivated) {
char buf[100];
GetExtraActivationFlags(buf, sizeof(buf));
- parser.ParseString(buf);
+ asan_parser.ParseString(buf);
}
SetVerbosity(common_flags()->verbosity);
@@ -98,7 +110,10 @@ void InitializeFlags() {
// TODO(eugenis): dump all flags at verbosity>=2?
if (Verbosity()) ReportUnrecognizedFlags();
- if (common_flags()->help) parser.PrintFlagDescriptions();
+ if (common_flags()->help) {
+ // TODO(samsonov): print all of the flags (ASan, LSan, common).
+ asan_parser.PrintFlagDescriptions();
+ }
// Flag validation:
if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {
@@ -128,8 +143,11 @@ void InitializeFlags() {
}
if (f->quarantine_size >= 0)
f->quarantine_size_mb = f->quarantine_size >> 20;
- if (f->quarantine_size_mb < 0)
+ if (f->quarantine_size_mb < 0) {
+ const int kDefaultQuarantineSizeMb =
+ (ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;
f->quarantine_size_mb = kDefaultQuarantineSizeMb;
+ }
}
} // namespace __asan
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index cfe28212b..9126e71a6 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -440,7 +440,7 @@ static void AsanInitInternal() {
SanitizerInitializeUnwinder();
#if CAN_SANITIZE_LEAKS
- __lsan::InitCommonLsan(false);
+ __lsan::InitCommonLsan();
if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {
Atexit(__lsan::DoLeakCheck);
}
diff --git a/lib/lsan/lsan.cc b/lib/lsan/lsan.cc
index 1509b2a7d..6018f7bf6 100644
--- a/lib/lsan/lsan.cc
+++ b/lib/lsan/lsan.cc
@@ -15,6 +15,7 @@
#include "lsan.h"
#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "lsan_allocator.h"
#include "lsan_common.h"
@@ -34,13 +35,42 @@ bool WordIsPoisoned(uptr addr) {
using namespace __lsan; // NOLINT
+static void InitializeFlags() {
+ // Set all the default values.
+ SetCommonFlagsDefaults();
+ {
+ CommonFlags cf;
+ cf.CopyFrom(*common_flags());
+ cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
+ cf.malloc_context_size = 30;
+ cf.detect_leaks = true;
+ OverrideCommonFlags(cf);
+ }
+
+ Flags *f = flags();
+ f->SetDefaults();
+
+ FlagParser parser;
+ RegisterLsanFlags(&parser, f);
+ RegisterCommonFlags(&parser);
+
+ parser.ParseString(GetEnv("LSAN_OPTIONS"));
+
+ SetVerbosity(common_flags()->verbosity);
+
+ if (Verbosity()) ReportUnrecognizedFlags();
+
+ if (common_flags()->help) parser.PrintFlagDescriptions();
+}
+
extern "C" void __lsan_init() {
CHECK(!lsan_init_is_running);
if (lsan_inited)
return;
lsan_init_is_running = true;
SanitizerToolName = "LeakSanitizer";
- InitCommonLsan(true);
+ InitializeFlags();
+ InitCommonLsan();
InitializeAllocator();
InitTlsSize();
InitializeInterceptors();
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index 7b3cd1639..5a2f25cf8 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -43,46 +43,13 @@ void Flags::SetDefaults() {
#undef LSAN_FLAG
}
-static void RegisterLsanFlags(FlagParser *parser, Flags *f) {
+void RegisterLsanFlags(FlagParser *parser, Flags *f) {
#define LSAN_FLAG(Type, Name, DefaultValue, Description) \
RegisterFlag(parser, #Name, Description, &f->Name);
#include "lsan_flags.inc"
#undef LSAN_FLAG
}
-static void InitializeFlags(bool standalone) {
- Flags *f = flags();
- FlagParser parser;
- RegisterLsanFlags(&parser, f);
- RegisterCommonFlags(&parser);
-
- f->SetDefaults();
-
- // Set defaults for common flags (only in standalone mode) and parse
- // them from LSAN_OPTIONS.
- if (standalone) {
- SetCommonFlagsDefaults();
- CommonFlags cf;
- cf.CopyFrom(*common_flags());
- cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
- cf.malloc_context_size = 30;
- cf.detect_leaks = true;
- OverrideCommonFlags(cf);
- }
-
- bool help_before = common_flags()->help;
-
- const char *options = GetEnv("LSAN_OPTIONS");
- parser.ParseString(options);
-
- SetVerbosity(common_flags()->verbosity);
-
- if (Verbosity()) ReportUnrecognizedFlags();
-
- if (!help_before && common_flags()->help)
- parser.PrintFlagDescriptions();
-}
-
#define LOG_POINTERS(...) \
do { \
if (flags()->log_pointers) Report(__VA_ARGS__); \
@@ -116,8 +83,7 @@ void InitializeRootRegions() {
root_regions = new(placeholder) InternalMmapVector<RootRegion>(1);
}
-void InitCommonLsan(bool standalone) {
- InitializeFlags(standalone);
+void InitCommonLsan() {
InitializeRootRegions();
if (common_flags()->detect_leaks) {
// Initialization which can fail or print warnings should only be done if
diff --git a/lib/lsan/lsan_common.h b/lib/lsan/lsan_common.h
index 64cbef38c..edb38ff47 100644
--- a/lib/lsan/lsan_common.h
+++ b/lib/lsan/lsan_common.h
@@ -27,6 +27,10 @@
#define CAN_SANITIZE_LEAKS 0
#endif
+namespace __sanitizer {
+class FlagParser;
+}
+
namespace __lsan {
// Chunk tags.
@@ -50,6 +54,7 @@ struct Flags {
extern Flags lsan_flags;
inline Flags *flags() { return &lsan_flags; }
+void RegisterLsanFlags(FlagParser *parser, Flags *f);
struct Leak {
u32 id;
@@ -105,7 +110,7 @@ enum IgnoreObjectResult {
};
// Functions called from the parent tool.
-void InitCommonLsan(bool standalone);
+void InitCommonLsan();
void DoLeakCheck();
bool DisabledInThisThread();