summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/sanitizer_common/sanitizer_flags.cc
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2014-03-20 12:52:52 +0000
committerAlexander Potapenko <glider@google.com>2014-03-20 12:52:52 +0000
commit1296436cbf3ef2a05e10d485967c4ec6af9db707 (patch)
tree890111d724b07317806098834daccb9bfad08b6e /compiler-rt/lib/sanitizer_common/sanitizer_flags.cc
parentefb1eb981b46fc6a6c089514b9db82a54e0a11cc (diff)
downloadbcm5719-llvm-1296436cbf3ef2a05e10d485967c4ec6af9db707.tar.gz
bcm5719-llvm-1296436cbf3ef2a05e10d485967c4ec6af9db707.zip
[libsanitizer] Introduce flag descriptions.
Extend ParseFlag to accept the |description| parameter, add dummy values for all existing flags. As the flags are parsed their descriptions are stored in a global linked list. The tool can later call __sanitizer::PrintFlagDescriptions() to dump all the flag names and their descriptions. Add the 'help' flag and make ASan, TSan and MSan print the flags if 'help' is set to 1. llvm-svn: 204339
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_flags.cc')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_flags.cc110
1 files changed, 82 insertions, 28 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cc
index e48a7a2d84b..40ada97b5a5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cc
@@ -20,6 +20,14 @@ namespace __sanitizer {
CommonFlags common_flags_dont_use;
+struct FlagDescriptionList {
+ const char *name;
+ const char *description;
+ FlagDescriptionList *next;
+};
+
+FlagDescriptionList *flag_descriptions = 0, *last_flag_description = 0;
+
void SetCommonFlagsDefaults(CommonFlags *f) {
f->symbolize = true;
f->external_symbolizer_path = 0;
@@ -47,29 +55,31 @@ void SetCommonFlagsDefaults(CommonFlags *f) {
}
void ParseCommonFlagsFromString(CommonFlags *f, const char *str) {
- ParseFlag(str, &f->symbolize, "symbolize");
- ParseFlag(str, &f->external_symbolizer_path, "external_symbolizer_path");
- ParseFlag(str, &f->allow_addr2line, "allow_addr2line");
- 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->handle_ioctl, "handle_ioctl");
- ParseFlag(str, &f->malloc_context_size, "malloc_context_size");
- ParseFlag(str, &f->log_path, "log_path");
- ParseFlag(str, &f->verbosity, "verbosity");
- ParseFlag(str, &f->detect_leaks, "detect_leaks");
- ParseFlag(str, &f->leak_check_at_exit, "leak_check_at_exit");
- ParseFlag(str, &f->allocator_may_return_null, "allocator_may_return_null");
- ParseFlag(str, &f->print_summary, "print_summary");
- ParseFlag(str, &f->check_printf, "check_printf");
- ParseFlag(str, &f->handle_segv, "handle_segv");
- ParseFlag(str, &f->allow_user_segv_handler, "allow_user_segv_handler");
- ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack");
- ParseFlag(str, &f->detect_deadlocks, "detect_deadlocks");
+ ParseFlag(str, &f->symbolize, "symbolize", "");
+ ParseFlag(str, &f->external_symbolizer_path, "external_symbolizer_path", "");
+ ParseFlag(str, &f->allow_addr2line, "allow_addr2line", "");
+ 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->handle_ioctl, "handle_ioctl", "");
+ ParseFlag(str, &f->malloc_context_size, "malloc_context_size", "");
+ ParseFlag(str, &f->log_path, "log_path", "");
+ ParseFlag(str, &f->verbosity, "verbosity", "");
+ ParseFlag(str, &f->detect_leaks, "detect_leaks", "");
+ ParseFlag(str, &f->leak_check_at_exit, "leak_check_at_exit", "");
+ ParseFlag(str, &f->allocator_may_return_null, "allocator_may_return_null",
+ "");
+ ParseFlag(str, &f->print_summary, "print_summary", "");
+ ParseFlag(str, &f->check_printf, "check_printf", "");
+ ParseFlag(str, &f->handle_segv, "handle_segv", "");
+ ParseFlag(str, &f->allow_user_segv_handler, "allow_user_segv_handler", "");
+ ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack", "");
+ ParseFlag(str, &f->detect_deadlocks, "detect_deadlocks", "");
ParseFlag(str, &f->clear_shadow_mmap_threshold,
- "clear_shadow_mmap_threshold");
- ParseFlag(str, &f->color, "color");
- ParseFlag(str, &f->legacy_pthread_cond, "legacy_pthread_cond");
+ "clear_shadow_mmap_threshold", "");
+ ParseFlag(str, &f->color, "color", "");
+ ParseFlag(str, &f->legacy_pthread_cond, "legacy_pthread_cond", "");
+ ParseFlag(str, &f->help, "help", "");
// Do a sanity check for certain flags.
if (f->malloc_context_size < 1)
@@ -124,9 +134,49 @@ static bool StartsWith(const char *flag, int flag_length, const char *value) {
(0 == internal_strncmp(flag, value, value_length));
}
-void ParseFlag(const char *env, bool *flag, const char *name) {
+static LowLevelAllocator allocator_for_flags;
+
+// The linear scan is suboptimal, but the number of flags is relatively small.
+bool FlagInDescriptionList(const char *name) {
+ FlagDescriptionList *descr = flag_descriptions;
+ while (descr) {
+ if (!internal_strcmp(descr->name, name)) return true;
+ descr = descr->next;
+ }
+ return false;
+}
+
+void AddFlagDescription(const char *name, const char *description) {
+ if (FlagInDescriptionList(name)) return;
+ FlagDescriptionList *new_description =
+ (FlagDescriptionList*)allocator_for_flags.Allocate(
+ sizeof(FlagDescriptionList));
+ if (!last_flag_description) {
+ flag_descriptions = new_description;
+ } else {
+ last_flag_description->next = new_description;
+ }
+ new_description->name = name;
+ new_description->description = description;
+ new_description->next = 0;
+ last_flag_description = new_description;
+}
+
+// TODO(glider): put the descriptions inside CommonFlags.
+void PrintFlagDescriptions() {
+ FlagDescriptionList *descr = flag_descriptions;
+ Printf("Available flags for %s:\n", SanitizerToolName);
+ while (descr) {
+ Printf("\t%s - %s\n", descr->name, descr->description);
+ descr = descr->next;
+ }
+}
+
+void ParseFlag(const char *env, bool *flag,
+ const char *name, const char *descr) {
const char *value;
int value_length;
+ AddFlagDescription(name, descr);
if (!GetFlagValue(env, name, &value, &value_length))
return;
if (StartsWith(value, value_length, "0") ||
@@ -139,27 +189,31 @@ void ParseFlag(const char *env, bool *flag, const char *name) {
*flag = true;
}
-void ParseFlag(const char *env, int *flag, const char *name) {
+void ParseFlag(const char *env, int *flag,
+ const char *name, const char *descr) {
const char *value;
int value_length;
+ AddFlagDescription(name, descr);
if (!GetFlagValue(env, name, &value, &value_length))
return;
*flag = static_cast<int>(internal_atoll(value));
}
-void ParseFlag(const char *env, uptr *flag, const char *name) {
+void ParseFlag(const char *env, uptr *flag,
+ const char *name, const char *descr) {
const char *value;
int value_length;
+ AddFlagDescription(name, descr);
if (!GetFlagValue(env, name, &value, &value_length))
return;
*flag = static_cast<uptr>(internal_atoll(value));
}
-static LowLevelAllocator allocator_for_flags;
-
-void ParseFlag(const char *env, const char **flag, const char *name) {
+void ParseFlag(const char *env, const char **flag,
+ const char *name, const char *descr) {
const char *value;
int value_length;
+ AddFlagDescription(name, descr);
if (!GetFlagValue(env, name, &value, &value_length))
return;
// Copy the flag value. Don't use locks here, as flags are parsed at
OpenPOWER on IntegriCloud