[compiler-rt] r331507 - [XRay][compiler-rt] Support string-based config for Basic mode.
Dean Michael Berris via llvm-commits
llvm-commits at lists.llvm.org
Thu May 3 23:27:53 PDT 2018
Author: dberris
Date: Thu May 3 23:27:53 2018
New Revision: 331507
URL: http://llvm.org/viewvc/llvm-project?rev=331507&view=rev
Log:
[XRay][compiler-rt] Support string-based config for Basic mode.
Summary:
This addresses http://llvm.org/PR36790.
This change allows the XRay Basic Mode implementation to use the
string-based initialization routine provided through
`__xray_log_init_mode(...)`. In the process, we've also deprecated some
flags defined for the `XRAY_OPTIONS` environment variable.
We then introduce another environment variable that can control the XRay
Basic Mode implementation through `XRAY_BASIC_OPTIONS`.
We also rename files from `xray_inmemory_log` to `xray_basic_logging` to
be more in line with the mode implementation.
Depends on D46174.
Reviewers: echristo, kpw, pelikan, eizan
Reviewed By: kpw
Subscribers: mgorny, llvm-commits
Differential Revision: https://reviews.llvm.org/D46246
Added:
compiler-rt/trunk/lib/xray/xray_basic_flags.cc
compiler-rt/trunk/lib/xray/xray_basic_flags.h
compiler-rt/trunk/lib/xray/xray_basic_flags.inc
compiler-rt/trunk/lib/xray/xray_basic_logging.cc
compiler-rt/trunk/lib/xray/xray_basic_logging.h
Removed:
compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
compiler-rt/trunk/lib/xray/xray_inmemory_log.h
Modified:
compiler-rt/trunk/lib/xray/CMakeLists.txt
compiler-rt/trunk/lib/xray/xray_flags.inc
compiler-rt/trunk/test/xray/TestCases/Posix/basic-filtering.cc
Modified: compiler-rt/trunk/lib/xray/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/CMakeLists.txt?rev=331507&r1=331506&r2=331507&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/xray/CMakeLists.txt Thu May 3 23:27:53 2018
@@ -15,7 +15,8 @@ set(XRAY_FDR_MODE_SOURCES
xray_fdr_logging.cc)
set(XRAY_BASIC_MODE_SOURCES
- xray_inmemory_log.cc)
+ xray_basic_flags.cc
+ xray_basic_logging.cc)
# Implementation files for all XRay architectures.
Added: compiler-rt/trunk/lib/xray/xray_basic_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_basic_flags.cc?rev=331507&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_basic_flags.cc (added)
+++ compiler-rt/trunk/lib/xray/xray_basic_flags.cc Thu May 3 23:27:53 2018
@@ -0,0 +1,50 @@
+//===-- xray_basic_flags.cc -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// XRay Basic flag parsing logic.
+//===----------------------------------------------------------------------===//
+
+#include "xray_basic_flags.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "xray_defs.h"
+
+using namespace __sanitizer;
+
+namespace __xray {
+
+/// Use via basicFlags().
+BasicFlags xray_basic_flags_dont_use_directly;
+
+void BasicFlags::setDefaults() XRAY_NEVER_INSTRUMENT {
+#define XRAY_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
+#include "xray_basic_flags.inc"
+#undef XRAY_FLAG
+}
+
+void registerXRayBasicFlags(FlagParser *P,
+ BasicFlags *F) XRAY_NEVER_INSTRUMENT {
+#define XRAY_FLAG(Type, Name, DefaultValue, Description) \
+ RegisterFlag(P, #Name, Description, &F->Name);
+#include "xray_basic_flags.inc"
+#undef XRAY_FLAG
+}
+
+const char *useCompilerDefinedBasicFlags() XRAY_NEVER_INSTRUMENT {
+#ifdef XRAY_BASIC_OPTIONS
+ return SANITIZER_STRINGIFY(XRAY_BASIC_OPTIONS);
+#else
+ return "";
+#endif
+}
+
+} // namespace __xray
Added: compiler-rt/trunk/lib/xray/xray_basic_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_basic_flags.h?rev=331507&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_basic_flags.h (added)
+++ compiler-rt/trunk/lib/xray/xray_basic_flags.h Thu May 3 23:27:53 2018
@@ -0,0 +1,38 @@
+//===-- xray_basic_flags.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instruementation system.
+//
+// XRay Basic Mode runtime flags.
+//===----------------------------------------------------------------------===//
+
+#ifndef XRAY_BASIC_FLAGS_H
+#define XRAY_BASIC_FLAGS_H
+
+#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
+
+namespace __xray {
+
+struct BasicFlags {
+#define XRAY_FLAG(Type, Name, DefaultValue, Description) Type Name;
+#include "xray_basic_flags.inc"
+#undef XRAY_FLAG
+
+ void setDefaults();
+};
+
+extern BasicFlags xray_basic_flags_dont_use_directly;
+extern void registerXRayBasicFlags(FlagParser *P, BasicFlags *F);
+const char *useCompilerDefinedBasicFlags();
+inline BasicFlags *basicFlags() { return &xray_basic_flags_dont_use_directly; }
+
+} // namespace __xray
+
+#endif // XRAY_BASIC_FLAGS_H
Added: compiler-rt/trunk/lib/xray/xray_basic_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_basic_flags.inc?rev=331507&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_basic_flags.inc (added)
+++ compiler-rt/trunk/lib/xray/xray_basic_flags.inc Thu May 3 23:27:53 2018
@@ -0,0 +1,24 @@
+//===-- xray_basic_flags.inc ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// XRay runtime flags.
+//
+//===----------------------------------------------------------------------===//
+#ifndef XRAY_FLAG
+#error "Define XRAY_FLAG prior to including this file!"
+#endif
+
+XRAY_FLAG(int, func_duration_threshold_us, 5,
+ "Basic logging will try to skip functions that execute for fewer "
+ "microseconds than this threshold.")
+XRAY_FLAG(int, max_stack_depth, 64,
+ "Basic logging will keep track of at most this deep a call stack, "
+ "any more and the recordings will be dropped.")
+XRAY_FLAG(int, thread_buffer_size, 1024,
+ "The number of entries to keep on a per-thread buffer.")
Added: compiler-rt/trunk/lib/xray/xray_basic_logging.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_basic_logging.cc?rev=331507&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_basic_logging.cc (added)
+++ compiler-rt/trunk/lib/xray/xray_basic_logging.cc Thu May 3 23:27:53 2018
@@ -0,0 +1,505 @@
+//===-- xray_basic_logging.cc -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// Implementation of a simple in-memory log of XRay events. This defines a
+// logging function that's compatible with the XRay handler interface, and
+// routines for exporting data to files.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cassert>
+#include <cstring>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "sanitizer_common/sanitizer_allocator_internal.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "xray/xray_records.h"
+#include "xray_basic_flags.h"
+#include "xray_basic_logging.h"
+#include "xray_defs.h"
+#include "xray_flags.h"
+#include "xray_interface_internal.h"
+#include "xray_tsc.h"
+#include "xray_utils.h"
+
+namespace __xray {
+
+__sanitizer::SpinMutex LogMutex;
+
+// We use elements of this type to record the entry TSC of every function ID we
+// see as we're tracing a particular thread's execution.
+struct alignas(16) StackEntry {
+ int32_t FuncId;
+ uint16_t Type;
+ uint8_t CPU;
+ uint8_t Padding;
+ uint64_t TSC;
+};
+
+static_assert(sizeof(StackEntry) == 16, "Wrong size for StackEntry");
+
+struct alignas(64) ThreadLocalData {
+ void *InMemoryBuffer = nullptr;
+ size_t BufferSize = 0;
+ size_t BufferOffset = 0;
+ void *ShadowStack = nullptr;
+ size_t StackSize = 0;
+ size_t StackEntries = 0;
+ int Fd = -1;
+ tid_t TID = 0;
+};
+
+static pthread_key_t PThreadKey;
+
+static __sanitizer::atomic_uint8_t BasicInitialized{0};
+
+BasicLoggingOptions GlobalOptions;
+
+thread_local volatile bool RecursionGuard = false;
+
+static uint64_t thresholdTicks() XRAY_NEVER_INSTRUMENT {
+ static uint64_t TicksPerSec = probeRequiredCPUFeatures()
+ ? getTSCFrequency()
+ : __xray::NanosecondsPerSecond;
+ static const uint64_t ThresholdTicks =
+ TicksPerSec * GlobalOptions.DurationFilterMicros / 1000000;
+ return ThresholdTicks;
+}
+
+static int openLogFile() XRAY_NEVER_INSTRUMENT {
+ int F = getLogFD();
+ if (F == -1)
+ return -1;
+
+ // Test for required CPU features and cache the cycle frequency
+ static bool TSCSupported = probeRequiredCPUFeatures();
+ static uint64_t CycleFrequency =
+ TSCSupported ? getTSCFrequency() : __xray::NanosecondsPerSecond;
+
+ // Since we're here, we get to write the header. We set it up so that the
+ // header will only be written once, at the start, and let the threads
+ // logging do writes which just append.
+ XRayFileHeader Header;
+ Header.Version = 2; // Version 2 includes tail exit records.
+ Header.Type = FileTypes::NAIVE_LOG;
+ Header.CycleFrequency = CycleFrequency;
+
+ // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc'
+ // before setting the values in the header.
+ Header.ConstantTSC = 1;
+ Header.NonstopTSC = 1;
+ retryingWriteAll(F, reinterpret_cast<char *>(&Header),
+ reinterpret_cast<char *>(&Header) + sizeof(Header));
+ return F;
+}
+
+int getGlobalFd() XRAY_NEVER_INSTRUMENT {
+ static int Fd = openLogFile();
+ return Fd;
+}
+
+ThreadLocalData &getThreadLocalData() XRAY_NEVER_INSTRUMENT {
+ thread_local ThreadLocalData TLD;
+ thread_local bool UNUSED TOnce = [] {
+ if (GlobalOptions.ThreadBufferSize == 0) {
+ if (__sanitizer::Verbosity())
+ Report("Not initializing TLD since ThreadBufferSize == 0.\n");
+ return false;
+ }
+ TLD.TID = __sanitizer::GetTid();
+ pthread_setspecific(PThreadKey, &TLD);
+ TLD.Fd = getGlobalFd();
+ TLD.InMemoryBuffer = reinterpret_cast<XRayRecord *>(
+ InternalAlloc(sizeof(XRayRecord) * GlobalOptions.ThreadBufferSize,
+ nullptr, alignof(XRayRecord)));
+ TLD.BufferSize = GlobalOptions.ThreadBufferSize;
+ TLD.BufferOffset = 0;
+ if (GlobalOptions.MaxStackDepth == 0) {
+ if (__sanitizer::Verbosity())
+ Report("Not initializing the ShadowStack since MaxStackDepth == 0.\n");
+ TLD.StackSize = 0;
+ TLD.StackEntries = 0;
+ TLD.ShadowStack = nullptr;
+ return false;
+ }
+ TLD.ShadowStack = reinterpret_cast<StackEntry *>(
+ InternalAlloc(sizeof(StackEntry) * GlobalOptions.MaxStackDepth, nullptr,
+ alignof(StackEntry)));
+ TLD.StackSize = GlobalOptions.MaxStackDepth;
+ TLD.StackEntries = 0;
+ if (__sanitizer::Verbosity() >= 2) {
+ static auto UNUSED Once = [] {
+ auto ticks = thresholdTicks();
+ Report("Ticks threshold: %d\n", ticks);
+ return false;
+ }();
+ }
+ return false;
+ }();
+ return TLD;
+}
+
+template <class RDTSC>
+void InMemoryRawLog(int32_t FuncId, XRayEntryType Type,
+ RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
+ auto &TLD = getThreadLocalData();
+ int Fd = getGlobalFd();
+ if (Fd == -1)
+ return;
+
+ // Use a simple recursion guard, to handle cases where we're already logging
+ // and for one reason or another, this function gets called again in the same
+ // thread.
+ if (RecursionGuard)
+ return;
+ RecursionGuard = true;
+ auto ExitGuard = __sanitizer::at_scope_exit([] { RecursionGuard = false; });
+
+ uint8_t CPU = 0;
+ uint64_t TSC = ReadTSC(CPU);
+
+ switch (Type) {
+ case XRayEntryType::ENTRY:
+ case XRayEntryType::LOG_ARGS_ENTRY: {
+ // Short circuit if we've reached the maximum depth of the stack.
+ if (TLD.StackEntries++ >= TLD.StackSize)
+ return;
+
+ // When we encounter an entry event, we keep track of the TSC and the CPU,
+ // and put it in the stack.
+ StackEntry E;
+ E.FuncId = FuncId;
+ E.CPU = CPU;
+ E.Type = Type;
+ E.TSC = TSC;
+ auto StackEntryPtr = static_cast<char *>(TLD.ShadowStack) +
+ (sizeof(StackEntry) * (TLD.StackEntries - 1));
+ __sanitizer::internal_memcpy(StackEntryPtr, &E, sizeof(StackEntry));
+ break;
+ }
+ case XRayEntryType::EXIT:
+ case XRayEntryType::TAIL: {
+ if (TLD.StackEntries == 0)
+ break;
+
+ if (--TLD.StackEntries >= TLD.StackSize)
+ return;
+
+ // When we encounter an exit event, we check whether all the following are
+ // true:
+ //
+ // - The Function ID is the same as the most recent entry in the stack.
+ // - The CPU is the same as the most recent entry in the stack.
+ // - The Delta of the TSCs is less than the threshold amount of time we're
+ // looking to record.
+ //
+ // If all of these conditions are true, we pop the stack and don't write a
+ // record and move the record offset back.
+ StackEntry StackTop;
+ auto StackEntryPtr = static_cast<char *>(TLD.ShadowStack) +
+ (sizeof(StackEntry) * TLD.StackEntries);
+ __sanitizer::internal_memcpy(&StackTop, StackEntryPtr, sizeof(StackEntry));
+ if (StackTop.FuncId == FuncId && StackTop.CPU == CPU &&
+ StackTop.TSC < TSC) {
+ auto Delta = TSC - StackTop.TSC;
+ if (Delta < thresholdTicks()) {
+ assert(TLD.BufferOffset > 0);
+ TLD.BufferOffset -= StackTop.Type == XRayEntryType::ENTRY ? 1 : 2;
+ return;
+ }
+ }
+ break;
+ }
+ default:
+ // Should be unreachable.
+ assert(false && "Unsupported XRayEntryType encountered.");
+ break;
+ }
+
+ // First determine whether the delta between the function's enter record and
+ // the exit record is higher than the threshold.
+ __xray::XRayRecord R;
+ R.RecordType = RecordTypes::NORMAL;
+ R.CPU = CPU;
+ R.TSC = TSC;
+ R.TId = TLD.TID;
+ R.Type = Type;
+ R.FuncId = FuncId;
+ auto FirstEntry = reinterpret_cast<__xray::XRayRecord *>(TLD.InMemoryBuffer);
+ __sanitizer::internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
+ if (++TLD.BufferOffset == TLD.BufferSize) {
+ __sanitizer::SpinMutexLock L(&LogMutex);
+ retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
+ reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+ TLD.BufferOffset = 0;
+ TLD.StackEntries = 0;
+ }
+}
+
+template <class RDTSC>
+void InMemoryRawLogWithArg(int32_t FuncId, XRayEntryType Type, uint64_t Arg1,
+ RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
+ auto &TLD = getThreadLocalData();
+ auto FirstEntry =
+ reinterpret_cast<__xray::XRayArgPayload *>(TLD.InMemoryBuffer);
+ const auto &BuffLen = TLD.BufferSize;
+ int Fd = getGlobalFd();
+ if (Fd == -1)
+ return;
+
+ // First we check whether there's enough space to write the data consecutively
+ // in the thread-local buffer. If not, we first flush the buffer before
+ // attempting to write the two records that must be consecutive.
+ if (TLD.BufferOffset + 2 > BuffLen) {
+ __sanitizer::SpinMutexLock L(&LogMutex);
+ retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
+ reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+ TLD.BufferOffset = 0;
+ TLD.StackEntries = 0;
+ }
+
+ // Then we write the "we have an argument" record.
+ InMemoryRawLog(FuncId, Type, ReadTSC);
+
+ if (RecursionGuard)
+ return;
+ RecursionGuard = true;
+ auto ExitGuard = __sanitizer::at_scope_exit([] { RecursionGuard = false; });
+
+ // And from here on write the arg payload.
+ __xray::XRayArgPayload R;
+ R.RecordType = RecordTypes::ARG_PAYLOAD;
+ R.FuncId = FuncId;
+ R.TId = TLD.TID;
+ R.Arg = Arg1;
+ __sanitizer::internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
+ if (++TLD.BufferOffset == BuffLen) {
+ __sanitizer::SpinMutexLock L(&LogMutex);
+ retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
+ reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+ TLD.BufferOffset = 0;
+ TLD.StackEntries = 0;
+ }
+}
+
+void basicLoggingHandleArg0RealTSC(int32_t FuncId,
+ XRayEntryType Type) XRAY_NEVER_INSTRUMENT {
+ InMemoryRawLog(FuncId, Type, __xray::readTSC);
+}
+
+void basicLoggingHandleArg0EmulateTSC(int32_t FuncId, XRayEntryType Type)
+ XRAY_NEVER_INSTRUMENT {
+ InMemoryRawLog(FuncId, Type, [](uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
+ timespec TS;
+ int result = clock_gettime(CLOCK_REALTIME, &TS);
+ if (result != 0) {
+ Report("clock_gettimg(2) return %d, errno=%d.", result, int(errno));
+ TS = {0, 0};
+ }
+ CPU = 0;
+ return TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
+ });
+}
+
+void basicLoggingHandleArg1RealTSC(int32_t FuncId, XRayEntryType Type,
+ uint64_t Arg1) XRAY_NEVER_INSTRUMENT {
+ InMemoryRawLogWithArg(FuncId, Type, Arg1, __xray::readTSC);
+}
+
+void basicLoggingHandleArg1EmulateTSC(int32_t FuncId, XRayEntryType Type,
+ uint64_t Arg1) XRAY_NEVER_INSTRUMENT {
+ InMemoryRawLogWithArg(
+ FuncId, Type, Arg1, [](uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
+ timespec TS;
+ int result = clock_gettime(CLOCK_REALTIME, &TS);
+ if (result != 0) {
+ Report("clock_gettimg(2) return %d, errno=%d.", result, int(errno));
+ TS = {0, 0};
+ }
+ CPU = 0;
+ return TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
+ });
+}
+
+static void TLDDestructor(void *P) XRAY_NEVER_INSTRUMENT {
+ ThreadLocalData &TLD = *reinterpret_cast<ThreadLocalData *>(P);
+ auto ExitGuard = __sanitizer::at_scope_exit([&TLD] {
+ // Clean up dynamic resources.
+ if (TLD.InMemoryBuffer)
+ InternalFree(TLD.InMemoryBuffer);
+ if (TLD.ShadowStack)
+ InternalFree(TLD.ShadowStack);
+ if (__sanitizer::Verbosity())
+ Report("Cleaned up log for TID: %d\n", TLD.TID);
+ });
+
+ if (TLD.Fd == -1 || TLD.BufferOffset == 0) {
+ if (__sanitizer::Verbosity())
+ Report("Skipping buffer for TID: %d; Fd = %d; Offset = %llu\n", TLD.TID,
+ TLD.Fd, TLD.BufferOffset);
+ return;
+ }
+
+ {
+ __sanitizer::SpinMutexLock L(&LogMutex);
+ retryingWriteAll(TLD.Fd, reinterpret_cast<char *>(TLD.InMemoryBuffer),
+ reinterpret_cast<char *>(TLD.InMemoryBuffer) +
+ (sizeof(__xray::XRayRecord) * TLD.BufferOffset));
+ }
+
+ // Because this thread's exit could be the last one trying to write to
+ // the file and that we're not able to close out the file properly, we
+ // sync instead and hope that the pending writes are flushed as the
+ // thread exits.
+ fsync(TLD.Fd);
+}
+
+XRayLogInitStatus basicLoggingInit(size_t BufferSize, size_t BufferMax,
+ void *Options,
+ size_t OptionsSize) XRAY_NEVER_INSTRUMENT {
+ uint8_t Expected = 0;
+ if (!__sanitizer::atomic_compare_exchange_strong(
+ &BasicInitialized, &Expected, 1, __sanitizer::memory_order_acq_rel)) {
+ if (__sanitizer::Verbosity())
+ Report("Basic logging already initialized.\n");
+ return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
+ }
+
+ static bool UNUSED Once = [] {
+ pthread_key_create(&PThreadKey, TLDDestructor);
+ return false;
+ }();
+
+ if (BufferSize == 0 && BufferMax == 0 && Options != nullptr) {
+ FlagParser P;
+ BasicFlags F;
+ F.setDefaults();
+ registerXRayBasicFlags(&P, &F);
+ P.ParseString(useCompilerDefinedBasicFlags());
+ auto *EnvOpts = GetEnv("XRAY_BASIC_OPTIONS");
+ if (EnvOpts == nullptr)
+ EnvOpts = "";
+
+ P.ParseString(EnvOpts);
+
+ // If XRAY_BASIC_OPTIONS was not defined, then we use the deprecated options
+ // set through XRAY_OPTIONS instead.
+ if (internal_strlen(EnvOpts) == 0) {
+ F.func_duration_threshold_us =
+ flags()->xray_naive_log_func_duration_threshold_us;
+ F.max_stack_depth = flags()->xray_naive_log_max_stack_depth;
+ F.thread_buffer_size = flags()->xray_naive_log_thread_buffer_size;
+ }
+
+ P.ParseString(static_cast<const char *>(Options));
+ GlobalOptions.ThreadBufferSize = F.thread_buffer_size;
+ GlobalOptions.DurationFilterMicros = F.func_duration_threshold_us;
+ GlobalOptions.MaxStackDepth = F.max_stack_depth;
+ } else if (OptionsSize != sizeof(BasicLoggingOptions)) {
+ Report("Invalid options size, potential ABI mismatch; expected %d got %d",
+ sizeof(BasicLoggingOptions), OptionsSize);
+ return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
+ } else {
+ if (Verbosity())
+ Report("XRay Basic: struct-based init is deprecated, please use "
+ "string-based configuration instead.\n");
+ GlobalOptions = *reinterpret_cast<BasicLoggingOptions *>(Options);
+ }
+
+ static auto UseRealTSC = probeRequiredCPUFeatures();
+ if (!UseRealTSC && __sanitizer::Verbosity())
+ Report("WARNING: Required CPU features missing for XRay instrumentation, "
+ "using emulation instead.\n");
+
+ __xray_set_handler_arg1(UseRealTSC ? basicLoggingHandleArg1RealTSC
+ : basicLoggingHandleArg1EmulateTSC);
+ __xray_set_handler(UseRealTSC ? basicLoggingHandleArg0RealTSC
+ : basicLoggingHandleArg0EmulateTSC);
+ __xray_remove_customevent_handler();
+ __xray_remove_typedevent_handler();
+
+ return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
+}
+
+XRayLogInitStatus basicLoggingFinalize() XRAY_NEVER_INSTRUMENT {
+ uint8_t Expected = 0;
+ if (!__sanitizer::atomic_compare_exchange_strong(
+ &BasicInitialized, &Expected, 0, __sanitizer::memory_order_acq_rel) &&
+ __sanitizer::Verbosity())
+ Report("Basic logging already finalized.\n");
+
+ // Nothing really to do aside from marking state of the global to be
+ // uninitialized.
+
+ return XRayLogInitStatus::XRAY_LOG_FINALIZED;
+}
+
+XRayLogFlushStatus basicLoggingFlush() XRAY_NEVER_INSTRUMENT {
+ // This really does nothing, since flushing the logs happen at the end of a
+ // thread's lifetime, or when the buffers are full.
+ return XRayLogFlushStatus::XRAY_LOG_FLUSHED;
+}
+
+// This is a handler that, effectively, does nothing.
+void basicLoggingHandleArg0Empty(int32_t, XRayEntryType) XRAY_NEVER_INSTRUMENT {
+}
+
+bool basicLogDynamicInitializer() XRAY_NEVER_INSTRUMENT {
+ XRayLogImpl Impl{
+ basicLoggingInit,
+ basicLoggingFinalize,
+ basicLoggingHandleArg0Empty,
+ basicLoggingFlush,
+ };
+ auto RegistrationResult = __xray_log_register_mode("xray-basic", Impl);
+ if (RegistrationResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK &&
+ Verbosity())
+ Report("Cannot register XRay Basic Mode to 'xray-basic'; error = %d\n",
+ RegistrationResult);
+ if (flags()->xray_naive_log ||
+ !internal_strcmp(flags()->xray_mode, "xray-basic")) {
+ auto SelectResult = __xray_log_select_mode("xray-basic");
+ if (SelectResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK) {
+ if (Verbosity())
+ Report("Failed selecting XRay Basic Mode; error = %d\n", SelectResult);
+ return false;
+ }
+
+ // We initialize the implementation using the data we get from the
+ // XRAY_BASIC_OPTIONS environment variable, at this point of the
+ // implementation.
+ auto *Env = GetEnv("XRAY_BASIC_OPTIONS");
+ auto InitResult =
+ __xray_log_init_mode("xray-basic", Env == nullptr ? "" : Env);
+ if (InitResult != XRayLogInitStatus::XRAY_LOG_INITIALIZED) {
+ if (Verbosity())
+ Report("Failed initializing XRay Basic Mode; error = %d\n", InitResult);
+ return false;
+ }
+ static auto UNUSED Once = [] {
+ static auto UNUSED &TLD = getThreadLocalData();
+ __sanitizer::Atexit(+[] { TLDDestructor(&TLD); });
+ return false;
+ }();
+ }
+ return true;
+}
+
+} // namespace __xray
+
+static auto UNUSED Unused = __xray::basicLogDynamicInitializer();
Added: compiler-rt/trunk/lib/xray/xray_basic_logging.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_basic_logging.h?rev=331507&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_basic_logging.h (added)
+++ compiler-rt/trunk/lib/xray/xray_basic_logging.h Thu May 3 23:27:53 2018
@@ -0,0 +1,43 @@
+//===-- xray_basic_logging.h ----------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a function call tracing system.
+//
+//===----------------------------------------------------------------------===//
+#ifndef XRAY_XRAY_INMEMORY_LOG_H
+#define XRAY_XRAY_INMEMORY_LOG_H
+
+#include "xray/xray_log_interface.h"
+
+/// Basic (Naive) Mode
+/// ==================
+///
+/// This implementation hooks in through the XRay logging implementation
+/// framework. The Basic Mode implementation will keep appending to a file as
+/// soon as the thread-local buffers are full. It keeps minimal in-memory state
+/// and does the minimum filtering required to keep log files smaller.
+
+namespace __xray {
+
+XRayLogInitStatus basicLoggingInit(size_t BufferSize, size_t BufferMax,
+ void *Options, size_t OptionsSize);
+XRayLogInitStatus basicLoggingFinalize();
+
+void basicLoggingHandleArg0RealTSC(int32_t FuncId, XRayEntryType Entry);
+void basicLoggingHandleArg0EmulateTSC(int32_t FuncId, XRayEntryType Entry);
+void basicLoggingHandleArg1RealTSC(int32_t FuncId, XRayEntryType Entry,
+ uint64_t Arg1);
+void basicLoggingHandleArg1EmulateTSC(int32_t FuncId, XRayEntryType Entry,
+ uint64_t Arg1);
+XRayLogFlushStatus basicLoggingFlush();
+XRayLogInitStatus basicLoggingReset();
+
+} // namespace __xray
+
+#endif // XRAY_XRAY_INMEMORY_LOG_H
Modified: compiler-rt/trunk/lib/xray/xray_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.inc?rev=331507&r1=331506&r2=331507&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_flags.inc (original)
+++ compiler-rt/trunk/lib/xray/xray_flags.inc Thu May 3 23:27:53 2018
@@ -27,13 +27,14 @@ XRAY_FLAG(uptr, xray_page_size_override,
XRAY_FLAG(bool, xray_naive_log, false,
"DEPRECATED: Use xray_mode=xray-basic instead.")
XRAY_FLAG(int, xray_naive_log_func_duration_threshold_us, 5,
- "Naive logging will try to skip functions that execute for fewer "
- "microseconds than this threshold.")
+ "DEPRECATED: use the environment variable XRAY_BASIC_OPTIONS and set "
+ "func_duration_threshold_us instead.")
XRAY_FLAG(int, xray_naive_log_max_stack_depth, 64,
- "Naive logging will keep track of at most this deep a call stack, "
- "any more and the recordings will be dropped.")
+ "DEPRECATED: use the environment variable XRAY_BASIC_OPTIONS and set "
+ "max_stack_depth instead.")
XRAY_FLAG(int, xray_naive_log_thread_buffer_size, 1024,
- "The number of entries to keep on a per-thread buffer.")
+ "DEPRECATED: use the environment variable XRAY_BASIC_OPTIONS and set "
+ "thread_buffer_size instead.")
// FDR (Flight Data Recorder) Mode logging options.
XRAY_FLAG(bool, xray_fdr_log, false,
Removed: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_inmemory_log.cc?rev=331506&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc (removed)
@@ -1,465 +0,0 @@
-//===-- xray_inmemory_log.cc ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a dynamic runtime instrumentation system.
-//
-// Implementation of a simple in-memory log of XRay events. This defines a
-// logging function that's compatible with the XRay handler interface, and
-// routines for exporting data to files.
-//
-//===----------------------------------------------------------------------===//
-
-#include <cassert>
-#include <cstring>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "sanitizer_common/sanitizer_allocator_internal.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "xray/xray_records.h"
-#include "xray_defs.h"
-#include "xray_flags.h"
-#include "xray_inmemory_log.h"
-#include "xray_interface_internal.h"
-#include "xray_tsc.h"
-#include "xray_utils.h"
-
-namespace __xray {
-
-__sanitizer::SpinMutex LogMutex;
-
-// We use elements of this type to record the entry TSC of every function ID we
-// see as we're tracing a particular thread's execution.
-struct alignas(16) StackEntry {
- int32_t FuncId;
- uint16_t Type;
- uint8_t CPU;
- uint8_t Padding;
- uint64_t TSC;
-};
-
-static_assert(sizeof(StackEntry) == 16, "Wrong size for StackEntry");
-
-struct alignas(64) ThreadLocalData {
- void *InMemoryBuffer = nullptr;
- size_t BufferSize = 0;
- size_t BufferOffset = 0;
- void *ShadowStack = nullptr;
- size_t StackSize = 0;
- size_t StackEntries = 0;
- int Fd = -1;
- tid_t TID = 0;
-};
-
-static pthread_key_t PThreadKey;
-
-static __sanitizer::atomic_uint8_t BasicInitialized{0};
-
-BasicLoggingOptions GlobalOptions;
-
-thread_local volatile bool RecursionGuard = false;
-
-static uint64_t thresholdTicks() XRAY_NEVER_INSTRUMENT {
- static uint64_t TicksPerSec = probeRequiredCPUFeatures()
- ? getTSCFrequency()
- : __xray::NanosecondsPerSecond;
- static const uint64_t ThresholdTicks =
- TicksPerSec * GlobalOptions.DurationFilterMicros / 1000000;
- return ThresholdTicks;
-}
-
-static int openLogFile() XRAY_NEVER_INSTRUMENT {
- int F = getLogFD();
- if (F == -1)
- return -1;
-
- // Test for required CPU features and cache the cycle frequency
- static bool TSCSupported = probeRequiredCPUFeatures();
- static uint64_t CycleFrequency =
- TSCSupported ? getTSCFrequency() : __xray::NanosecondsPerSecond;
-
- // Since we're here, we get to write the header. We set it up so that the
- // header will only be written once, at the start, and let the threads
- // logging do writes which just append.
- XRayFileHeader Header;
- Header.Version = 2; // Version 2 includes tail exit records.
- Header.Type = FileTypes::NAIVE_LOG;
- Header.CycleFrequency = CycleFrequency;
-
- // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc'
- // before setting the values in the header.
- Header.ConstantTSC = 1;
- Header.NonstopTSC = 1;
- retryingWriteAll(F, reinterpret_cast<char *>(&Header),
- reinterpret_cast<char *>(&Header) + sizeof(Header));
- return F;
-}
-
-int getGlobalFd() XRAY_NEVER_INSTRUMENT {
- static int Fd = openLogFile();
- return Fd;
-}
-
-ThreadLocalData &getThreadLocalData() XRAY_NEVER_INSTRUMENT {
- thread_local ThreadLocalData TLD;
- thread_local bool UNUSED TOnce = [] {
- if (GlobalOptions.ThreadBufferSize == 0) {
- if (__sanitizer::Verbosity())
- Report("Not initializing TLD since ThreadBufferSize == 0.\n");
- return false;
- }
- TLD.TID = __sanitizer::GetTid();
- pthread_setspecific(PThreadKey, &TLD);
- TLD.Fd = getGlobalFd();
- TLD.InMemoryBuffer = reinterpret_cast<XRayRecord *>(
- InternalAlloc(sizeof(XRayRecord) * GlobalOptions.ThreadBufferSize,
- nullptr, alignof(XRayRecord)));
- TLD.BufferSize = GlobalOptions.ThreadBufferSize;
- TLD.BufferOffset = 0;
- if (GlobalOptions.MaxStackDepth == 0) {
- if (__sanitizer::Verbosity())
- Report("Not initializing the ShadowStack since MaxStackDepth == 0.\n");
- TLD.StackSize = 0;
- TLD.StackEntries = 0;
- TLD.ShadowStack = nullptr;
- return false;
- }
- TLD.ShadowStack = reinterpret_cast<StackEntry *>(
- InternalAlloc(sizeof(StackEntry) * GlobalOptions.MaxStackDepth, nullptr,
- alignof(StackEntry)));
- TLD.StackSize = GlobalOptions.MaxStackDepth;
- TLD.StackEntries = 0;
- if (__sanitizer::Verbosity() >= 2) {
- static auto UNUSED Once = [] {
- auto ticks = thresholdTicks();
- Report("Ticks threshold: %d\n", ticks);
- return false;
- }();
- }
- return false;
- }();
- return TLD;
-}
-
-template <class RDTSC>
-void InMemoryRawLog(int32_t FuncId, XRayEntryType Type,
- RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
- auto &TLD = getThreadLocalData();
- int Fd = getGlobalFd();
- if (Fd == -1)
- return;
-
- // Use a simple recursion guard, to handle cases where we're already logging
- // and for one reason or another, this function gets called again in the same
- // thread.
- if (RecursionGuard)
- return;
- RecursionGuard = true;
- auto ExitGuard = __sanitizer::at_scope_exit([] { RecursionGuard = false; });
-
- uint8_t CPU = 0;
- uint64_t TSC = ReadTSC(CPU);
-
- switch (Type) {
- case XRayEntryType::ENTRY:
- case XRayEntryType::LOG_ARGS_ENTRY: {
- // Short circuit if we've reached the maximum depth of the stack.
- if (TLD.StackEntries++ >= TLD.StackSize)
- return;
-
- // When we encounter an entry event, we keep track of the TSC and the CPU,
- // and put it in the stack.
- StackEntry E;
- E.FuncId = FuncId;
- E.CPU = CPU;
- E.Type = Type;
- E.TSC = TSC;
- auto StackEntryPtr = static_cast<char *>(TLD.ShadowStack) +
- (sizeof(StackEntry) * (TLD.StackEntries - 1));
- __sanitizer::internal_memcpy(StackEntryPtr, &E, sizeof(StackEntry));
- break;
- }
- case XRayEntryType::EXIT:
- case XRayEntryType::TAIL: {
- if (TLD.StackEntries == 0)
- break;
-
- if (--TLD.StackEntries >= TLD.StackSize)
- return;
-
- // When we encounter an exit event, we check whether all the following are
- // true:
- //
- // - The Function ID is the same as the most recent entry in the stack.
- // - The CPU is the same as the most recent entry in the stack.
- // - The Delta of the TSCs is less than the threshold amount of time we're
- // looking to record.
- //
- // If all of these conditions are true, we pop the stack and don't write a
- // record and move the record offset back.
- StackEntry StackTop;
- auto StackEntryPtr = static_cast<char *>(TLD.ShadowStack) +
- (sizeof(StackEntry) * TLD.StackEntries);
- __sanitizer::internal_memcpy(&StackTop, StackEntryPtr, sizeof(StackEntry));
- if (StackTop.FuncId == FuncId && StackTop.CPU == CPU &&
- StackTop.TSC < TSC) {
- auto Delta = TSC - StackTop.TSC;
- if (Delta < thresholdTicks()) {
- assert(TLD.BufferOffset > 0);
- TLD.BufferOffset -= StackTop.Type == XRayEntryType::ENTRY ? 1 : 2;
- return;
- }
- }
- break;
- }
- default:
- // Should be unreachable.
- assert(false && "Unsupported XRayEntryType encountered.");
- break;
- }
-
- // First determine whether the delta between the function's enter record and
- // the exit record is higher than the threshold.
- __xray::XRayRecord R;
- R.RecordType = RecordTypes::NORMAL;
- R.CPU = CPU;
- R.TSC = TSC;
- R.TId = TLD.TID;
- R.Type = Type;
- R.FuncId = FuncId;
- auto FirstEntry = reinterpret_cast<__xray::XRayRecord *>(TLD.InMemoryBuffer);
- __sanitizer::internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
- if (++TLD.BufferOffset == TLD.BufferSize) {
- __sanitizer::SpinMutexLock L(&LogMutex);
- retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
- reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
- TLD.BufferOffset = 0;
- TLD.StackEntries = 0;
- }
-}
-
-template <class RDTSC>
-void InMemoryRawLogWithArg(int32_t FuncId, XRayEntryType Type, uint64_t Arg1,
- RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
- auto &TLD = getThreadLocalData();
- auto FirstEntry =
- reinterpret_cast<__xray::XRayArgPayload *>(TLD.InMemoryBuffer);
- const auto &BuffLen = TLD.BufferSize;
- int Fd = getGlobalFd();
- if (Fd == -1)
- return;
-
- // First we check whether there's enough space to write the data consecutively
- // in the thread-local buffer. If not, we first flush the buffer before
- // attempting to write the two records that must be consecutive.
- if (TLD.BufferOffset + 2 > BuffLen) {
- __sanitizer::SpinMutexLock L(&LogMutex);
- retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
- reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
- TLD.BufferOffset = 0;
- TLD.StackEntries = 0;
- }
-
- // Then we write the "we have an argument" record.
- InMemoryRawLog(FuncId, Type, ReadTSC);
-
- if (RecursionGuard)
- return;
- RecursionGuard = true;
- auto ExitGuard = __sanitizer::at_scope_exit([] { RecursionGuard = false; });
-
- // And from here on write the arg payload.
- __xray::XRayArgPayload R;
- R.RecordType = RecordTypes::ARG_PAYLOAD;
- R.FuncId = FuncId;
- R.TId = TLD.TID;
- R.Arg = Arg1;
- __sanitizer::internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
- if (++TLD.BufferOffset == BuffLen) {
- __sanitizer::SpinMutexLock L(&LogMutex);
- retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
- reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
- TLD.BufferOffset = 0;
- TLD.StackEntries = 0;
- }
-}
-
-void basicLoggingHandleArg0RealTSC(int32_t FuncId,
- XRayEntryType Type) XRAY_NEVER_INSTRUMENT {
- InMemoryRawLog(FuncId, Type, __xray::readTSC);
-}
-
-void basicLoggingHandleArg0EmulateTSC(int32_t FuncId, XRayEntryType Type)
- XRAY_NEVER_INSTRUMENT {
- InMemoryRawLog(FuncId, Type, [](uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
- timespec TS;
- int result = clock_gettime(CLOCK_REALTIME, &TS);
- if (result != 0) {
- Report("clock_gettimg(2) return %d, errno=%d.", result, int(errno));
- TS = {0, 0};
- }
- CPU = 0;
- return TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
- });
-}
-
-void basicLoggingHandleArg1RealTSC(int32_t FuncId, XRayEntryType Type,
- uint64_t Arg1) XRAY_NEVER_INSTRUMENT {
- InMemoryRawLogWithArg(FuncId, Type, Arg1, __xray::readTSC);
-}
-
-void basicLoggingHandleArg1EmulateTSC(int32_t FuncId, XRayEntryType Type,
- uint64_t Arg1) XRAY_NEVER_INSTRUMENT {
- InMemoryRawLogWithArg(
- FuncId, Type, Arg1, [](uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
- timespec TS;
- int result = clock_gettime(CLOCK_REALTIME, &TS);
- if (result != 0) {
- Report("clock_gettimg(2) return %d, errno=%d.", result, int(errno));
- TS = {0, 0};
- }
- CPU = 0;
- return TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
- });
-}
-
-static void TLDDestructor(void *P) XRAY_NEVER_INSTRUMENT {
- ThreadLocalData &TLD = *reinterpret_cast<ThreadLocalData *>(P);
- auto ExitGuard = __sanitizer::at_scope_exit([&TLD] {
- // Clean up dynamic resources.
- if (TLD.InMemoryBuffer)
- InternalFree(TLD.InMemoryBuffer);
- if (TLD.ShadowStack)
- InternalFree(TLD.ShadowStack);
- if (__sanitizer::Verbosity())
- Report("Cleaned up log for TID: %d\n", TLD.TID);
- });
-
- if (TLD.Fd == -1 || TLD.BufferOffset == 0) {
- if (__sanitizer::Verbosity())
- Report("Skipping buffer for TID: %d; Fd = %d; Offset = %llu\n", TLD.TID,
- TLD.Fd, TLD.BufferOffset);
- return;
- }
-
- {
- __sanitizer::SpinMutexLock L(&LogMutex);
- retryingWriteAll(TLD.Fd, reinterpret_cast<char *>(TLD.InMemoryBuffer),
- reinterpret_cast<char *>(TLD.InMemoryBuffer) +
- (sizeof(__xray::XRayRecord) * TLD.BufferOffset));
- }
-
- // Because this thread's exit could be the last one trying to write to
- // the file and that we're not able to close out the file properly, we
- // sync instead and hope that the pending writes are flushed as the
- // thread exits.
- fsync(TLD.Fd);
-}
-
-XRayLogInitStatus basicLoggingInit(size_t BufferSize, size_t BufferMax,
- void *Options,
- size_t OptionsSize) XRAY_NEVER_INSTRUMENT {
- static bool UNUSED Once = [] {
- pthread_key_create(&PThreadKey, TLDDestructor);
- return false;
- }();
-
- uint8_t Expected = 0;
- if (!__sanitizer::atomic_compare_exchange_strong(
- &BasicInitialized, &Expected, 1, __sanitizer::memory_order_acq_rel)) {
- if (__sanitizer::Verbosity())
- Report("Basic logging already initialized.\n");
- return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
- }
-
- if (OptionsSize != sizeof(BasicLoggingOptions)) {
- Report("Invalid options size, potential ABI mismatch; expected %d got %d",
- sizeof(BasicLoggingOptions), OptionsSize);
- return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
- }
-
- static auto UseRealTSC = probeRequiredCPUFeatures();
- if (!UseRealTSC && __sanitizer::Verbosity())
- Report("WARNING: Required CPU features missing for XRay instrumentation, "
- "using emulation instead.\n");
-
- GlobalOptions = *reinterpret_cast<BasicLoggingOptions *>(Options);
- __xray_set_handler_arg1(UseRealTSC ? basicLoggingHandleArg1RealTSC
- : basicLoggingHandleArg1EmulateTSC);
- __xray_set_handler(UseRealTSC ? basicLoggingHandleArg0RealTSC
- : basicLoggingHandleArg0EmulateTSC);
- __xray_remove_customevent_handler();
- __xray_remove_typedevent_handler();
-
- return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
-}
-
-XRayLogInitStatus basicLoggingFinalize() XRAY_NEVER_INSTRUMENT {
- uint8_t Expected = 0;
- if (!__sanitizer::atomic_compare_exchange_strong(
- &BasicInitialized, &Expected, 0, __sanitizer::memory_order_acq_rel) &&
- __sanitizer::Verbosity())
- Report("Basic logging already finalized.\n");
-
- // Nothing really to do aside from marking state of the global to be
- // uninitialized.
-
- return XRayLogInitStatus::XRAY_LOG_FINALIZED;
-}
-
-XRayLogFlushStatus basicLoggingFlush() XRAY_NEVER_INSTRUMENT {
- // This really does nothing, since flushing the logs happen at the end of a
- // thread's lifetime, or when the buffers are full.
- return XRayLogFlushStatus::XRAY_LOG_FLUSHED;
-}
-
-// This is a handler that, effectively, does nothing.
-void basicLoggingHandleArg0Empty(int32_t, XRayEntryType) XRAY_NEVER_INSTRUMENT {
-}
-
-bool basicLogDynamicInitializer() XRAY_NEVER_INSTRUMENT {
- XRayLogImpl Impl{
- basicLoggingInit,
- basicLoggingFinalize,
- basicLoggingHandleArg0Empty,
- basicLoggingFlush,
- };
- auto RegistrationResult = __xray_log_register_mode("xray-basic", Impl);
- if (RegistrationResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK &&
- __sanitizer::Verbosity())
- Report("Cannot register XRay Basic Mode to 'xray-basic'; error = %d\n",
- RegistrationResult);
- if (flags()->xray_naive_log ||
- !__sanitizer::internal_strcmp(flags()->xray_mode, "xray-basic")) {
- __xray_set_log_impl(Impl);
- BasicLoggingOptions Options;
- Options.DurationFilterMicros =
- flags()->xray_naive_log_func_duration_threshold_us;
- Options.MaxStackDepth = flags()->xray_naive_log_max_stack_depth;
- Options.ThreadBufferSize = flags()->xray_naive_log_thread_buffer_size;
- __xray_log_init(flags()->xray_naive_log_thread_buffer_size, 0, &Options,
- sizeof(BasicLoggingOptions));
- static auto UNUSED Once = [] {
- static auto UNUSED &TLD = getThreadLocalData();
- __sanitizer::Atexit(+[] { TLDDestructor(&TLD); });
- return false;
- }();
- }
- return true;
-}
-
-} // namespace __xray
-
-static auto UNUSED Unused = __xray::basicLogDynamicInitializer();
Removed: compiler-rt/trunk/lib/xray/xray_inmemory_log.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_inmemory_log.h?rev=331506&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_inmemory_log.h (original)
+++ compiler-rt/trunk/lib/xray/xray_inmemory_log.h (removed)
@@ -1,44 +0,0 @@
-//===-- xray_inmemory_log.h
-//------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#ifndef XRAY_XRAY_INMEMORY_LOG_H
-#define XRAY_XRAY_INMEMORY_LOG_H
-
-#include "xray/xray_log_interface.h"
-
-/// Basic (Naive) Mode
-/// ==================
-///
-/// This implementation hooks in through the XRay logging implementation
-/// framework. The Basic Mode implementation will keep appending to a file as
-/// soon as the thread-local buffers are full. It keeps minimal in-memory state
-/// and does the minimum filtering required to keep log files smaller.
-
-namespace __xray {
-
-XRayLogInitStatus basicLoggingInit(size_t BufferSize, size_t BufferMax,
- void *Options, size_t OptionsSize);
-XRayLogInitStatus basicLoggingFinalize();
-
-void basicLoggingHandleArg0RealTSC(int32_t FuncId, XRayEntryType Entry);
-void basicLoggingHandleArg0EmulateTSC(int32_t FuncId, XRayEntryType Entry);
-void basicLoggingHandleArg1RealTSC(int32_t FuncId, XRayEntryType Entry,
- uint64_t Arg1);
-void basicLoggingHandleArg1EmulateTSC(int32_t FuncId, XRayEntryType Entry,
- uint64_t Arg1);
-XRayLogFlushStatus basicLoggingFlush();
-XRayLogInitStatus basicLoggingReset();
-
-} // namespace __xray
-
-#endif // XRAY_XRAY_INMEMORY_LOG_H
Modified: compiler-rt/trunk/test/xray/TestCases/Posix/basic-filtering.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Posix/basic-filtering.cc?rev=331507&r1=331506&r2=331507&view=diff
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Posix/basic-filtering.cc (original)
+++ compiler-rt/trunk/test/xray/TestCases/Posix/basic-filtering.cc Thu May 3 23:27:53 2018
@@ -3,7 +3,7 @@
// RUN: %clangxx_xray -std=c++11 %s -o %t -g
// RUN: rm basic-filtering-* || true
-// RUN: XRAY_OPTIONS="patch_premain=true xray_naive_log=true verbosity=1 \
+// RUN: XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1 \
// RUN: xray_logfile_base=basic-filtering- \
// RUN: xray_naive_log_func_duration_threshold_us=1000 \
// RUN: xray_naive_log_max_stack_depth=2" %run %t 2>&1 | \
@@ -11,6 +11,16 @@
// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
// RUN: "`ls basic-filtering-* | head -1`" | \
// RUN: FileCheck %s --check-prefix TRACE
+// RUN: rm basic-filtering-* || true
+//
+// Now check support for the XRAY_BASIC_OPTIONS environment variable.
+// RUN: XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1 \
+// RUN: xray_logfile_base=basic-filtering-" \
+// RUN: XRAY_BASIC_OPTIONS="func_duration_threshold_us=1000 max_stack_depth=2" \
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
+// RUN: "`ls basic-filtering-* | head -1`" | \
+// RUN: FileCheck %s --check-prefix TRACE
// RUN: rm basic-filtering-* || true
//
// REQUIRES: x86_64-target-arch
More information about the llvm-commits
mailing list