summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2018-05-04 06:01:12 +0000
committerDean Michael Berris <dberris@google.com>2018-05-04 06:01:12 +0000
commit3e5a6035832014f79af2ea233377bceddf22b9c4 (patch)
tree5a07dbd4ba423150078dd11e70e66ba7f7a665a7
parentdd13b645eb3a61963b6c50ae0f5e683ee854ba44 (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.h82
-rw-r--r--lib/xray/xray_log_interface.cc41
-rw-r--r--test/xray/TestCases/Posix/logging-modes.cc29
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 {{.*}}