[sanitizer] Implement include= option.

Allows loading sanitizer options from file.

llvm-svn: 226175
This commit is contained in:
Evgeniy Stepanov 2015-01-15 16:26:59 +00:00
parent 13be264db2
commit bc14dd46f2
4 changed files with 58 additions and 4 deletions

View File

@ -71,10 +71,7 @@ void FlagParser::parse_flag() {
InternalFree((void *)value);
}
void FlagParser::ParseString(const char *s) {
if (!s) return;
buf_ = s;
pos_ = 0;
void FlagParser::parse_flags() {
while (true) {
skip_whitespace();
if (buf_[pos_] == 0) break;
@ -86,6 +83,20 @@ void FlagParser::ParseString(const char *s) {
common_flags_dont_use.malloc_context_size = 1;
}
void FlagParser::ParseString(const char *s) {
if (!s) return;
// Backup current parser state to allow nested ParseString() calls.
const char *old_buf_ = buf_;
uptr old_pos_ = pos_;
buf_ = s;
pos_ = 0;
parse_flags();
buf_ = old_buf_;
pos_ = old_pos_;
}
bool FlagParser::run_handler(const char *name, const char *value) {
for (int i = 0; i < n_flags_; ++i) {
if (internal_strcmp(name, flags_[i].name) == 0)

View File

@ -101,6 +101,7 @@ class FlagParser {
void fatal_error(const char *err);
bool is_space(char c);
void skip_whitespace();
void parse_flags();
void parse_flag();
bool run_handler(const char *name, const char *value);
};

View File

@ -45,11 +45,37 @@ void CommonFlags::CopyFrom(const CommonFlags &other) {
internal_memcpy(this, &other, sizeof(*this));
}
class FlagHandlerInclude : public FlagHandlerBase {
static const uptr kMaxIncludeSize = 1 << 15;
FlagParser *parser_;
public:
explicit FlagHandlerInclude(FlagParser *parser) : parser_(parser) {}
bool Parse(const char *value) {
char *data;
uptr data_mapped_size;
uptr len =
ReadFileToBuffer(value, &data, &data_mapped_size, kMaxIncludeSize);
if (!len) {
Printf("Failed to read options from '%s'\n", value);
return false;
}
parser_->ParseString(data);
UnmapOrDie(data, data_mapped_size);
return true;
}
};
void RegisterCommonFlags(FlagParser *parser, CommonFlags *cf) {
#define COMMON_FLAG(Type, Name, DefaultValue, Description) \
RegisterFlag(parser, #Name, Description, &cf->Name);
#include "sanitizer_flags.inc"
#undef COMMON_FLAG
FlagHandlerInclude *fh_include =
new (INTERNAL_ALLOC) FlagHandlerInclude(parser); // NOLINT
parser->RegisterHandler("include", fh_include,
"read more options from the given file");
}
} // namespace __sanitizer

View File

@ -0,0 +1,16 @@
// RUN: %clangxx_asan -O0 %s -o %t
// RUN: echo "symbolize=1\ninclude='%t.options2.txt'" > %t.options1.txt
// RUN: echo "verbosity=1" > %t.options2.txt
// RUN: ASAN_OPTIONS="verbosity=0:include='%t.options2.txt'" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-VERBOSITY1
// RUN: ASAN_OPTIONS="include='%t.options2.txt',verbosity=0" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-VERBOSITY0
// RUN: ASAN_OPTIONS="include='%t.options-not-found.txt',verbosity=0" not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-FOUND
#include <stdio.h>
int main() {
fprintf(stderr, "done\n");
}
// CHECK-VERBOSITY1: Parsed ASAN_OPTIONS:
// CHECK-VERBOSITY0-NOT: Parsed ASAN_OPTIONS:
// CHECK-NOT-FOUND: Failed to read options from