diff options
author | Dean Michael Berris <dberris@google.com> | 2018-05-04 06:13:35 +0000 |
---|---|---|
committer | Dean Michael Berris <dberris@google.com> | 2018-05-04 06:13:35 +0000 |
commit | eebc67fc29382a7505890e517e1d9eedae5c4f57 (patch) | |
tree | 2dc38831223fecfe4ec03a5318464b170579195d /lib/xray | |
parent | 3e5a6035832014f79af2ea233377bceddf22b9c4 (diff) |
[XRay][compiler-rt] Support string-based config for FDR mode
Summary:
In this chage we add support for the string-based configuration
mechanism for configuring FDR mode.
We deprecate most of the `xray_fdr_log_*` flags that are set with the
`XRAY_OPTIONS` environment variable. Instead we make the FDR
implementation take defaults from the `XRAY_FDR_OPTIONS` environment
variable, and use the flags defined in `xray_fdr_flags.{h,cc,inc}` for
the options we support.
This change addresses http://llvm.org/PR36790.
Depends on D46173.
Reviewers: eizan, pelikan, kpw, echristo
Subscribers: llvm-commits, mgorny
Differential Revision: https://reviews.llvm.org/D46174
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@331506 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/xray')
-rw-r--r-- | lib/xray/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/xray/xray_fdr_flags.cc | 48 | ||||
-rw-r--r-- | lib/xray/xray_fdr_flags.h | 38 | ||||
-rw-r--r-- | lib/xray/xray_fdr_flags.inc | 27 | ||||
-rw-r--r-- | lib/xray/xray_fdr_logging.cc | 97 | ||||
-rw-r--r-- | lib/xray/xray_flags.cc | 13 | ||||
-rw-r--r-- | lib/xray/xray_flags.h | 2 | ||||
-rw-r--r-- | lib/xray/xray_flags.inc | 12 |
8 files changed, 189 insertions, 49 deletions
diff --git a/lib/xray/CMakeLists.txt b/lib/xray/CMakeLists.txt index 22aa4d3de..58b566576 100644 --- a/lib/xray/CMakeLists.txt +++ b/lib/xray/CMakeLists.txt @@ -10,6 +10,7 @@ set(XRAY_SOURCES # Implementation files for all XRay modes. set(XRAY_FDR_MODE_SOURCES + xray_fdr_flags.cc xray_buffer_queue.cc xray_fdr_logging.cc) diff --git a/lib/xray/xray_fdr_flags.cc b/lib/xray/xray_fdr_flags.cc new file mode 100644 index 000000000..a14851b1b --- /dev/null +++ b/lib/xray/xray_fdr_flags.cc @@ -0,0 +1,48 @@ +//===-- xray_fdr_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 FDR flag parsing logic. +//===----------------------------------------------------------------------===// + +#include "xray_fdr_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 { + +FDRFlags xray_fdr_flags_dont_use_directly; // use via fdrFlags(). + +void FDRFlags::setDefaults() XRAY_NEVER_INSTRUMENT { +#define XRAY_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; +#include "xray_fdr_flags.inc" +#undef XRAY_FLAG +} + +void registerXRayFDRFlags(FlagParser *P, FDRFlags *F) XRAY_NEVER_INSTRUMENT { +#define XRAY_FLAG(Type, Name, DefaultValue, Description) \ + RegisterFlag(P, #Name, Description, &F->Name); +#include "xray_fdr_flags.inc" +#undef XRAY_FLAG +} + +const char *useCompilerDefinedFDRFlags() XRAY_NEVER_INSTRUMENT { +#ifdef XRAY_FDR_OPTIONS + return SANITIZER_STRINGIFY(XRAY_FDR_OPTIONS); +#else + return ""; +#endif +} + +} // namespace __xray diff --git a/lib/xray/xray_fdr_flags.h b/lib/xray/xray_fdr_flags.h new file mode 100644 index 000000000..9c953f1ca --- /dev/null +++ b/lib/xray/xray_fdr_flags.h @@ -0,0 +1,38 @@ +//===-- xray_fdr_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 instrumentation system. +// +// This file defines the flags for the flight-data-recorder mode implementation. +// +//===----------------------------------------------------------------------===// +#ifndef XRAY_FDR_FLAGS_H +#define XRAY_FDR_FLAGS_H + +#include "sanitizer_common/sanitizer_flag_parser.h" +#include "sanitizer_common/sanitizer_internal_defs.h" + +namespace __xray { + +struct FDRFlags { +#define XRAY_FLAG(Type, Name, DefaultValue, Description) Type Name; +#include "xray_fdr_flags.inc" +#undef XRAY_FLAG + + void setDefaults(); +}; + +extern FDRFlags xray_fdr_flags_dont_use_directly; +extern void registerXRayFDRFlags(FlagParser *P, FDRFlags *F); +const char *useCompilerDefinedFDRFlags(); +inline FDRFlags *fdrFlags() { return &xray_fdr_flags_dont_use_directly; } + +} // namespace __xray + +#endif // XRAY_FDR_FLAGS_H diff --git a/lib/xray/xray_fdr_flags.inc b/lib/xray/xray_fdr_flags.inc new file mode 100644 index 000000000..7815738a1 --- /dev/null +++ b/lib/xray/xray_fdr_flags.inc @@ -0,0 +1,27 @@ +//===-- xray_fdr_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 FDR Mode runtime flags. +// +//===----------------------------------------------------------------------===// +#ifndef XRAY_FLAG +#error "Define XRAY_FLAG prior to including this file!" +#endif + +// FDR (Flight Data Recorder) Mode logging options. +XRAY_FLAG(int, func_duration_threshold_us, 5, + "FDR logging will try to skip functions that execute for fewer " + "microseconds than this threshold.") +XRAY_FLAG(int, grace_period_ms, 100, + "FDR logging will wait this much time in milliseconds before " + "actually flushing the log; this gives a chance for threads to " + "notice that the log has been finalized and clean up.") +XRAY_FLAG(int, buffer_size, 16384, + "Size of buffers in the circular buffer queue.") +XRAY_FLAG(int, buffer_max, 100, "Maximum number of buffers in the queue.") diff --git a/lib/xray/xray_fdr_logging.cc b/lib/xray/xray_fdr_logging.cc index fcb33fc87..d666733c4 100644 --- a/lib/xray/xray_fdr_logging.cc +++ b/lib/xray/xray_fdr_logging.cc @@ -27,6 +27,7 @@ #include "xray/xray_records.h" #include "xray_buffer_queue.h" #include "xray_defs.h" +#include "xray_fdr_flags.h" #include "xray_fdr_logging_impl.h" #include "xray_flags.h" #include "xray_tsc.h" @@ -72,7 +73,7 @@ XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT { // We wait a number of milliseconds to allow threads to see that we've // finalised before attempting to flush the log. - __sanitizer::SleepForMillis(flags()->xray_fdr_log_grace_period_ms); + __sanitizer::SleepForMillis(fdrFlags()->grace_period_ms); // We write out the file in the following format: // @@ -83,8 +84,12 @@ XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT { // (fixed-sized) and let the tools reading the buffers deal with the data // afterwards. // + // FIXME: Support the case for letting users handle the data through + // __xray_process_buffers(...) and provide an option to skip writing files. int Fd = -1; { + // FIXME: Remove this section of the code, when we remove the struct-based + // configuration API. __sanitizer::SpinMutexLock Guard(&FDROptionsMutex); Fd = FDROptions.Fd; } @@ -168,33 +173,6 @@ XRayLogInitStatus fdrLoggingFinalize() XRAY_NEVER_INSTRUMENT { return XRayLogInitStatus::XRAY_LOG_FINALIZED; } -XRayLogInitStatus fdrLoggingReset() XRAY_NEVER_INSTRUMENT { - s32 CurrentStatus = XRayLogInitStatus::XRAY_LOG_FINALIZED; - if (__sanitizer::atomic_compare_exchange_strong( - &LoggingStatus, &CurrentStatus, - XRayLogInitStatus::XRAY_LOG_INITIALIZED, - __sanitizer::memory_order_release)) - return static_cast<XRayLogInitStatus>(CurrentStatus); - - // Release the in-memory buffer queue. - delete BQ; - BQ = nullptr; - - // Spin until the flushing status is flushed. - s32 CurrentFlushingStatus = XRayLogFlushStatus::XRAY_LOG_FLUSHED; - while (__sanitizer::atomic_compare_exchange_weak( - &LogFlushStatus, &CurrentFlushingStatus, - XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING, - __sanitizer::memory_order_release)) { - if (CurrentFlushingStatus == XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING) - break; - CurrentFlushingStatus = XRayLogFlushStatus::XRAY_LOG_FLUSHED; - } - - // At this point, we know that the status is flushed, and that we can assume - return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; -} - struct TSCAndCPU { uint64_t TSC = 0; unsigned char CPU = 0; @@ -346,16 +324,12 @@ void fdrLoggingHandleTypedEvent( endBufferIfFull(); } -XRayLogInitStatus fdrLoggingInit(std::size_t BufferSize, std::size_t BufferMax, +XRayLogInitStatus fdrLoggingInit(size_t BufferSize, size_t BufferMax, void *Options, size_t OptionsSize) XRAY_NEVER_INSTRUMENT { - if (OptionsSize != sizeof(FDRLoggingOptions)) { - if (__sanitizer::Verbosity()) - Report("Cannot initialize FDR logging; wrong size for options: %d\n", - OptionsSize); - return static_cast<XRayLogInitStatus>(__sanitizer::atomic_load( - &LoggingStatus, __sanitizer::memory_order_acquire)); - } + if (Options == nullptr) + return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; + s32 CurrentStatus = XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; if (!__sanitizer::atomic_compare_exchange_strong( &LoggingStatus, &CurrentStatus, @@ -366,7 +340,56 @@ XRayLogInitStatus fdrLoggingInit(std::size_t BufferSize, std::size_t BufferMax, return static_cast<XRayLogInitStatus>(CurrentStatus); } - { + // Because of __xray_log_init_mode(...) which guarantees that this will be + // called with BufferSize == 0 and BufferMax == 0 we parse the configuration + // provided in the Options pointer as a string instead. + if (BufferSize == 0 && BufferMax == 0) { + if (__sanitizer::Verbosity()) + Report("Initializing FDR mode with options: %s\n", + static_cast<const char *>(Options)); + + // TODO: Factor out the flags specific to the FDR mode implementation. For + // now, use the global/single definition of the flags, since the FDR mode + // flags are already defined there. + FlagParser FDRParser; + FDRFlags FDRFlags; + registerXRayFDRFlags(&FDRParser, &FDRFlags); + FDRFlags.setDefaults(); + + // Override first from the general XRAY_DEFAULT_OPTIONS compiler-provided + // options until we migrate everyone to use the XRAY_FDR_OPTIONS + // compiler-provided options. + FDRParser.ParseString(useCompilerDefinedFlags()); + FDRParser.ParseString(useCompilerDefinedFDRFlags()); + auto *EnvOpts = GetEnv("XRAY_FDR_OPTIONS"); + if (EnvOpts == nullptr) + EnvOpts = ""; + FDRParser.ParseString(EnvOpts); + FDRParser.ParseString(static_cast<const char *>(Options)); + *fdrFlags() = FDRFlags; + + BufferSize = FDRFlags.buffer_size; + BufferMax = FDRFlags.buffer_max; + + // FIXME: Remove this when we fully remove the deprecated flags. + if (internal_strlen(EnvOpts) != 0) { + flags()->xray_fdr_log_func_duration_threshold_us = + FDRFlags.func_duration_threshold_us; + flags()->xray_fdr_log_grace_period_ms = FDRFlags.grace_period_ms; + } + } else if (OptionsSize != sizeof(FDRLoggingOptions)) { + // FIXME: This is deprecated, and should really be removed. + // At this point we use the flag parser specific to the FDR mode + // implementation. + if (__sanitizer::Verbosity()) + Report("Cannot initialize FDR logging; wrong size for options: %d\n", + OptionsSize); + return static_cast<XRayLogInitStatus>(__sanitizer::atomic_load( + &LoggingStatus, __sanitizer::memory_order_acquire)); + } else { + if (__sanitizer::Verbosity()) + Report("XRay FDR: struct-based init is deprecated, please use " + "string-based configuration instead.\n"); __sanitizer::SpinMutexLock Guard(&FDROptionsMutex); memcpy(&FDROptions, Options, OptionsSize); } diff --git a/lib/xray/xray_flags.cc b/lib/xray/xray_flags.cc index ced1a5214..b50b68666 100644 --- a/lib/xray/xray_flags.cc +++ b/lib/xray/xray_flags.cc @@ -30,7 +30,7 @@ void Flags::setDefaults() XRAY_NEVER_INSTRUMENT { #undef XRAY_FLAG } -static void registerXRayFlags(FlagParser *P, Flags *F) XRAY_NEVER_INSTRUMENT { +void registerXRayFlags(FlagParser *P, Flags *F) XRAY_NEVER_INSTRUMENT { #define XRAY_FLAG(Type, Name, DefaultValue, Description) \ RegisterFlag(P, #Name, Description, &F->Name); #include "xray_flags.inc" @@ -42,12 +42,13 @@ static void registerXRayFlags(FlagParser *P, Flags *F) XRAY_NEVER_INSTRUMENT { // options that control XRay. This means users/deployments can tweak the // defaults that override the hard-coded defaults in the xray_flags.inc at // compile-time using the XRAY_DEFAULT_OPTIONS macro. -static const char *useCompilerDefinedFlags() XRAY_NEVER_INSTRUMENT { +const char *useCompilerDefinedFlags() XRAY_NEVER_INSTRUMENT { #ifdef XRAY_DEFAULT_OPTIONS -// Do the double-layered string conversion to prevent badly crafted strings -// provided through the XRAY_DEFAULT_OPTIONS from causing compilation issues (or -// changing the semantics of the implementation through the macro). This ensures -// that we convert whatever XRAY_DEFAULT_OPTIONS is defined as a string literal. + // Do the double-layered string conversion to prevent badly crafted strings + // provided through the XRAY_DEFAULT_OPTIONS from causing compilation issues + // (or changing the semantics of the implementation through the macro). This + // ensures that we convert whatever XRAY_DEFAULT_OPTIONS is defined as a + // string literal. return SANITIZER_STRINGIFY(XRAY_DEFAULT_OPTIONS); #else return ""; diff --git a/lib/xray/xray_flags.h b/lib/xray/xray_flags.h index 3ed5b8844..7c1ba9458 100644 --- a/lib/xray/xray_flags.h +++ b/lib/xray/xray_flags.h @@ -29,6 +29,8 @@ struct Flags { }; extern Flags xray_flags_dont_use_directly; +extern void registerXRayFlags(FlagParser *P, Flags *F); +const char *useCompilerDefinedFlags(); inline Flags *flags() { return &xray_flags_dont_use_directly; } void initializeFlags(); diff --git a/lib/xray/xray_flags.inc b/lib/xray/xray_flags.inc index 181ed3d7f..746051c55 100644 --- a/lib/xray/xray_flags.inc +++ b/lib/xray/xray_flags.inc @@ -39,11 +39,11 @@ XRAY_FLAG(int, xray_naive_log_thread_buffer_size, 1024, XRAY_FLAG(bool, xray_fdr_log, false, "DEPRECATED: Use xray_mode=xray-fdr instead.") XRAY_FLAG(int, xray_fdr_log_func_duration_threshold_us, 5, - "FDR logging will try to skip functions that execute for fewer " - "microseconds than this threshold.") + "DEPRECATED: use the environment variable XRAY_FDR_OPTIONS and set " + "func_duration_threshold_us instead.") XRAY_FLAG(int, xray_fdr_log_grace_period_us, 0, - "DEPRECATED: use xray_fdr_log_grace_period_ms instead.") + "DEPRECATED: use the environment variable XRAY_FDR_OPTIONS and set " + "grace_period_ms instead.") XRAY_FLAG(int, xray_fdr_log_grace_period_ms, 100, - "FDR logging will wait this much time in microseconds before " - "actually flushing the log; this gives a chance for threads to " - "notice that the log has been finalized and clean up.") + "DEPRECATED: use the environment variable XRAY_FDR_OPTIONS and set " + "grace_period_ms instead.") |