From 47e6b8c2c74e18d1f3bf30a52790e1f1aafea5cc Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 4 May 2018 06:27:53 +0000 Subject: [PATCH] [XRay][compiler-rt] Support string-based config for Basic mode. 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 | 3 +- compiler-rt/lib/xray/xray_basic_flags.cc | 50 ++++++++++++++ compiler-rt/lib/xray/xray_basic_flags.h | 38 +++++++++++ compiler-rt/lib/xray/xray_basic_flags.inc | 24 +++++++ ...{xray_inmemory_log.cc => xray_basic_logging.cc} | 78 ++++++++++++++++------ .../{xray_inmemory_log.h => xray_basic_logging.h} | 3 +- compiler-rt/lib/xray/xray_flags.inc | 11 +-- .../test/xray/TestCases/Posix/basic-filtering.cc | 12 +++- 8 files changed, 191 insertions(+), 28 deletions(-) create mode 100644 compiler-rt/lib/xray/xray_basic_flags.cc create mode 100644 compiler-rt/lib/xray/xray_basic_flags.h create mode 100644 compiler-rt/lib/xray/xray_basic_flags.inc rename compiler-rt/lib/xray/{xray_inmemory_log.cc => xray_basic_logging.cc} (87%) rename compiler-rt/lib/xray/{xray_inmemory_log.h => xray_basic_logging.h} (95%) diff --git a/compiler-rt/lib/xray/CMakeLists.txt b/compiler-rt/lib/xray/CMakeLists.txt index 58b5665..7954411 100644 --- a/compiler-rt/lib/xray/CMakeLists.txt +++ b/compiler-rt/lib/xray/CMakeLists.txt @@ -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 index 0000000..14d805c --- /dev/null +++ b/compiler-rt/lib/xray/xray_basic_flags.cc @@ -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 index 0000000..041578f --- /dev/null +++ b/compiler-rt/lib/xray/xray_basic_flags.h @@ -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 index 0000000..327735b --- /dev/null +++ b/compiler-rt/lib/xray/xray_basic_flags.inc @@ -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.") diff --git a/compiler-rt/lib/xray/xray_inmemory_log.cc b/compiler-rt/lib/xray/xray_basic_logging.cc 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 --- a/compiler-rt/lib/xray/xray_inmemory_log.cc +++ b/compiler-rt/lib/xray/xray_basic_logging.cc @@ -1,4 +1,4 @@ -//===-- xray_inmemory_log.cc ------------------------------------*- C++ -*-===// +//===-- xray_basic_logging.cc -----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -29,9 +29,10 @@ #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(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(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(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); }); diff --git a/compiler-rt/lib/xray/xray_inmemory_log.h b/compiler-rt/lib/xray/xray_basic_logging.h 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 --- a/compiler-rt/lib/xray/xray_inmemory_log.h +++ b/compiler-rt/lib/xray/xray_basic_logging.h @@ -1,5 +1,4 @@ -//===-- xray_inmemory_log.h -//------------------------------------------------===// +//===-- xray_basic_logging.h ----------------------------------------------===// // // The LLVM Compiler Infrastructure // diff --git a/compiler-rt/lib/xray/xray_flags.inc b/compiler-rt/lib/xray/xray_flags.inc index 746051c..c879039 100644 --- a/compiler-rt/lib/xray/xray_flags.inc +++ b/compiler-rt/lib/xray/xray_flags.inc @@ -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, diff --git a/compiler-rt/test/xray/TestCases/Posix/basic-filtering.cc b/compiler-rt/test/xray/TestCases/Posix/basic-filtering.cc index bd3f6c6..5c51ef6 100644 --- a/compiler-rt/test/xray/TestCases/Posix/basic-filtering.cc +++ b/compiler-rt/test/xray/TestCases/Posix/basic-filtering.cc @@ -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 | \ @@ -13,6 +13,16 @@ // 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 -- 2.7.4