[XRay][compiler-rt] Support string-based config for Basic mode.
authorDean Michael Berris <dberris@google.com>
Fri, 4 May 2018 06:27:53 +0000 (06:27 +0000)
committerDean Michael Berris <dberris@google.com>
Fri, 4 May 2018 06:27:53 +0000 (06:27 +0000)
Summary:
This addresses http://llvm.org/PR36790.

This change allows the XRay Basic Mode implementation to use the
string-based initialization routine provided through
`__xray_log_init_mode(...)`. In the process, we've also deprecated some
flags defined for the `XRAY_OPTIONS` environment variable.

We then introduce another environment variable that can control the XRay
Basic Mode implementation through `XRAY_BASIC_OPTIONS`.

We also rename files from `xray_inmemory_log` to `xray_basic_logging` to
be more in line with the mode implementation.

Depends on D46174.

Reviewers: echristo, kpw, pelikan, eizan

Reviewed By: kpw

Subscribers: mgorny, llvm-commits

Differential Revision: https://reviews.llvm.org/D46246

llvm-svn: 331507

compiler-rt/lib/xray/CMakeLists.txt
compiler-rt/lib/xray/xray_basic_flags.cc [new file with mode: 0644]
compiler-rt/lib/xray/xray_basic_flags.h [new file with mode: 0644]
compiler-rt/lib/xray/xray_basic_flags.inc [new file with mode: 0644]
compiler-rt/lib/xray/xray_basic_logging.cc [moved from compiler-rt/lib/xray/xray_inmemory_log.cc with 87% similarity]
compiler-rt/lib/xray/xray_basic_logging.h [moved from compiler-rt/lib/xray/xray_inmemory_log.h with 95% similarity]
compiler-rt/lib/xray/xray_flags.inc
compiler-rt/test/xray/TestCases/Posix/basic-filtering.cc

index 58b5665..7954411 100644 (file)
@@ -15,7 +15,8 @@ set(XRAY_FDR_MODE_SOURCES
     xray_fdr_logging.cc)
 
 set(XRAY_BASIC_MODE_SOURCES
-    xray_inmemory_log.cc)
+    xray_basic_flags.cc
+    xray_basic_logging.cc)
 
 
 # Implementation files for all XRay architectures.
