Index: compiler-rt/lib/xray/CMakeLists.txt =================================================================== --- compiler-rt/lib/xray/CMakeLists.txt +++ compiler-rt/lib/xray/CMakeLists.txt @@ -15,7 +15,8 @@ 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. Index: compiler-rt/lib/xray/xray_basic_flags.h =================================================================== --- /dev/null +++ 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 Index: compiler-rt/lib/xray/xray_basic_flags.cc =================================================================== --- /dev/null +++ compiler-rt/lib/xray/xray_basic_flags.cc @@ -0,0 +1,49 @@ +//===-- 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 { + +BasicFlags xray_basic_flags_dont_use_directly; // use via basicFlags(). + +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 + Index: compiler-rt/lib/xray/xray_basic_flags.inc =================================================================== --- /dev/null +++ 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.") Index: compiler-rt/lib/xray/xray_basic_logging.h =================================================================== --- compiler-rt/lib/xray/xray_basic_logging.h +++ compiler-rt/lib/xray/xray_basic_logging.h @@ -1,5 +1,4 @@ -//===-- xray_inmemory_log.h -//------------------------------------------------===// +//===-- xray_basic_logging.h ----------------------------------------------===// // // The LLVM Compiler Infrastructure // Index: compiler-rt/lib/xray/xray_basic_logging.cc =================================================================== --- compiler-rt/lib/xray/xray_basic_logging.cc +++ 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 @@ 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,40 @@ 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 && + OptionsSize == 0) { + 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 (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 { + GlobalOptions = *reinterpret_cast(Options); } static auto UseRealTSC = probeRequiredCPUFeatures(); @@ -395,7 +421,6 @@ 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 +463,29 @@ }; 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); }); Index: compiler-rt/lib/xray/xray_flags.inc =================================================================== --- compiler-rt/lib/xray/xray_flags.inc +++ compiler-rt/lib/xray/xray_flags.inc @@ -27,13 +27,14 @@ 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: compiler-rt/test/xray/TestCases/Posix/basic-filtering.cc =================================================================== --- compiler-rt/test/xray/TestCases/Posix/basic-filtering.cc +++ 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