Skip to content

Commit 3e5a603

Browse files
committed
[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
1 parent dd13b64 commit 3e5a603

File tree

3 files changed

+121
-31
lines changed

3 files changed

+121
-31
lines changed

include/xray/xray_log_interface.h

+59-23
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,29 @@
2121
///
2222
/// The high-level usage pattern for these APIs look like the following:
2323
///
24-
/// // Before we try initializing the log implementation, we must set it as
25-
/// // the log implementation. We provide the function pointers that define
26-
/// // the various initialization, finalization, and other pluggable hooks
27-
/// // that we need.
28-
/// __xray_set_log_impl({...});
29-
///
30-
/// // Once that's done, we can now initialize the implementation. Each
31-
/// // implementation has a chance to let users customize the implementation
32-
/// // with a struct that their implementation supports. Roughly this might
33-
/// // look like:
34-
/// MyImplementationOptions opts;
35-
/// opts.enable_feature = true;
36-
/// ...
37-
/// auto init_status = __xray_log_init(
38-
/// BufferSize, MaxBuffers, &opts, sizeof opts);
39-
/// if (init_status != XRayLogInitStatus::XRAY_LOG_INITIALIZED) {
24+
/// // We choose the mode which we'd like to install, and check whether this
25+
/// // has succeeded. Each mode will have their own set of flags they will
26+
/// // support, outside of the global XRay configuration options that are
27+
/// // defined in the XRAY_OPTIONS environment variable.
28+
/// auto select_status = __xray_log_select_mode("xray-fdr");
29+
/// if (select_status != XRayLogRegisterStatus::XRAY_REGISTRATION_OK) {
30+
/// // This failed, we should not proceed with attempting to initialise
31+
/// // the currently selected mode.
32+
/// return;
33+
/// }
34+
///
35+
/// // Once that's done, we can now attempt to configure the implementation.
36+
/// // To do this, we provide the string flags configuration for the mode.
37+
/// auto config_status = __xray_log_init_mode(
38+
/// "xray-fdr", "verbosity=1 some_flag=1 another_flag=2");
39+
/// if (config_status != XRayLogInitStatus::XRAY_LOG_INITIALIZED) {
4040
/// // deal with the error here, if there is one.
4141
/// }
4242
///
4343
/// // When the log implementation has had the chance to initialize, we can
44-
/// // now patch the sleds.
44+
/// // now patch the instrumentation points. Note that we could have patched
45+
/// // the instrumentation points first, but there's no strict ordering to
46+
/// // these operations.
4547
/// auto patch_status = __xray_patch();
4648
/// if (patch_status != XRayPatchingStatus::SUCCESS) {
4749
/// // deal with the error here, if it is an error.
@@ -56,12 +58,12 @@
5658
///
5759
/// // We can optionally wait before flushing the log to give other threads a
5860
/// // chance to see that the implementation is already finalized. Also, at
59-
/// // this point we can optionally unpatch the sleds to reduce overheads at
60-
/// // runtime.
61+
/// // this point we can optionally unpatch the instrumentation points to
62+
/// // reduce overheads at runtime.
6163
/// auto unpatch_status = __xray_unpatch();
6264
/// if (unpatch_status != XRayPatchingStatus::SUCCESS) {
63-
// // deal with the error here, if it is an error.
64-
// }
65+
/// // deal with the error here, if it is an error.
66+
/// }
6567
///
6668
/// // If there are logs or data to be flushed somewhere, we can do so only
6769
/// // after we've finalized the log. Some implementations may not actually
@@ -193,9 +195,13 @@ struct XRayLogImpl {
193195
XRayLogFlushStatus (*flush_log)();
194196
};
195197

198+
/// DEPRECATED: Use the mode registration workflow instead with
199+
/// __xray_log_register_mode(...) and __xray_log_select_mode(...). See the
200+
/// documentation for those function.
201+
///
196202
/// This function installs a new logging implementation that XRay will use. In
197203
/// case there are any nullptr members in Impl, XRay will *uninstall any
198-
/// existing implementations*. It does NOT patch the instrumentation sleds.
204+
/// existing implementations*. It does NOT patch the instrumentation points.
199205
///
200206
/// NOTE: This function does NOT attempt to finalize the currently installed
201207
/// implementation. Use with caution.
@@ -245,7 +251,7 @@ const char *__xray_log_get_current_mode();
245251

246252
/// This function removes the currently installed implementation. It will also
247253
/// uninstall any handlers that have been previously installed. It does NOT
248-
/// unpatch the instrumentation sleds.
254+
/// unpatch the instrumentation points.
249255
///
250256
/// NOTE: This function does NOT attempt to finalize the currently installed
251257
/// implementation. Use with caution.
@@ -260,11 +266,37 @@ const char *__xray_log_get_current_mode();
260266
/// called while in any other states.
261267
void __xray_remove_log_impl();
262268

269+
/// DEPRECATED: Use __xray_log_init_mode() instead, and provide all the options
270+
/// in string form.
263271
/// Invokes the installed implementation initialization routine. See
264272
/// XRayLogInitStatus for what the return values mean.
265273
XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers,
266274
void *Args, size_t ArgsSize);
267275