diff --git a/compiler-rt/lib/xray/xray_basic_flags.cc b/compiler-rt/lib/xray/xray_basic_flags.cc
new file mode 100644 (file)
index 0000000..14d805c
--- /dev/null
@@ -0,0 +1,50 @@
+//===-- xray_basic_flags.cc -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// XRay Basic flag parsing logic.
+//===----------------------------------------------------------------------===//
+
+#include "xray_basic_flags.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "xray_defs.h"
+
+using namespace __sanitizer;
+
+namespace __xray {
+
+/// Use via basicFlags().
+BasicFlags xray_basic_flags_dont_use_directly;
+
+void BasicFlags::setDefaults() XRAY_NEVER_INSTRUMENT {
+#define XRAY_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
+#include "xray_basic_flags.inc"
+#undef XRAY_FLAG
+}
+
+void registerXRayBasicFlags(FlagParser *P,
+                            BasicFlags *F) XRAY_NEVER_INSTRUMENT {
+#define XRAY_FLAG(Type, Name, DefaultValue, Description)                       \
+  RegisterFlag(P, #Name, Description, &F->Name);
+#include "xray_basic_flags.inc"
+#undef XRAY_FLAG
+}
+
+const char *useCompilerDefinedBasicFlags() XRAY_NEVER_INSTRUMENT {
+#ifdef XRAY_BASIC_OPTIONS
+  return SANITIZER_STRINGIFY(XRAY_BASIC_OPTIONS);
+#else
+  return "";
+#endif
+}
+
+} // namespace __xray
diff --git a/compiler-rt/lib/xray/xray_basic_flags.h b/compiler-rt/lib/xray/xray_basic_flags.h
new file mode 100644 (file)
index 0000000..041578f
--- /dev/null
@@ -0,0 +1,38 @@
+//===-- xray_basic_flags.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instruementation system.
+//
+// XRay Basic Mode runtime flags.
+//===----------------------------------------------------------------------===//
+
+#ifndef XRAY_BASIC_FLAGS_H
+#define XRAY_BASIC_FLAGS_H
+
+#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
+
+namespace __xray {
+
+struct BasicFlags {
+#define XRAY_FLAG(Type, Name, DefaultValue, Description) Type Name;
+#include "xray_basic_flags.inc"
+#undef XRAY_FLAG
+
+  void setDefaults();
+};
+
+extern BasicFlags xray_basic_flags_dont_use_directly;
+extern void registerXRayBasicFlags(FlagParser *P, BasicFlags *F);
+const char *useCompilerDefinedBasicFlags();
+inline BasicFlags *basicFlags() { return &xray_basic_flags_dont_use_directly; }
+
+} // namespace __xray
+
+#endif // XRAY_BASIC_FLAGS_H
diff --git a/compiler-rt/lib/xray/xray_basic_flags.inc b/compiler-rt/lib/xray/xray_basic_flags.inc
new file mode 100644 (file)
index 0000000..327735b
--- /dev/null
@@ -0,0 +1,24 @@
+//===-- xray_basic_flags.inc ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// XRay runtime flags.
+//
+//===----------------------------------------------------------------------===//
+#ifndef XRAY_FLAG
+#error "Define XRAY_FLAG prior to including this file!"
+#endif
+
+XRAY_FLAG(int, func_duration_threshold_us, 5,
+          "Basic logging will try to skip functions that execute for fewer "
+          "microseconds than this threshold.")
+XRAY_FLAG(int, max_stack_depth, 64,
+          "Basic logging will keep track of at most this deep a call stack, "
+          "any more and the recordings will be dropped.")
+XRAY_FLAG(int, thread_buffer_size, 1024,
+          "The number of entries to keep on a per-thread buffer.")
similarity index 87%
rename from compiler-rt/lib/xray/xray_inmemory_log.cc
rename to compiler-rt/lib/xray/xray_basic_logging.cc
index 4d11896..f984de3 100644 (file)
@@ -1,4 +1,4 @@
-//===-- xray_inmemory_log.cc ------------------------------------*- C++ -*-===//
+//===-- xray_basic_logging.cc -----------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
 #include "sanitizer_common/sanitizer_allocator_internal.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "xray/xray_records.h"
+#include "xray_basic_flags.h"
+#include "xray_basic_logging.h"
 #include "xray_defs.h"
 #include "xray_flags.h"
-#include "xray_inmemory_log.h"
 #include "xray_interface_internal.h"
 #include "xray_tsc.h"
 #include "xray_utils.h"
@@ -371,11 +372,6 @@ static void TLDDestructor(void *P) XRAY_NEVER_INSTRUMENT {
 XRayLogInitStatus basicLoggingInit(size_t BufferSize, size_t BufferMax,
                                    void *Options,
                                    size_t OptionsSize) XRAY_NEVER_INSTRUMENT {
-  static bool UNUSED Once = [] {
-    pthread_key_create(&PThreadKey, TLDDestructor);
-    return false;
-  }();
-
   uint8_t Expected = 0;
   if (!__sanitizer::atomic_compare_exchange_strong(
           &BasicInitialized, &Expected, 1, __sanitizer::memory_order_acq_rel)) {
@@ -384,10 +380,45 @@ XRayLogInitStatus basicLoggingInit(size_t BufferSize, size_t BufferMax,
     return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
   }
 
-  if (OptionsSize != sizeof(BasicLoggingOptions)) {
+  static bool UNUSED Once = [] {
+    pthread_key_create(&PThreadKey, TLDDestructor);
+    return false;
+  }();
+
+  if (BufferSize == 0 && BufferMax == 0 && Options != nullptr) {
+    FlagParser P;
+    BasicFlags F;
+    F.setDefaults();
+    registerXRayBasicFlags(&P, &F);
+    P.ParseString(useCompilerDefinedBasicFlags());
+    auto *EnvOpts = GetEnv("XRAY_BASIC_OPTIONS");
+    if (EnvOpts == nullptr)
+      EnvOpts = "";
+
+    P.ParseString(EnvOpts);
+
+    // If XRAY_BASIC_OPTIONS was not defined, then we use the deprecated options
+    // set through XRAY_OPTIONS instead.
+    if (internal_strlen(EnvOpts) == 0) {
+      F.func_duration_threshold_us =
+          flags()->xray_naive_log_func_duration_threshold_us;
+      F.max_stack_depth = flags()->xray_naive_log_max_stack_depth;
+      F.thread_buffer_size = flags()->xray_naive_log_thread_buffer_size;
+    }
+
+    P.ParseString(static_cast<const char *>(Options));
+    GlobalOptions.ThreadBufferSize = F.thread_buffer_size;
+    GlobalOptions.DurationFilterMicros = F.func_duration_threshold_us;
+    GlobalOptions.MaxStackDepth = F.max_stack_depth;
+  } else if (OptionsSize != sizeof(BasicLoggingOptions)) {
     Report("Invalid options size, potential ABI mismatch; expected %d got %d",
            sizeof(BasicLoggingOptions), OptionsSize);
     return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
+  } else {
+    if (Verbosity())
+      Report("XRay Basic: struct-based init is deprecated, please use "
+             "string-based configuration instead.\n");
+    GlobalOptions = *reinterpret_cast<BasicLoggingOptions *>(Options);
   }
 
   static auto UseRealTSC = probeRequiredCPUFeatures();
@@ -395,7 +426,6 @@ XRayLogInitStatus basicLoggingInit(size_t BufferSize, size_t BufferMax,
     Report("WARNING: Required CPU features missing for XRay instrumentation, "
            "using emulation instead.\n");
 
-  GlobalOptions = *reinterpret_cast<BasicLoggingOptions *>(Options);
   __xray_set_handler_arg1(UseRealTSC ? basicLoggingHandleArg1RealTSC
                                      : basicLoggingHandleArg1EmulateTSC);
   __xray_set_handler(UseRealTSC ? basicLoggingHandleArg0RealTSC
@@ -438,19 +468,29 @@ bool basicLogDynamicInitializer() XRAY_NEVER_INSTRUMENT {
   };
   auto RegistrationResult = __xray_log_register_mode("xray-basic", Impl);
   if (RegistrationResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK &&
-      __sanitizer::Verbosity())
+      Verbosity())
     Report("Cannot register XRay Basic Mode to 'xray-basic'; error = %d\n",
            RegistrationResult);
   if (flags()->xray_naive_log ||
-      !__sanitizer::internal_strcmp(flags()->xray_mode, "xray-basic")) {
-    __xray_set_log_impl(Impl);
-    BasicLoggingOptions Options;
-    Options.DurationFilterMicros =
-        flags()->xray_naive_log_func_duration_threshold_us;
-    Options.MaxStackDepth = flags()->xray_naive_log_max_stack_depth;
-    Options.ThreadBufferSize = flags()->xray_naive_log_thread_buffer_size;
-    __xray_log_init(flags()->xray_naive_log_thread_buffer_size, 0, &Options,
-                    sizeof(BasicLoggingOptions));
+      !internal_strcmp(flags()->xray_mode, "xray-basic")) {
+    auto SelectResult = __xray_log_select_mode("xray-basic");
+    if (SelectResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK) {
+      if (Verbosity())
+        Report("Failed selecting XRay Basic Mode; error = %d\n", SelectResult);
+      return false;
+    }
+
+    // We initialize the implementation using the data we get from the
+    // XRAY_BASIC_OPTIONS environment variable, at this point of the
+    // implementation.
+    auto *Env = GetEnv("XRAY_BASIC_OPTIONS");
+    auto InitResult =
+        __xray_log_init_mode("xray-basic", Env == nullptr ? "" : Env);
+    if (InitResult != XRayLogInitStatus::XRAY_LOG_INITIALIZED) {
+      if (Verbosity())
+        Report("Failed initializing XRay Basic Mode; error = %d\n", InitResult);
+      return false;
+    }
     static auto UNUSED Once = [] {
       static auto UNUSED &TLD = getThreadLocalData();
       __sanitizer::Atexit(+[] { TLDDestructor(&TLD); });
similarity index 95%
rename from compiler-rt/lib/xray/xray_inmemory_log.h
rename to compiler-rt/lib/xray/xray_basic_logging.h
index e4fcb8c..1639b96 100644 (file)
@@ -1,5 +1,4 @@
-//===-- xray_inmemory_log.h
-//------------------------------------------------===//
+//===-- xray_basic_logging.h ----------------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
index 746051c..c879039 100644 (file)
@@ -27,13 +27,14 @@ XRAY_FLAG(uptr, xray_page_size_override, 0,
 XRAY_FLAG(bool, xray_naive_log, false,
           "DEPRECATED: Use xray_mode=xray-basic instead.")
 XRAY_FLAG(int, xray_naive_log_func_duration_threshold_us, 5,
-          "Naive logging will try to skip functions that execute for fewer "
-          "microseconds than this threshold.")
+          "DEPRECATED: use the environment variable XRAY_BASIC_OPTIONS and set "
+          "func_duration_threshold_us instead.")
 XRAY_FLAG(int, xray_naive_log_max_stack_depth, 64,
-          "Naive logging will keep track of at most this deep a call stack, "
-          "any more and the recordings will be dropped.")
+          "DEPRECATED: use the environment variable XRAY_BASIC_OPTIONS and set "
+          "max_stack_depth instead.")
 XRAY_FLAG(int, xray_naive_log_thread_buffer_size, 1024,
-          "The number of entries to keep on a per-thread buffer.")
+          "DEPRECATED: use the environment variable XRAY_BASIC_OPTIONS and set "
+          "thread_buffer_size instead.")
 
 // FDR (Flight Data Recorder) Mode logging options.
 XRAY_FLAG(bool, xray_fdr_log, false,
index bd3f6c6..5c51ef6 100644 (file)
@@ -3,7 +3,7 @@
 
 // RUN: %clangxx_xray -std=c++11 %s -o %t -g
 // RUN: rm basic-filtering-* || true
-// RUN: XRAY_OPTIONS="patch_premain=true xray_naive_log=true verbosity=1 \
+// RUN: XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1 \
 // RUN:     xray_logfile_base=basic-filtering- \
 // RUN:     xray_naive_log_func_duration_threshold_us=1000 \
 // RUN:     xray_naive_log_max_stack_depth=2" %run %t 2>&1 | \
 // RUN:     FileCheck %s --check-prefix TRACE
 // RUN: rm basic-filtering-* || true
 //
+// Now check support for the XRAY_BASIC_OPTIONS environment variable.
+// RUN: XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1 \
+// RUN:     xray_logfile_base=basic-filtering-" \
+// RUN: XRAY_BASIC_OPTIONS="func_duration_threshold_us=1000 max_stack_depth=2" \
+// RUN:     %run %t 2>&1 | FileCheck %s
+// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
+// RUN:     "`ls basic-filtering-* | head -1`" | \
+// RUN:     FileCheck %s --check-prefix TRACE
+// RUN: rm basic-filtering-* || true
+//
 // REQUIRES: x86_64-target-arch
 // REQUIRES: built-in-llvm-tree