This is an archive of the discontinued LLVM Phabricator instance.

[XRay][compiler-rt] Implement XRay Basic Mode Filtering
ClosedPublic

Authored by dberris on Dec 5 2017, 12:20 AM.

Details

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.

Diff Detail

Event Timeline

dberris created this revision.Dec 5 2017, 12:20 AM
eizan added inline comments.Dec 5 2017, 3:24 AM
compiler-rt/lib/xray/xray_inmemory_log.cc
48 ↗(On Diff #125476)

is 8 bits enough for a CPU number much longer? E.g., getcpu() on Linux returns an unsigned integer for a cpu number.

56 ↗(On Diff #125476)

Why did you change this from XRayRecord * to void *?

123 ↗(On Diff #125476)

Are there any plans to make this useable on other operating systems? What about pthread_self() instead?

173 ↗(On Diff #125476)

Why are you hard-coding this to 0 instead of getting the CPU number that the thread is running on?

dberris updated this revision to Diff 125494.Dec 5 2017, 3:52 AM
dberris marked 4 inline comments as done.
  • fixup: use __sanitizer::GetTid()
compiler-rt/lib/xray/xray_inmemory_log.cc
48 ↗(On Diff #125476)

Not for long. I was going to change this to a uint32_t, but then that means I'd have to make a larger change moving forward. In the meantime I thought it was better to be consistent with the current record data structure. We can make that change later, independently, and update the version number of the log to support the new larger CPU ID storage. For now, being consistent with the rest of the code is I think more prudent (and more manageable to change).

56 ↗(On Diff #125476)

Ah, because the original version of this code was violating strict aliasing rules. The changes here make it so that we're explicitly making the in-memory buffer character-aligned, and not running into strict aliasing errors.

123 ↗(On Diff #125476)

Yep -- found one already in sanitizer_common called __sanitizer::GetTid().

173 ↗(On Diff #125476)

Ah, ReadTSC takes a mutable reference. It will actually update CPU.

eizan accepted this revision.Dec 5 2017, 4:15 AM
This revision is now accepted and ready to land.Dec 5 2017, 4:15 AM
This revision was automatically updated to reflect the committed changes.