276+
/// Invokes the installed initialization routine, which *must* support the
277+
/// string based form.
278+
///
279+
/// NOTE: When this API is used, we still invoke the installed initialization
280+
/// routine, but we will call it with the following convention to signal that we
281+
/// are using the string form:
282+
///
283+
/// - BufferSize = 0
284+
/// - MaxBuffers = 0
285+
/// - ArgsSize = 0
286+
/// - Args will be the pointer to the character buffer representing the
287+
/// configuration.
288+
///
289+
/// FIXME: Updating the XRayLogImpl struct is an ABI breaking change. When we
290+
/// are ready to make a breaking change, we should clean this up appropriately.
291+
XRayLogInitStatus __xray_log_init_mode(const char *Mode, const char *Config);
292+
293+
/// Like __xray_log_init_mode(...) this version allows for providing
294+
/// configurations that might have non-null-terminated strings. This will
295+
/// operate similarly to __xray_log_init_mode, with the exception that
296+
/// |ArgsSize| will be what |ConfigSize| is.
297+
XRayLogInitStatus __xray_log_init_mode_bin(const char *Mode, const char *Config,
298+
size_t ConfigSize);
299+
268300
/// Invokes the installed implementation finalization routine. See
269301
/// XRayLogInitStatus for what the return values mean.
270302
XRayLogInitStatus __xray_log_finalize();
@@ -325,12 +357,16 @@ XRayLogFlushStatus __xray_log_process_buffers(void (*Processor)(const char *,
325357

326358
namespace __xray {
327359

360+
/// DEPRECATED: Use __xray_log_init_mode(...) instead, and provide flag
361+
/// configuration strings to set the options instead.
328362
/// Options used by the LLVM XRay FDR logging implementation.
329363
struct FDRLoggingOptions {
330364
bool ReportErrors = false;
331365
int Fd = -1;
332366
};
333367

368+
/// DEPRECATED: Use __xray_log_init_mode(...) instead, and provide flag
369+
/// configuration strings to set the options instead.
334370
/// Options used by the LLVM XRay Basic (Naive) logging implementation.
335371
struct BasicLoggingOptions {
336372
int DurationFilterMicros = 0;

lib/xray/xray_log_interface.cc

+41
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,47 @@ XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers,
139139
return GlobalXRayImpl->log_init(BufferSize, MaxBuffers, Args, ArgsSize);
140140
}
141141

142+
XRayLogInitStatus __xray_log_init_mode(const char *Mode, const char *Config)
143+
XRAY_NEVER_INSTRUMENT {
144+
__sanitizer::SpinMutexLock Guard(&XRayImplMutex);
145+
if (!GlobalXRayImpl)
146+
return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
147+
148+
if (Config == nullptr)
149+
return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
150+
151+
// Check first whether the current mode is the same as what we expect.
152+
if (CurrentMode == nullptr || internal_strcmp(CurrentMode->Mode, Mode) != 0)
153+
return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
154+
155+
// Here we do some work to coerce the pointer we're provided, so that
156+
// the implementations that still take void* pointers can handle the
157+
// data provided in the Config argument.
158+
return GlobalXRayImpl->log_init(
159+
0, 0, const_cast<void *>(static_cast<const void *>(Config)), 0);
160+
}
161+
162+
XRayLogInitStatus
163+
__xray_log_init_mode_bin(const char *Mode, const char *Config,
164+
size_t ConfigSize) XRAY_NEVER_INSTRUMENT {
165+
__sanitizer::SpinMutexLock Guard(&XRayImplMutex);
166+
if (!GlobalXRayImpl)
167+
return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
168+
169+
if (Config == nullptr)
170+
return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
171+
172+
// Check first whether the current mode is the same as what we expect.
173+
if (CurrentMode == nullptr || internal_strcmp(CurrentMode->Mode, Mode) != 0)
174+
return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
175+
176+
// Here we do some work to coerce the pointer we're provided, so that
177+
// the implementations that still take void* pointers can handle the
178+
// data provided in the Config argument.
179+
return GlobalXRayImpl->log_init(
180+
0, 0, const_cast<void *>(static_cast<const void *>(Config)), ConfigSize);
181+
}
182+
142183
XRayLogInitStatus __xray_log_finalize() XRAY_NEVER_INSTRUMENT {
143184
__sanitizer::SpinMutexLock Guard(&XRayImplMutex);
144185
if (!GlobalXRayImpl)

test/xray/TestCases/Posix/logging-modes.cc

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Check that we can install an implementation associated with a mode.
22
//
3-
// RUN: %clangxx_xray -std=c++11 %s -o %t
3+
// RUN: rm xray-log.logging-modes* || true
4+
// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=none
45
// RUN: %run %t | FileCheck %s
56
//
67
// UNSUPPORTED: target-is-mips64,target-is-mips64el
@@ -31,8 +32,18 @@
3132
assert(false && "Invalid buffer provided.");
3233
}
3334

35+
static constexpr char Options[] = "additional_flags";
36+
3437
[[clang::xray_never_instrument]] XRayLogInitStatus
35-
printing_init(size_t, size_t, void *, size_t) {
38+
printing_init(size_t BufferSize, size_t MaxBuffers, void *Config,
39+
size_t ArgsSize) {
40+
// We require that the printing init is called through the
41+
// __xray_log_init_mode(...) implementation, and that the promised contract is
42+
// enforced.
43+
assert(BufferSize == 0);
44+
assert(MaxBuffers == 0);
45+
assert(Config != nullptr);
46+
assert(ArgsSize == 0 || ArgsSize == sizeof(Options));
3647
__xray_log_set_buffer_iterator(next_buffer);
3748
return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
3849
}
@@ -52,23 +63,25 @@ static auto buffer_counter = 0;
5263

5364
void process_buffer(const char *, XRayBuffer) { ++buffer_counter; }
5465

55-
static bool unused = [] {
66+
int main(int argc, char **argv) {
5667
assert(__xray_log_register_mode("custom",
5768
{printing_init, printing_finalize,
5869
printing_handler, printing_flush_log}) ==
5970
XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
60-
return true;
61-
}();
62-
63-
int main(int argc, char **argv) {
6471
assert(__xray_log_select_mode("custom") ==
6572
XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
6673
assert(__xray_log_get_current_mode() != nullptr);
6774
std::string current_mode = __xray_log_get_current_mode();
6875
assert(current_mode == "custom");
6976
assert(__xray_patch() == XRayPatchingStatus::SUCCESS);
70-
assert(__xray_log_init(0, 0, nullptr, 0) ==
77+
assert(__xray_log_init_mode("custom", "flags_config_here=true") ==
7178
XRayLogInitStatus::XRAY_LOG_INITIALIZED);
79+
80+
// Also test that we can use the "binary" version of the
81+
// __xray_log_niit_mode(...) API.
82+
assert(__xray_log_init_mode_bin("custom", Options, sizeof(Options)) ==
83+
XRayLogInitStatus::XRAY_LOG_INITIALIZED);
84+
7285
// CHECK: printing {{.*}}
7386
callme(); // CHECK: called me!
7487
// CHECK: printing {{.*}}

0 commit comments

Comments
 (0)