llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

140 lines
4.2 KiB
C++
Raw Normal View History

//===-- sanitizer_flags.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_flags.h"
#include "sanitizer_common.h"
#include "sanitizer_flag_parser.h"
#include "sanitizer_libc.h"
#include "sanitizer_linux.h"
#include "sanitizer_list.h"
namespace __sanitizer {
CommonFlags common_flags_dont_use;
void CommonFlags::SetDefaults() {
#define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
#include "sanitizer_flags.inc"
#undef COMMON_FLAG
}
void CommonFlags::CopyFrom(const CommonFlags &other) {
internal_memcpy(this, &other, sizeof(*this));
}
// Copy the string from "s" to "out", making the following substitutions:
// %b = binary basename
// %p = pid
// %d = binary directory
void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
char *out_end = out + out_size;
while (*s && out < out_end - 1) {
if (s[0] != '%') {
*out++ = *s++;
continue;
}
switch (s[1]) {
case 'b': {
const char *base = GetProcessName();
CHECK(base);
while (*base && out < out_end - 1)
*out++ = *base++;
s += 2; // skip "%b"
break;
}
case 'p': {
int pid = internal_getpid();
char buf[32];
char *buf_pos = buf + 32;
do {
*--buf_pos = (pid % 10) + '0';
pid /= 10;
} while (pid);
while (buf_pos < buf + 32 && out < out_end - 1)
*out++ = *buf_pos++;
s += 2; // skip "%p"
break;
}
case 'd': {
uptr len = ReadBinaryDir(out, out_end - out);
out += len;
s += 2; // skip "%d"
break;
}
default:
*out++ = *s++;
break;
}
}
CHECK(out < out_end - 1);
*out = '\0';
}
class FlagHandlerInclude final : public FlagHandlerBase {
FlagParser *parser_;
bool ignore_missing_;
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
const char *original_path_;
public:
explicit FlagHandlerInclude(FlagParser *parser, bool ignore_missing)
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
: parser_(parser), ignore_missing_(ignore_missing), original_path_("") {}
bool Parse(const char *value) final {
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
original_path_ = value;
if (internal_strchr(value, '%')) {
char *buf = (char *)MmapOrDie(kMaxPathLength, "FlagHandlerInclude");
SubstituteForFlagValue(value, buf, kMaxPathLength);
bool res = parser_->ParseFile(buf, ignore_missing_);
UnmapOrDie(buf, kMaxPathLength);
return res;
}
return parser_->ParseFile(value, ignore_missing_);
}
bool Format(char *buffer, uptr size) override {
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
// Note `original_path_` isn't actually what's parsed due to `%`
// substitutions. Printing the substituted path would require holding onto
// mmap'ed memory.
return FormatString(buffer, size, original_path_);
}
};
void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) {
FlagHandlerInclude *fh_include = new (FlagParser::Alloc)
FlagHandlerInclude(parser, /*ignore_missing*/ false);
parser->RegisterHandler("include", fh_include,
"read more options from the given file");
FlagHandlerInclude *fh_include_if_exists = new (FlagParser::Alloc)
FlagHandlerInclude(parser, /*ignore_missing*/ true);
parser->RegisterHandler(
"include_if_exists", fh_include_if_exists,
"read more options from the given file (if it exists)");
}
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
RegisterIncludeFlags(parser, cf);
}
void InitializeCommonFlags(CommonFlags *cf) {
// need to record coverage to generate coverage report.
cf->coverage |= cf->html_cov_report;
SetVerbosity(cf->verbosity);
InitializePlatformCommonFlags(cf);
}
} // namespace __sanitizer