diff options
author | Dean Michael Berris <dberris@google.com> | 2018-05-04 06:01:12 +0000 |
---|---|---|
committer | Dean Michael Berris <dberris@google.com> | 2018-05-04 06:01:12 +0000 |
commit | 3e5a6035832014f79af2ea233377bceddf22b9c4 (patch) | |
tree | 5a07dbd4ba423150078dd11e70e66ba7f7a665a7 | |
parent | dd13b645eb3a61963b6c50ae0f5e683ee854ba44 (diff) |
[XRay][compiler-rt+docs] Introduce __xray_log_init_mode(...).
Summary:
This addresses http://llvm.org/PR36790.
The change Deprecates a number of functions and types in
`include/xray/xray_log_interface.h` to recommend using string-based
configuration of XRay through the __xray_log_init_mode(...) function. In
particular, this deprecates the following:
- `__xray_set_log_impl(...)` -- users should instead use the
`__xray_log_register_mode(...)` and `__xray_log_select_mode(...)` APIs.
- `__xray_log_init(...)` -- users should instead use the
`__xray_log_init_mode(...)` function, which also requires using the
`__xray_log_register_mode(...)` and `__xray_log_select_mode(...)`
functionality.
- `__xray::FDRLoggingOptions` -- in following patches, we'll be
migrating the FDR logging implementations (and tests) to use the
string-based configuration. In later stages we'll remove the
`__xray::FDRLoggingOptions` type, and ask users to migrate to using the
string-based configuration mechanism instead.
- `__xray::BasicLoggingOptions` -- same as `__xray::FDRLoggingOptions`,
we'll be removing this type later and instead rely exclusively on the
string-based configuration API.
We also update the documentation to reflect the new advice and remove
some of the deprecated notes.
Reviewers: eizan, kpw, echristo, pelikan
Reviewed By: kpw
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D46173
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@331503 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/xray/xray_log_interface.h | 82 | ||||
-rw-r--r-- | lib/xray/xray_log_interface.cc | 41 | ||||
-rw-r--r-- | test/xray/TestCases/Posix/logging-modes.cc | 29 |
3 files changed, 121 insertions, 31 deletions
diff --git a/include/xray/xray_log_interface.h b/include/xray/xray_log_interface.h index 5b24b5f40..5f8b3a4a0 100644 --- a/include/xray/xray_log_interface.h +++ b/include/xray/xray_log_interface.h @@ -21,27 +21,29 @@ /// /// The high-level usage pattern for these APIs look like the following: /// -/// // Before we try initializing the log implementation, we must set it as -/// // the log implementation. We provide the function pointers that define -/// // the various initialization, finalization, and other pluggable hooks -/// // that we need. -/// __xray_set_log_impl({...}); -/// -/// // Once that's done, we can now initialize the implementation. Each -/// // implementation has a chance to let users customize the implementation -/// // with a struct that their implementation supports. Roughly this might -/// // look like: -/// MyImplementationOptions opts; -/// opts.enable_feature = true; -/// ... -/// auto init_status = __xray_log_init( -/// BufferSize, MaxBuffers, &opts, sizeof opts); -/// if (init_status != XRayLogInitStatus::XRAY_LOG_INITIALIZED) { +/// // We choose the mode which we'd like to install, and check whether this +/// // has succeeded. Each mode will have their own set of flags they will +/// // support, outside of the global XRay configuration options that are +/// // defined in the XRAY_OPTIONS environment variable. +/// auto select_status = __xray_log_select_mode("xray-fdr"); +/// if (select_status != XRayLogRegisterStatus::XRAY_REGISTRATION_OK) { +/// // This failed, we should not proceed with attempting to initialise +/// // the currently selected mode. +/// return; +/// } +/// +/// // Once that's done, we can now attempt to configure the implementation. +/// // To do this, we provide the string flags configuration for the mode. +/// auto config_status = __xray_log_init_mode( +/// "xray-fdr", "verbosity=1 some_flag=1 another_flag=2"); +/// if (config_status != XRayLogInitStatus::XRAY_LOG_INITIALIZED) { /// // deal with the error here, if there is one. /// } /// /// // When the log implementation has had the chance to initialize, we can -/// // now patch the sleds. +/// // now patch the instrumentation points. Note that we could have patched +/// // the instrumentation points first, but there's no strict ordering to +/// // these operations. /// auto patch_status = __xray_patch(); /// if (patch_status != XRayPatchingStatus::SUCCESS) { /// // deal with the error here, if it is an error. @@ -56,12 +58,12 @@ /// /// // We can optionally wait before flushing the log to give other threads a /// // chance to see that the implementation is already finalized. Also, at -/// // this point we can optionally unpatch the sleds to reduce overheads at -/// // runtime. +/// // this point we can optionally unpatch the instrumentation points to +/// // reduce overheads at runtime. /// auto unpatch_status = __xray_unpatch(); /// if (unpatch_status != XRayPatchingStatus::SUCCESS) { -// // deal with the error here, if it is an error. -// } +/// // deal with the error here, if it is an error. +/// } /// /// // If there are logs or data to be flushed somewhere, we can do so only /// // after we've finalized the log. Some implementations may not actually @@ -193,9 +195,13 @@ struct XRayLogImpl { XRayLogFlushStatus (*flush_log)(); }; +/// DEPRECATED: Use the mode registration workflow instead with +/// __xray_log_register_mode(...) and __xray_log_select_mode(...). See the +/// documentation for those function. +/// /// This function installs a new logging implementation that XRay will use. In /// case there are any nullptr members in Impl, XRay will *uninstall any -/// existing implementations*. It does NOT patch the instrumentation sleds. +/// existing implementations*. It does NOT patch the instrumentation points. /// /// NOTE: This function does NOT attempt to finalize the currently installed /// implementation. Use with caution. @@ -245,7 +251,7 @@ const char *__xray_log_get_current_mode(); /// This function removes the currently installed implementation. It will also /// uninstall any handlers that have been previously installed. It does NOT -/// unpatch the instrumentation sleds. +/// unpatch the instrumentation points. /// /// NOTE: This function does NOT attempt to finalize the currently installed /// implementation. Use with caution. @@ -260,11 +266,37 @@ const char *__xray_log_get_current_mode(); /// called while in any other states. void __xray_remove_log_impl(); +/// DEPRECATED: Use __xray_log_init_mode() instead, and provide all the options +/// in string form. /// Invokes the installed implementation initialization routine. See /// XRayLogInitStatus for what the return values mean. XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers, void *Args, size_t ArgsSize); +/// Invokes the installed initialization routine, which *must* support the +/// string based form. +/// +/// NOTE: When this API is used, we still invoke the installed initialization +/// routine, but we will call it with the following convention to signal that we +/// are using the string form: +/// +/// - BufferSize = 0 +/// - MaxBuffers = 0 +/// - ArgsSize = 0 +/// - Args will be the pointer to the character buffer representing the +/// configuration. +/// +/// FIXME: Updating the XRayLogImpl struct is an ABI breaking change. When we +/// are ready to make a breaking change, we should clean this up appropriately. +XRayLogInitStatus __xray_log_init_mode(const char *Mode, const char *Config); + +/// Like __xray_log_init_mode(...) this version allows for providing +/// configurations that might have non-null-terminated strings. This will +/// operate similarly to __xray_log_init_mode, with the exception that +/// |ArgsSize| will be what |ConfigSize| is. +XRayLogInitStatus __xray_log_init_mode_bin(const char *Mode, const char *Config, + size_t ConfigSize); + /// Invokes the installed implementation finalization routine. See /// XRayLogInitStatus for what the return values mean. XRayLogInitStatus __xray_log_finalize(); @@ -325,12 +357,16 @@ XRayLogFlushStatus __xray_log_process_buffers(void (*Processor)(const char *, namespace __xray { +/// DEPRECATED: Use __xray_log_init_mode(...) instead, and provide flag +/// configuration strings to set the options instead. /// Options used by the LLVM XRay FDR logging implementation. struct FDRLoggingOptions { bool ReportErrors = false; int Fd = -1; }; +/// DEPRECATED: Use __xray_log_init_mode(...) instead, and provide flag +/// configuration strings to set the options instead. /// Options used by the LLVM XRay Basic (Naive) logging implementation. struct BasicLoggingOptions { int DurationFilterMicros = 0; diff --git a/lib/xray/xray_log_interface.cc b/lib/xray/xray_log_interface.cc index 78b2060dd..aa3fcc835 100644 --- a/lib/xray/xray_log_interface.cc +++ b/lib/xray/xray_log_interface.cc @@ -139,6 +139,47 @@ XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers, return GlobalXRayImpl->log_init(BufferSize, MaxBuffers, Args, ArgsSize); } +XRayLogInitStatus __xray_log_init_mode(const char *Mode, const char *Config) + XRAY_NEVER_INSTRUMENT { + __sanitizer::SpinMutexLock Guard(&XRayImplMutex); + if (!GlobalXRayImpl) + return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; + + if (Config == nullptr) + return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; + + // Check first whether the current mode is the same as what we expect. + if (CurrentMode == nullptr || internal_strcmp(CurrentMode->Mode, Mode) != 0) + return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; + + // Here we do some work to coerce the pointer we're provided, so that + // the implementations that still take void* pointers can handle the + // data provided in the Config argument. + return GlobalXRayImpl->log_init( + 0, 0, const_cast<void *>(static_cast<const void *>(Config)), 0); +} + +XRayLogInitStatus +__xray_log_init_mode_bin(const char *Mode, const char *Config, + size_t ConfigSize) XRAY_NEVER_INSTRUMENT { + __sanitizer::SpinMutexLock Guard(&XRayImplMutex); + if (!GlobalXRayImpl) + return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; + + if (Config == nullptr) + return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; + + // Check first whether the current mode is the same as what we expect. + if (CurrentMode == nullptr || internal_strcmp(CurrentMode->Mode, Mode) != 0) + return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; + + // Here we do some work to coerce the pointer we're provided, so that + // the implementations that still take void* pointers can handle the + // data provided in the Config argument. + return GlobalXRayImpl->log_init( + 0, 0, const_cast<void *>(static_cast<const void *>(Config)), ConfigSize); +} + XRayLogInitStatus __xray_log_finalize() XRAY_NEVER_INSTRUMENT { __sanitizer::SpinMutexLock Guard(&XRayImplMutex); if (!GlobalXRayImpl) diff --git a/test/xray/TestCases/Posix/logging-modes.cc b/test/xray/TestCases/Posix/logging-modes.cc index b846cf675..26dac3554 100644 --- a/test/xray/TestCases/Posix/logging-modes.cc +++ b/test/xray/TestCases/Posix/logging-modes.cc @@ -1,6 +1,7 @@ // Check that we can install an implementation associated with a mode. // -// RUN: %clangxx_xray -std=c++11 %s -o %t +// RUN: rm xray-log.logging-modes* || true +// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=none // RUN: %run %t | FileCheck %s // // UNSUPPORTED: target-is-mips64,target-is-mips64el @@ -31,8 +32,18 @@ assert(false && "Invalid buffer provided."); } +static constexpr char Options[] = "additional_flags"; + [[clang::xray_never_instrument]] XRayLogInitStatus -printing_init(size_t, size_t, void *, size_t) { +printing_init(size_t BufferSize, size_t MaxBuffers, void *Config, + size_t ArgsSize) { + // We require that the printing init is called through the + // __xray_log_init_mode(...) implementation, and that the promised contract is + // enforced. + assert(BufferSize == 0); + assert(MaxBuffers == 0); + assert(Config != nullptr); + assert(ArgsSize == 0 || ArgsSize == sizeof(Options)); __xray_log_set_buffer_iterator(next_buffer); return XRayLogInitStatus::XRAY_LOG_INITIALIZED; } @@ -52,23 +63,25 @@ static auto buffer_counter = 0; void process_buffer(const char *, XRayBuffer) { ++buffer_counter; } -static bool unused = [] { +int main(int argc, char **argv) { assert(__xray_log_register_mode("custom", {printing_init, printing_finalize, printing_handler, printing_flush_log}) == XRayLogRegisterStatus::XRAY_REGISTRATION_OK); - return true; -}(); - -int main(int argc, char **argv) { assert(__xray_log_select_mode("custom") == XRayLogRegisterStatus::XRAY_REGISTRATION_OK); assert(__xray_log_get_current_mode() != nullptr); std::string current_mode = __xray_log_get_current_mode(); assert(current_mode == "custom"); assert(__xray_patch() == XRayPatchingStatus::SUCCESS); - assert(__xray_log_init(0, 0, nullptr, 0) == + assert(__xray_log_init_mode("custom", "flags_config_here=true") == XRayLogInitStatus::XRAY_LOG_INITIALIZED); + + // Also test that we can use the "binary" version of the + // __xray_log_niit_mode(...) API. + assert(__xray_log_init_mode_bin("custom", Options, sizeof(Options)) == + XRayLogInitStatus::XRAY_LOG_INITIALIZED); + // CHECK: printing {{.*}} callme(); // CHECK: called me! // CHECK: printing {{.*}} |