[compiler-rt] r242853 - [sanitizer] Implement include_if_exists with process name substitution.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Jul 21 16:03:14 PDT 2015


Author: eugenis
Date: Tue Jul 21 18:03:13 2015
New Revision: 242853

URL: http://llvm.org/viewvc/llvm-project?rev=242853&view=rev
Log:
[sanitizer] Implement include_if_exists with process name substitution.

include_if_exists=/path/to/sanitizer/options reads flags from the
file if it is present. "%b" in the include file path (for both
variants of the flag) is replaced with the basename of the main
executable.

Modified:
    compiler-rt/trunk/lib/asan/asan_activation.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/lsan/lsan.cc
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
    compiler-rt/trunk/test/sanitizer_common/TestCases/options-include.cc

Modified: compiler-rt/trunk/lib/asan/asan_activation.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_activation.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_activation.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_activation.cc Tue Jul 21 18:03:13 2015
@@ -38,7 +38,7 @@ static struct AsanDeactivatedFlags {
 #undef ASAN_ACTIVATION_FLAG
 #undef COMMON_ACTIVATION_FLAG
 
-    RegisterIncludeFlag(parser, cf);
+    RegisterIncludeFlags(parser, cf);
   }
 
   void OverrideFromActivationFlags() {

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Tue Jul 21 18:03:13 2015
@@ -363,12 +363,12 @@ static void AsanInitInternal() {
   CHECK(!asan_init_is_running && "ASan init calls itself!");
   asan_init_is_running = true;
 
+  CacheBinaryName();
+
   // Initialize flags. This must be done early, because most of the
   // initialization steps look at flags().
   InitializeFlags();
 
-  CacheBinaryName();
-
   AsanCheckIncompatibleRT();
   AsanCheckDynamicRTPrereqs();
 

Modified: compiler-rt/trunk/lib/lsan/lsan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan.cc Tue Jul 21 18:03:13 2015
@@ -69,6 +69,7 @@ extern "C" void __lsan_init() {
     return;
   lsan_init_is_running = true;
   SanitizerToolName = "LeakSanitizer";
+  CacheBinaryName();
   InitializeFlags();
   InitCommonLsan();
   InitializeAllocator();

Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Tue Jul 21 18:03:13 2015
@@ -372,8 +372,8 @@ void __msan_init() {
   SetDieCallback(MsanDie);
   InitTlsSize();
 
-  InitializeFlags();
   CacheBinaryName();
+  InitializeFlags();
   __sanitizer_set_report_path(common_flags()->log_path);
 
   InitializeInterceptors();

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.cc Tue Jul 21 18:03:13 2015
@@ -127,6 +127,24 @@ void FlagParser::ParseString(const char
   pos_ = old_pos_;
 }
 
+bool FlagParser::ParseFile(const char *path, bool ignore_missing) {
+  static const uptr kMaxIncludeSize = 1 << 15;
+  char *data;
+  uptr data_mapped_size;
+  error_t err;
+  uptr len;
+  if (!ReadFileToBuffer(path, &data, &data_mapped_size, &len,
+                        Max(kMaxIncludeSize, GetPageSizeCached()), &err)) {
+    if (ignore_missing)
+      return true;
+    Printf("Failed to read options from '%s': error %d\n", path, err);
+    return false;
+  }
+  ParseString(data);
+  UnmapOrDie(data, data_mapped_size);
+  return true;
+}
+
 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)

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h Tue Jul 21 18:03:13 2015
@@ -93,6 +93,7 @@ class FlagParser {
   void RegisterHandler(const char *name, FlagHandlerBase *handler,
                        const char *desc);
   void ParseString(const char *s);
+  bool ParseFile(const char *path, bool ignore_missing);
   void PrintFlagDescriptions();
 
   static LowLevelAllocator Alloc;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Tue Jul 21 18:03:13 2015
@@ -45,33 +45,49 @@ void CommonFlags::CopyFrom(const CommonF
   internal_memcpy(this, &other, sizeof(*this));
 }
 
+// Copy the string from "s" to "out", replacing "%b" with the binary basename.
+static void SubstituteBinaryName(const char *s, char *out, uptr out_size) {
+  char *out_end = out + out_size;
+  while (*s && out < out_end - 1) {
+    if (s[0] != '%' || s[1] != 'b') { *out++ = *s++; continue; }
+    const char *base = GetBinaryBasename();
+    CHECK(base);
+    while (*base && out < out_end - 1)
+      *out++ = *base++;
+    s += 2; // skip "%b"
+  }
+  *out = '\0';
+}
+
 class FlagHandlerInclude : public FlagHandlerBase {
-  static const uptr kMaxIncludeSize = 1 << 15;
   FlagParser *parser_;
+  bool ignore_missing_;
 
  public:
-  explicit FlagHandlerInclude(FlagParser *parser) : parser_(parser) {}
+  explicit FlagHandlerInclude(FlagParser *parser, bool ignore_missing)
+      : parser_(parser), ignore_missing_(ignore_missing) {}
   bool Parse(const char *value) final {
-    char *data;
-    uptr data_mapped_size;
-    uptr len;
-    error_t err;
-    if (!ReadFileToBuffer(value, &data, &data_mapped_size, &len,
-                          Max(kMaxIncludeSize, GetPageSizeCached()), &err)) {
-      Printf("Failed to read options from '%s': error %d\n", value, err);
-      return false;
+    if (internal_strchr(value, '%')) {
+      char *buf = (char *)MmapOrDie(kMaxPathLength, "FlagHandlerInclude");
+      SubstituteBinaryName(value, buf, kMaxPathLength);
+      bool res = parser_->ParseFile(buf, ignore_missing_);
+      UnmapOrDie(buf, kMaxPathLength);
+      return res;
     }
-    parser_->ParseString(data);
-    UnmapOrDie(data, data_mapped_size);
-    return true;
+    return parser_->ParseFile(value, ignore_missing_);
   }
 };
 
-void RegisterIncludeFlag(FlagParser *parser, CommonFlags *cf) {
-  FlagHandlerInclude *fh_include =
-      new (FlagParser::Alloc) FlagHandlerInclude(parser);  // NOLINT
+void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) {
+  FlagHandlerInclude *fh_include = new (FlagParser::Alloc) // NOLINT
+      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) // NOLINT
+      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) {
@@ -80,7 +96,7 @@ void RegisterCommonFlags(FlagParser *par
 #include "sanitizer_flags.inc"
 #undef COMMON_FLAG
 
-  RegisterIncludeFlag(parser, cf);
+  RegisterIncludeFlags(parser, cf);
 }
 
 }  // namespace __sanitizer

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Tue Jul 21 18:03:13 2015
@@ -49,7 +49,7 @@ inline void OverrideCommonFlags(const Co
 class FlagParser;
 void RegisterCommonFlags(FlagParser *parser,
                          CommonFlags *cf = &common_flags_dont_use);
-void RegisterIncludeFlag(FlagParser *parser, CommonFlags *cf);
+void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf);
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_FLAGS_H

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Tue Jul 21 18:03:13 2015
@@ -318,8 +318,8 @@ void Initialize(ThreadState *thr) {
 
   ctx = new(ctx_placeholder) Context;
   const char *options = GetEnv(kTsanOptionsEnv);
-  InitializeFlags(&ctx->flags, options);
   CacheBinaryName();
+  InitializeFlags(&ctx->flags, options);
 #ifndef SANITIZER_GO
   InitializeAllocator();
 #endif

Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/options-include.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/options-include.cc?rev=242853&r1=242852&r2=242853&view=diff
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/options-include.cc (original)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/options-include.cc Tue Jul 21 18:03:13 2015
@@ -1,21 +1,46 @@
 // RUN: %clangxx -O0 %s -o %t
+
+// Recursive include: options1 includes options2
 // RUN: echo -e "symbolize=1\ninclude='%t.options2.txt'" >%t.options1.txt
 // RUN: echo -e "help=1\n" >%t.options2.txt
+// RUN: echo -e "help=1\n" >%t.options.options-include.cc.tmp
 // RUN: cat %t.options1.txt
 // RUN: cat %t.options2.txt
+
 // RUN: %tool_options="help=0:include='%t.options1.txt'" %run %t 2>&1 | tee %t.out
-// RUN: FileCheck %s --check-prefix=CHECK-VERBOSITY1 <%t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND <%t.out
+
 // RUN: %tool_options="include='%t.options1.txt',help=0" %run %t 2>&1 | tee %t.out
-// RUN: FileCheck %s --check-prefix=CHECK-VERBOSITY0 <%t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITHOUT-HELP --check-prefix=CHECK-FOUND <%t.out
+
 // RUN: %tool_options="include='%t.options-not-found.txt',help=1" not %run %t 2>&1 | tee %t.out
 // RUN: FileCheck %s --check-prefix=CHECK-NOT-FOUND < %t.out
 
+// include_if_exists does not fail when the file is missing
+// RUN: %tool_options="include_if_exists='%t.options-not-found.txt',help=1" %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND < %t.out
+
+// %b (binary basename substitution)
+// RUN: %tool_options="include='%t.options.%b'" %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND < %t.out
+
+// RUN: %tool_options="include='%t.options-not-found.%b'" not %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITHOUT-HELP --check-prefix=CHECK-NOT-FOUND < %t.out
+
+// RUN: %tool_options="include_if_exists='%t.options.%b'" %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND < %t.out
+
+// RUN: %tool_options="include_if_exists='%t.options-not-found.%b'" %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITHOUT-HELP --check-prefix=CHECK-FOUND < %t.out
+
+
 #include <stdio.h>
 
 int main() {
   fprintf(stderr, "done\n");
 }
 
-// CHECK-VERBOSITY1: Available flags for
-// CHECK-VERBOSITY0-NOT: Available flags for
+// CHECK-WITH-HELP: Available flags for
+// CHECK-WITHOUT-HELP-NOT: Available flags for
+// CHECK-FOUND-NOT: Failed to read options from
 // CHECK-NOT-FOUND: Failed to read options from





More information about the llvm-commits mailing list