Summary:
Before this change, XRay would conservatively patch sections of the code
one sled at a time. Upon testing/profiling, this turns out to take an
inordinate amount of time and cycles. For an instrumented clang binary,
the cycles spent both in the patching/unpatching routine constituted 4%
of the cycles -- this didn't count the time spent in the kernel while
performing the mprotect calls in quick succession.
With this change, we're coalescing the number of calls to mprotect from
being linear to the number of instrumentation points, to now being a
lower constant when patching all the sleds through `__xray_patch()` or
`__xray_unpatch()`. In the case of calling `__xray_patch_function()` or
`__xray_unpatch_function()` we're now doing an mprotect call once for
all the sleds for that function (reduction of at least 2x calls to
mprotect).
Reviewers: kpw, eizan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D41153
llvm-svn: 320664
This change makes XRay print the log file output only when the verbosity
level is higher than 0. It reduces the log spam in the default case when
we want XRay running silently, except when there are actual
fatal/serious errors.
We also update the documentation to show how to get the information
after the change to the default behaviour.
llvm-svn: 320550
r319165 introduced a change to CMakeLists.txt for xray where the set of supported
architectures for XRay was iterated over, tested if they could be targeted then
passed to add_compiler_rt_object_libraries. However all targets were passed,
rather than the architecture that was just tested. For cases such as MIPS, where
mips and mips64 are supported, cmake would then test if mips64 could be targetted
resulting in an attempt to produce multiple identical logical target names, falling
afowl of CMP0002.
Reviewers: dberris
Differential Revision: https://reviews.llvm.org/D40890
llvm-svn: 319893
Summary:
This change implements the basic mode filtering similar to what we do in
FDR mode. The implementation is slightly simpler in basic-mode filtering
because we have less details to remember, but the idea is the same. At a
high level, we do the following to decide when to filter function call
records:
- We maintain a per-thread "shadow stack" which keeps track of the
XRay instrumented functions we've encountered in a thread's
execution.
- We push an entry onto the stack when we enter an XRay instrumented
function, and note the CPU, TSC, and type of entry (whether we have
payload or not when entering).
- When we encounter an exit event, we determine whether the function
being exited is the same function we've entered recently, was
executing in the same CPU, and the delta of the recent TSC and the
recorded TSC at the top of the stack is less than the equivalent
amount of microseconds we're configured to ignore -- then we un-wind
the record offset an appropriate number of times (so we can
overwrite the records later).
We also support limiting the stack depth of the recorded functions,
so that we don't arbitrarily write deep function call stacks.
Reviewers: eizan, pelikan, kpw, dblaikie
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D40828
llvm-svn: 319762
Summary:
This change allows for registration of multiple logging implementations
through a central mechanism in XRay, mapping an implementation to a
"mode". Modes are strings that are used as keys to determine which
implementation to install through a single API. This mechanism allows
users to choose which implementation to install either from the
environment variable 'XRAY_OPTIONS' with the `xray_mode=` flag, or
programmatically using the `__xray_select_mode(...)` function.
Here, we introduce two API functions for the XRay logging:
__xray_log_register_mode(Mode, Impl): Associates an XRayLogImpl to a
string Mode. We can only have one implementation associated with a given
Mode.
__xray_log_select_mode(Mode): Finds the associated Impl for Mode and
installs it as if by calling `__xray_set_log_impl(...)`.
Along with these changes, we also deprecate the xray_naive_log and
xray_fdr_log flags and encourage users to instead use the xray_mode
flag.
Reviewers: kpw, dblaikie, eizan, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D40703
llvm-svn: 319759
Summary:
In cases where we can't use the .preinit_array section (as in Darwin for
example) we instead use dynamic initialisation. We know that this
alternative approach will race with the initializers of other objects at
global scope, but this is strictly better than nothing.
Reviewers: kubamracek, nglevin
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D40599
llvm-svn: 319366
This renames ASM_TSAN_SYMBOL and ASM_TSAN_SYMBOL_INTERCEPTOR to just ASM_SYMBOL and ASM_SYMBOL_INTERCEPTOR, because they can be useful in more places than just TSan. Also introduce a CMake function to add ASM sources to a target.
Differential Revision: https://reviews.llvm.org/D40143
llvm-svn: 319339
rL319241 was a bit too aggressive removing sources dependencies. This
restores the actual required dependency for armhf.
Follow-up to D39114.
llvm-svn: 319255
This isolates the per-architecture files from the common files
implementing the XRay facilities. Because of the refactoring done in
D39114, we were including the definition of the sources in the archive
twice, causing link-time failures.
Follow-up to D39114.
llvm-svn: 319241
This change is the first in a series of changes to get the XRay runtime
building on macOS. This first allows us to build the minimal parts of
XRay to get us started on supporting macOS development. These include:
- CMake changes to allow targeting x86_64 initially.
- Allowing for building the initialisation routines without
`.preinit_array` support.
- Use __sanitizer::SleepForMillis() to work around the lack of
clock_nanosleep on macOS.
- Deprecate the xray_fdr_log_grace_period_us flag, and introduce
the xray_fdr_log_grace_period_ms flag instead, to use
milliseconds across platforms.
Reviewers: kubamracek
Subscribers: llvm-commits, krytarowski, nglevin, mgorny
Differential Review: https://reviews.llvm.org/D39114
llvm-svn: 319165
Summary:
Before this patch, XRay's basic (naive mode) logging would be
initialised and installed in an adhoc manner. This patch ports the
implementation of the basic (naive mode) logging implementation to use
the common XRay framework.
We also make the following changes to reduce the variance between the
usage model of basic mode from FDR (flight data recorder) mode:
- Allow programmatic control of the size of the buffers dedicated to
per-thread records. This removes some hard-coded constants and turns
them into runtime-controllable flags and through an Options
structure.
- Default the `xray_naive_log` option to false. For now, the only way
to start basic mode is to set the environment variable, or set the
default at build-time compiler options. Because of this change we've
had to update a couple of tests relying on basic mode being always
on.
- Removed the reliance on a non-trivially destructible per-thread
resource manager. We use a similar trick done in D39526 to use
pthread_key_create() and pthread_setspecific() to ensure that the
per-thread cleanup handling is performed at thread-exit time.
We also radically simplify the code structure for basic mode, to move
most of the implementation in the `__xray` namespace.
Reviewers: pelikan, eizan, kpw
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D40164
llvm-svn: 318734
Summary:
Before this change, the FDR mode implementation relied on at thread-exit
handling to return buffers back to the (global) buffer queue. This
introduces issues with the initialisation of the thread_local objects
which, even through the use of pthread_setspecific(...) may eventually
call into an allocation function. Similar to previous changes in this
line, we're finding that there is a huge potential for deadlocks when
initialising these thread-locals when the memory allocation
implementation is also xray-instrumented.
In this change, we limit the call to pthread_setspecific(...) to provide
a non-null value to associate to the key created with
pthread_key_create(...). While this doesn't completely eliminate the
potential for the deadlock(s), it does allow us to still clean up at
thread exit when we need to. The change is that we don't need to do more
work when starting and ending a thread's lifetime. We also have a test
to make sure that we actually can safely recycle the buffers in case we
end up re-using the buffer(s) available from the queue on multiple
thread entry/exits.
This change cuts across both LLVM and compiler-rt to allow us to update
both the XRay runtime implementation as well as the library support for
loading these new versions of the FDR mode logging. Version 2 of the FDR
logging implementation makes the following changes:
* Introduction of a new 'BufferExtents' metadata record that's outside
of the buffer's contents but are written before the actual buffer.
This data is associated to the Buffer handed out by the BufferQueue
rather than a record that occupies bytes in the actual buffer.
* Removal of the "end of buffer" records. This is in-line with the
changes we described above, to allow for optimistic logging without
explicit record writing at thread exit.
The optimistic logging model operates under the following assumptions:
* Threads writing to the buffers will potentially race with the thread
attempting to flush the log. To avoid this situation from occuring,
we make sure that when we've finalized the logging implementation,
that threads will see this finalization state on the next write, and
either choose to not write records the thread would have written or
write the record(s) in two phases -- first write the record(s), then
update the extents metadata.
* We change the buffer queue implementation so that once it's handed
out a buffer to a thread, that we assume that buffer is marked
"used" to be able to capture partial writes. None of this will be
safe to handle if threads are racing to write the extents records
and the reader thread is attempting to flush the log. The optimism
comes from the finalization routine being required to complete
before we attempt to flush the log.
This is a fairly significant semantics change for the FDR
implementation. This is why we've decided to update the version number
for FDR mode logs. The tools, however, still need to be able to support
older versions of the log until we finally deprecate those earlier
versions.
Reviewers: dblaikie, pelikan, kpw
Subscribers: llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D39526
llvm-svn: 318733
Summary:
This change fixes the XRay trampolines aside from the __xray_CustomEvent
trampoline to align the stack to 16-byte boundaries before calling the
handler. Before this change we've not been explicitly aligning the stack
to 16-byte boundaries, which makes it dangerous when calling handlers
that leave the stack in a state that isn't strictly 16-byte aligned
after calling the handlers.
We add a test that makes sure we can handle these cases appropriately
after the changes, and prevents us from regressing the state moving
forward.
Fixes http://llvm.org/PR35294.
Reviewers: pelikan, pcc
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D40004
llvm-svn: 318261
Summary:
This change implements the changes required in both clang and
compiler-rt to allow building XRay-instrumented binaries in Darwin. For
now we limit this to x86_64. We also start building the XRay runtime
library in compiler-rt for osx.
A caveat to this is that we don't have the tests set up and running
yet, which we'll do in a set of follow-on changes.
This patch uses the monorepo layout for the coordinated change across
multiple projects.
Reviewers: kubamracek
Subscribers: mgorny, cfe-commits, llvm-commits
Differential Revision: https://reviews.llvm.org/D39114
llvm-svn: 317875
Summary:
This change removes dependencies on STL types:
- std::aligned_storage -- we're using manually-aligned character
buffers instead for metadata and function records.
- std::tuple -- use a plain old struct instead.
This is an incremental step in removing all STL references from the
compiler-rt implementation of XRay (llvm.org/PR32274).
Reviewers: dblaikie, pelikan, kpw
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D39277
llvm-svn: 316816
Summary:
This change removes the dependency on C++ standard library
types/functions in the implementation of the buffer queue. This is an
incremental step in resolving llvm.org/PR32274.
Reviewers: dblaikie, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D39175
llvm-svn: 316406
Breaks build:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/4677/steps/build%20with%20ninja/logs/stdio
In file included from compiler-rt/lib/xray/xray_fdr_logging.cc:34:
In file included from compiler-rt/lib/xray/xray_fdr_logging_impl.h:36:
In file included from compiler-rt/lib/xray/xray_flags.h:18:
compiler-rt/lib/xray/../sanitizer_common/sanitizer_flag_parser.h:23:7: error: '__sanitizer::FlagHandlerBase' has virtual functions but non-virtual destructor [-Werror,-Wnon-virtual-dtor]
class FlagHandlerBase {
llvm-svn: 316348
Summary:
In FDR Mode, when we set up a new buffer for a thread that's just
overflowed, we must place the CPU identifier with the TSC record as the
first record. This is so that we can reconstruct all the function
entry/exit with deltas rooted on a TSC record for the CPU at the
beginning of the buffer.
Without doing this, the tools are rejecting the log for cases when we've
overflown and have different buffers that don't have the CPU and TSC
records as the first entry in the buffers.
Reviewers: pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38995
llvm-svn: 315987
Summary:
This change allows the XRay basic (naive) mode logging implementation to
start writing the payload entries through the arg1 logging handler. This
implementation writes out the records that the llvm-xray tool and the
trace reader library will start processing in D38550.
This introduces a new payload record type which logs the data through
the in-memory buffer. It uses the same size/alignment that the normal
XRay record entries use. We use a new record type to indicate these new
entries, so that the trace reader library in LLVM can start reading
these entries.
Depends on D38550.
Reviewers: pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38551
llvm-svn: 314968
Summary:
This change removes the dependency on using a std::deque<...> for the
storage of the buffers in the buffer queue. We instead implement a
fixed-size circular buffer that's resilient to exhaustion, and preserves
the semantics of the BufferQueue.
We're moving away from using std::deque<...> for two reasons:
- We want to remove dependencies on the STL for data structures.
- We want the data structure we use to not require re-allocation in
the normal course of operation.
The internal implementation of the buffer queue uses heap-allocated
arrays that are initialized once when the BufferQueue is created, and
re-uses slots in the buffer array as buffers are returned in order.
We also change the lock used in the implementation to a spinlock
instead of a blocking mutex. We reason that since the release operations
now take very little time in the critical section, that a spinlock would
be appropriate.
This change is related to D38073.
This change is a re-submit with the following changes:
- Keeping track of the live buffers with a counter independent of the
pointers keeping track of the extents of the circular buffer.
- Additional documentation of what the data members are meant to
represent.
Reviewers: dblaikie, kpw, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38119
llvm-svn: 314877
Summary:
When the XRay user calls the API to finish writing the log, the thread
which is calling the API still hasn't finished and therefore won't get
its trace written. Add a test for only the main thread to check this.
Reviewers: dberris
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38493
llvm-svn: 314875
Summary:
This change removes the dependency on using a std::deque<...> for the
storage of the buffers in the buffer queue. We instead implement a
fixed-size circular buffer that's resilient to exhaustion, and preserves
the semantics of the BufferQueue.
We're moving away from using std::deque<...> for two reasons:
- We want to remove dependencies on the STL for data structures.
- We want the data structure we use to not require re-allocation in
the normal course of operation.
The internal implementation of the buffer queue uses heap-allocated
arrays that are initialized once when the BufferQueue is created, and
re-uses slots in the buffer array as buffers are returned in order.
We also change the lock used in the implementation to a spinlock
instead of a blocking mutex. We reason that since the release operations
now take very little time in the critical section, that a spinlock would
be appropriate.
This change is related to D38073.
Reviewers: dblaikie, kpw, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38119
llvm-svn: 314766
Summary:
We avoid using C++11's thread_local keyword on non-trivially
destructible objects because it may introduce deadlocks when the C++
runtime registers destructors calling std::malloc(...). The deadlock may
happen when the allocator implementation is itself XRay instrumented.
To avoid having to call malloc(...) and free(...) in particular, we use
pthread_once, pthread_create_key, and pthread_setspecific to instead
manually register the cleanup implementation we want.
The code this replaces used an RAII type that implements the cleanup
functionality in the destructor, that was then initialized as a
function-local thread_local object. While it works in usual situations,
unfortunately it breaks when using a malloc implementation that itself
is XRay-instrumented.
Reviewers: dblaikie, kpw, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38073
llvm-svn: 314764
The function was introduced as a convenience that used to be called in
multiple places. Recent refactorings have removed the need to call this
function in multiple places, so inlined the implementation in the single
place it's defined.
Broken out from D38119.
llvm-svn: 314489
Summary:
Write out records about logged function call first arguments. D32840
implements the reading of this in llvm-xray.
Reviewers: dberris
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D32844
llvm-svn: 314378
Summary:
Remove dependency on std::unique_ptr<...> for the global representing
the installed XRay implementation.
Reviewers: dblaikie, kpw, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38121
llvm-svn: 313871
Summary:
This change starts differentiating tail exits from normal exits. We also
increase the version number of the "naive" log to version 2, which will
be the starting version where these records start appearing. In FDR mode
we treat the tail exits as normal exits, and are thus subject to the
same treatment with regard to record unwriting.
Updating the version number is important to signal older builds of the
llvm-xray tool that do not deal with the tail exit records must fail
early (and that users should only use the llvm-xray tool built after
the support for tail exits to get accurate handling of these records).
Depends on D37964.
Reviewers: kpw, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D37965
llvm-svn: 313515
Summary:
Before this change, the recursion guard for the flight data recorder
(FDR) mode handlers were independent. This change makes it so that when
a handler is already in the process of running and somehow the same or
another handler starts running -- say in a signal handler, while the
XRay handler is executing -- then we can use the same thread-local
recursion guard to stop the second handler from running.
Reviewers: kpw, eizan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D37612
llvm-svn: 312992
Summary:
Before this change we seemed to not be running the unit tests, and therefore we
set out to run them. In the process of making this happen we found a divergence
between the implementation and the tests.
This includes changes to both the CMake files as well as the implementation and
headers of the XRay runtime. We've also updated documentation on the changed
functions.
Reviewers: kpw, eizan
Subscribers: mgorny, llvm-commits
Differential Revision: https://reviews.llvm.org/D37290
llvm-svn: 312202
Summary:
This change hides all the initialization of thread_local variables used
by the XRay FDR mode implementation behind a function call. This makes
initialization of thread-local data to be done lazily, instead of
eagerly when they're done as globals. It also gives us an isolation
mechanism if/when we want to change the TLS implementation from using
the C++ thread_local keyword, for something more ad-hoc (potentialy
using pthread directly) on some platforms or set-ups where we cannot use
the C++ thread_local variables.
Reviewers: kpw, eizan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D37248
llvm-svn: 311997
Summary:
XRay has erroneously been returning the address of the first sled in the
instrumentation map for a function id instead of the (runtime-relocated)
functison address. This causes confusion and issues for applications
where:
- The first sled in the function may not be an entry sled (due to
re-ordering or some other reason).
- The caller attempts to find a symbol associated with the pointer at
runtime, because the sled may not be exactly where the function's
known address is (in case of inlined functions or those that have an
external definition for symbols).
This fixes http://llvm.org/PR34340.
Reviewers: eizan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D37202
llvm-svn: 311871
Summary:
This change introduces versions to the instrumentation map entries we
emit for XRay instrumentaiton points. The status quo for the version is
currently set to 0 (as emitted by the LLVM back-end), and versions will
count up to 255 (unsigned char).
This change is in preparation for supporting the newer version of the
custom event sleds that will be emitted by the LLVM compiler.
While we're here, we take the opportunity to stash more registers and
align the stack properly in the __xray_CustomEvent trampoline.
Reviewers: kpw, pcc, dblaikie
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36816
llvm-svn: 311524
into a function.
Most CMake configuration under compiler-rt/lib/*/tests have
almost-the-same-but-not-quite functions of the form add_X_[unit]tests
for compiling and running the tests.
Much of the logic is duplicated with minor variations across different
sub-folders.
This can harm productivity for multiple reasons:
For newcomers, resulting CMake files are very large, hard to understand,
and hide the intention of the code.
Changes for enabling certain architectures end up being unnecessarily
large, as they get duplicated across multiple folders.
Adding new sub-projects requires more effort than it should, as a
developer has to again copy-n-paste the configuration, and it's not even
clear from which sub-project it should be copy-n-pasted.
With this change the logic of compile-and-generate-a-set-of-tests is
extracted into a function, which hopefully makes writing and reading
CMake much easier.
Differential Revision: https://reviews.llvm.org/D36116
llvm-svn: 310971
Summary:
Define a build-time configuration option for the XRay runtime to
determine whether the archive will add an entry to the `.preinit_array`
section of the binary. We also allow for initializing the XRay data
structures with an explicit call to __xray_init(). This allows us to
give users the capability to initialize the XRay data structures on
demand.
This can allow us to start porting XRay to platforms where
`.preinit_array` isn't a supported section. It also allows us to limit
the effects of XRay in the initialization sequence for applications that
are sensitive to this kind of interference (i.e. large binaries) or
those that want to package XRay control in libraries.
Future changes should allow us to build two different library archives
for the XRay runtime, and allow clang users to determine which version
to link.
Reviewers: dblaikie, kpw, pelikan
Subscribers: mgorny, llvm-commits
Differential Revision: https://reviews.llvm.org/D36080
llvm-svn: 309909
Summary:
This change attempts to remove all the dependencies we have on
std::mutex and any std::shared_ptr construction in global variables. We
instead use raw pointers to these objects, and construct them on the
heap. In cases where it's possible, we lazily initialize these pointers.
While we do not have a replacement for std::shared_ptr yet in
compiler-rt, we use this work-around to avoid having to statically
initialize the objects as globals. Subsequent changes should allow us to
completely remove our dependency on std::shared_ptr and instead have our
own implementation of the std::shared_ptr and std::weak_ptr semantics
(or completely rewrite the implementaton to not need these
standard-library provided abstractions).
Reviewers: dblaikie, kpw, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36078
llvm-svn: 309792
Summary:
Currently when the XRay runtime is linked into a binary that doesn't
have the instrumentation map, we print a warning unconditionally. This
change attempts to make this behaviour more quiet.
Reviewers: kpw, pelikan
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D35789
llvm-svn: 309534
Currently there's a large amount of CMake logic duplication for
compiling sanitizer tests.
If we add more sanitizers, the duplication will get even worse.
This change factors out common compilation commands into a macro
available to all sanitizers.
llvm-svn: 309405
Summary:
This change introduces two files that show exaples of the
always/never instrument files that can be provided to clang. We don't
add these as defaults yet in clang, which we can do later on (in a
separate change).
We also add a test that makes sure that these apply in the compiler-rt
project tests, and that changes in clang don't break the expectations in
compiler-rt.
Reviewers: pelikan, kpw
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D34669
llvm-svn: 306502