[sanitizer] Make unrecognized flags not fatal.

Print a warning at verbosity=1 and higher instead of dying immediately.

llvm-svn: 226458
This commit is contained in:
Evgeniy Stepanov 2015-01-19 12:22:57 +00:00
parent f8753fc48d
commit a2edd9159a
8 changed files with 58 additions and 11 deletions

View File

@ -98,9 +98,9 @@ void InitializeFlags(Flags *f) {
VReport(1, "Parsed activation flags: %s\n", buf); VReport(1, "Parsed activation flags: %s\n", buf);
} }
if (common_flags()->help) { if (common_flags()->verbosity) ReportUnrecognizedFlags();
parser.PrintFlagDescriptions();
} if (common_flags()->help) parser.PrintFlagDescriptions();
// Flag validation: // Flag validation:
if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) { if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {

View File

@ -75,6 +75,8 @@ static void InitializeFlags(bool standalone) {
const char *options = GetEnv("LSAN_OPTIONS"); const char *options = GetEnv("LSAN_OPTIONS");
parser.ParseString(options); parser.ParseString(options);
if (common_flags()->verbosity) ReportUnrecognizedFlags();
if (!help_before && common_flags()->help) if (!help_before && common_flags()->help)
parser.PrintFlagDescriptions(); parser.PrintFlagDescriptions();
} }

View File

@ -157,6 +157,8 @@ static void InitializeFlags(Flags *f, const char *options) {
parser.ParseString(options); parser.ParseString(options);
if (common_flags()->verbosity) ReportUnrecognizedFlags();
if (common_flags()->help) parser.PrintFlagDescriptions(); if (common_flags()->help) parser.PrintFlagDescriptions();
// Check flag values: // Check flag values:

View File

@ -22,6 +22,32 @@ namespace __sanitizer {
LowLevelAllocator FlagParser::Alloc; LowLevelAllocator FlagParser::Alloc;
class UnknownFlags {
static const int kMaxUnknownFlags = 20;
const char *unknown_flags_[kMaxUnknownFlags];
int n_unknown_flags_;
public:
void Add(const char *name) {
CHECK_LT(n_unknown_flags_, kMaxUnknownFlags);
unknown_flags_[n_unknown_flags_++] = name;
}
void Report() {
if (!n_unknown_flags_) return;
Printf("WARNING: found %d unrecognized flag(s):\n", n_unknown_flags_);
for (int i = 0; i < n_unknown_flags_; ++i)
Printf(" %s\n", unknown_flags_[i]);
n_unknown_flags_ = 0;
}
};
UnknownFlags unknown_flags;
void ReportUnrecognizedFlags() {
unknown_flags.Report();
}
char *FlagParser::ll_strndup(const char *s, uptr n) { char *FlagParser::ll_strndup(const char *s, uptr n) {
uptr len = internal_strnlen(s, n); uptr len = internal_strnlen(s, n);
char *s2 = (char*)Alloc.Allocate(len + 1); char *s2 = (char*)Alloc.Allocate(len + 1);
@ -106,8 +132,9 @@ bool FlagParser::run_handler(const char *name, const char *value) {
if (internal_strcmp(name, flags_[i].name) == 0) if (internal_strcmp(name, flags_[i].name) == 0)
return flags_[i].handler->Parse(value); return flags_[i].handler->Parse(value);
} }
Printf("ERROR: Unknown flag: '%s'\n", name); // Unrecognized flag. This is not a fatal error, we may print a warning later.
return false; unknown_flags.Add(name);
return true;
} }
void FlagParser::RegisterHandler(const char *name, FlagHandlerBase *handler, void FlagParser::RegisterHandler(const char *name, FlagHandlerBase *handler,

View File

@ -114,6 +114,8 @@ static void RegisterFlag(FlagParser *parser, const char *name, const char *desc,
parser->RegisterHandler(name, fh, desc); parser->RegisterHandler(name, fh, desc);
} }
void ReportUnrecognizedFlags();
} // namespace __sanitizer } // namespace __sanitizer
#endif // SANITIZER_FLAG_REGISTRY_H #endif // SANITIZER_FLAG_REGISTRY_H

View File

@ -63,9 +63,14 @@ TEST(SanitizerCommon, IntFlags) {
TestFlag(-11, "flag_name=0", 0); TestFlag(-11, "flag_name=0", 0);
TestFlag(-11, "flag_name=42", 42); TestFlag(-11, "flag_name=42", 42);
TestFlag(-11, "flag_name=-42", -42); TestFlag(-11, "flag_name=-42", -42);
// Unrecognized flags are ignored.
TestFlag(-11, "--flag_name=42", -11);
TestFlag(-11, "zzzzzzz=42", -11);
EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='"); EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='");
EXPECT_DEATH(TestFlag(-11, "--flag_name=42", 0), EXPECT_DEATH(TestFlag(-11, "flag_name=42U", 0),
"Unknown flag: '--flag_name'"); "Invalid value for int option");
} }
TEST(SanitizerCommon, StrFlags) { TEST(SanitizerCommon, StrFlags) {

View File

@ -80,8 +80,9 @@ void InitializeFlags(Flags *f, const char *env) {
f->report_signal_unsafe = false; f->report_signal_unsafe = false;
} }
if (common_flags()->help) if (common_flags()->verbosity) ReportUnrecognizedFlags();
parser.PrintFlagDescriptions();
if (common_flags()->help) parser.PrintFlagDescriptions();
if (f->history_size < 0 || f->history_size > 7) { if (f->history_size < 0 || f->history_size > 7) {
Printf("ThreadSanitizer: incorrect value for history_size" Printf("ThreadSanitizer: incorrect value for history_size"

View File

@ -1,7 +1,15 @@
// RUN: %clangxx -O0 %s -o %t // RUN: %clangxx -O0 %s -o %t
// RUN: %tool_options=invalid_option_name=10 not %run %t 2>&1 | FileCheck %s // RUN: %tool_options=invalid_option_name=10,verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V1
// RUN: %tool_options=invalid_option_name=10 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V0
#include <stdio.h>
int main() { int main() {
fprintf(stderr, "done\n");
} }
// CHECK: Unknown flag{{.*}}invalid_option_name // CHECK-V1: WARNING: found 1 unrecognized
// CHECK-V1: invalid_option_name
// CHECK-V0-NOT: WARNING: found 1 unrecognized
// CHECK-V0-NOT: invalid_option_name
// CHECK: done