diff options
| -rw-r--r-- | compiler-rt/include/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | compiler-rt/include/xray/xray_log_interface.h | 9 | ||||
| -rw-r--r-- | compiler-rt/lib/xray/xray_fdr_logging.cc | 19 | ||||
| -rw-r--r-- | compiler-rt/lib/xray/xray_fdr_logging.h | 8 | ||||
| -rw-r--r-- | compiler-rt/lib/xray/xray_log_interface.cc | 5 | ||||
| -rw-r--r-- | compiler-rt/lib/xray/xray_utils.cc | 5 | ||||
| -rw-r--r-- | compiler-rt/test/xray/TestCases/Linux/fdr-mode.cc | 62 | ||||
| -rw-r--r-- | compiler-rt/test/xray/lit.cfg | 5 | 
8 files changed, 91 insertions, 25 deletions
| diff --git a/compiler-rt/include/CMakeLists.txt b/compiler-rt/include/CMakeLists.txt index 6104aded290..3d6c96be931 100644 --- a/compiler-rt/include/CMakeLists.txt +++ b/compiler-rt/include/CMakeLists.txt @@ -12,7 +12,8 @@ set(SANITIZER_HEADERS    sanitizer/tsan_interface_atomic.h)  set(XRAY_HEADERS -  xray/xray_interface.h) +  xray/xray_interface.h +  xray/xray_log_interface.h)  set(COMPILER_RT_HEADERS    ${SANITIZER_HEADERS} diff --git a/compiler-rt/include/xray/xray_log_interface.h b/compiler-rt/include/xray/xray_log_interface.h index f98b331101a..a8709c3a7c8 100644 --- a/compiler-rt/include/xray/xray_log_interface.h +++ b/compiler-rt/include/xray/xray_log_interface.h @@ -48,4 +48,13 @@ XRayLogFlushStatus __xray_log_flushLog();  } // extern "C" +namespace __xray { +// Options used by the LLVM XRay FDR implementation. +struct FDRLoggingOptions { +  bool ReportErrors = false; +  int Fd = -1; +}; + +} // namespace __xray +  #endif // XRAY_XRAY_LOG_INTERFACE_H diff --git a/compiler-rt/lib/xray/xray_fdr_logging.cc b/compiler-rt/lib/xray/xray_fdr_logging.cc index df95c1d66e7..a86cf0b1410 100644 --- a/compiler-rt/lib/xray/xray_fdr_logging.cc +++ b/compiler-rt/lib/xray/xray_fdr_logging.cc @@ -51,19 +51,18 @@ std::unique_ptr<FDRLoggingOptions> FDROptions;  XRayLogInitStatus fdrLoggingInit(std::size_t BufferSize, std::size_t BufferMax,                                   void *Options,                                   size_t OptionsSize) XRAY_NEVER_INSTRUMENT { -  assert(OptionsSize == sizeof(FDRLoggingOptions)); +  if (OptionsSize != sizeof(FDRLoggingOptions)) +    return static_cast<XRayLogInitStatus>(__sanitizer::atomic_load( +        &LoggingStatus, __sanitizer::memory_order_acquire));    s32 CurrentStatus = XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; -  if (__sanitizer::atomic_compare_exchange_strong( +  if (!__sanitizer::atomic_compare_exchange_strong(            &LoggingStatus, &CurrentStatus,            XRayLogInitStatus::XRAY_LOG_INITIALIZING,            __sanitizer::memory_order_release))      return static_cast<XRayLogInitStatus>(CurrentStatus);    FDROptions.reset(new FDRLoggingOptions()); -  *FDROptions = *reinterpret_cast<FDRLoggingOptions *>(Options); -  if (FDROptions->ReportErrors) -    SetPrintfAndReportCallback(printToStdErr); - +  memcpy(FDROptions.get(), Options, OptionsSize);    bool Success = false;    BQ = std::make_shared<BufferQueue>(BufferSize, BufferMax, Success);    if (!Success) { @@ -77,6 +76,7 @@ XRayLogInitStatus fdrLoggingInit(std::size_t BufferSize, std::size_t BufferMax,    __sanitizer::atomic_store(&LoggingStatus,                              XRayLogInitStatus::XRAY_LOG_INITIALIZED,                              __sanitizer::memory_order_release); +  Report("XRay FDR init successful.\n");    return XRayLogInitStatus::XRAY_LOG_INITIALIZED;  } @@ -88,7 +88,7 @@ XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT {      return XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;    s32 Result = XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING; -  if (__sanitizer::atomic_compare_exchange_strong( +  if (!__sanitizer::atomic_compare_exchange_strong(            &LogFlushStatus, &Result, XRayLogFlushStatus::XRAY_LOG_FLUSHING,            __sanitizer::memory_order_release))      return static_cast<XRayLogFlushStatus>(Result); @@ -140,7 +140,7 @@ XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT {  XRayLogInitStatus fdrLoggingFinalize() XRAY_NEVER_INSTRUMENT {    s32 CurrentStatus = XRayLogInitStatus::XRAY_LOG_INITIALIZED; -  if (__sanitizer::atomic_compare_exchange_strong( +  if (!__sanitizer::atomic_compare_exchange_strong(            &LoggingStatus, &CurrentStatus,            XRayLogInitStatus::XRAY_LOG_FINALIZING,            __sanitizer::memory_order_release)) @@ -168,8 +168,7 @@ XRayLogInitStatus fdrLoggingReset() XRAY_NEVER_INSTRUMENT {    BQ.reset();    // Spin until the flushing status is flushed. -  s32 CurrentFlushingStatus = -      XRayLogFlushStatus::XRAY_LOG_FLUSHED; +  s32 CurrentFlushingStatus = XRayLogFlushStatus::XRAY_LOG_FLUSHED;    while (__sanitizer::atomic_compare_exchange_weak(        &LogFlushStatus, &CurrentFlushingStatus,        XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING, diff --git a/compiler-rt/lib/xray/xray_fdr_logging.h b/compiler-rt/lib/xray/xray_fdr_logging.h index 93c33b417ba..426b54dc788 100644 --- a/compiler-rt/lib/xray/xray_fdr_logging.h +++ b/compiler-rt/lib/xray/xray_fdr_logging.h @@ -26,14 +26,6 @@  // default mode of always writing fixed-size records.  namespace __xray { - -// Options used by the FDR implementation. -struct FDRLoggingOptions { -  bool ReportErrors = false; -  int Fd = -1; -}; - -// Flight Data Recorder mode implementation interfaces.  XRayLogInitStatus fdrLoggingInit(size_t BufferSize, size_t BufferMax,                                   void *Options, size_t OptionsSize);  XRayLogInitStatus fdrLoggingFinalize(); diff --git a/compiler-rt/lib/xray/xray_log_interface.cc b/compiler-rt/lib/xray/xray_log_interface.cc index 8fb6e39192e..ffed601c05c 100644 --- a/compiler-rt/lib/xray/xray_log_interface.cc +++ b/compiler-rt/lib/xray/xray_log_interface.cc @@ -35,8 +35,9 @@ void __xray_set_log_impl(XRayLogImpl Impl) XRAY_NEVER_INSTRUMENT {    *GlobalXRayImpl = Impl;  } -XRayLogInitStatus __xray_init(size_t BufferSize, size_t MaxBuffers, void *Args, -                              size_t ArgsSize) XRAY_NEVER_INSTRUMENT { +XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers, +                                  void *Args, +                                  size_t ArgsSize) XRAY_NEVER_INSTRUMENT {    __sanitizer::SpinMutexLock Guard(&XRayImplMutex);    if (!GlobalXRayImpl)      return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; diff --git a/compiler-rt/lib/xray/xray_utils.cc b/compiler-rt/lib/xray/xray_utils.cc index 5d6390c802a..b9a38d1b98e 100644 --- a/compiler-rt/lib/xray/xray_utils.cc +++ b/compiler-rt/lib/xray/xray_utils.cc @@ -93,8 +93,6 @@ bool readValueFromFile(const char *Filename,  }  int getLogFD() XRAY_NEVER_INSTRUMENT { -  // FIXME: Figure out how to make this less stderr-dependent. -  SetPrintfAndReportCallback(printToStdErr);    // Open a temporary file once for the log.    static char TmpFilename[256] = {};    static char TmpWildcardPattern[] = "XXXXXX"; @@ -119,8 +117,7 @@ int getLogFD() XRAY_NEVER_INSTRUMENT {             TmpFilename);      return -1;    } -  if (Verbosity()) -    fprintf(stderr, "XRay: Log file in '%s'\n", TmpFilename); +  Report("XRay: Log file in '%s'\n", TmpFilename);    return Fd;  } diff --git a/compiler-rt/test/xray/TestCases/Linux/fdr-mode.cc b/compiler-rt/test/xray/TestCases/Linux/fdr-mode.cc new file mode 100644 index 00000000000..88660802ecb --- /dev/null +++ b/compiler-rt/test/xray/TestCases/Linux/fdr-mode.cc @@ -0,0 +1,62 @@ +// RUN: %clangxx_xray -std=c++11 %s -o %t +// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false xray_logfile_base=fdr-logging-test- xray_fdr_log=true verbosity=1" %run %t 2>&1 | FileCheck %s +// FIXME: %llvm_xray convert -instr_map=%t "`ls fdr-logging-test-* | head -1`" | FileCheck %s --check-prefix TRACE +// RUN: rm fdr-logging-test-* + +#include "xray/xray_log_interface.h" +#include <cassert> +#include <chrono> +#include <cstdio> +#include <iostream> +#include <stdlib.h> +#include <thread> +#include <time.h> + +constexpr auto kBufferSize = 16384; +constexpr auto kBufferMax = 10; + +thread_local uint64_t var = 0; +[[clang::xray_always_instrument]] void __attribute__((noinline)) fC() { ++var; } + +[[clang::xray_always_instrument]] void __attribute__((noinline)) fB() { fC(); } + +[[clang::xray_always_instrument]] void __attribute__((noinline)) fA() { fB(); } + +int main(int argc, char *argv[]) { +  using namespace __xray; +  FDRLoggingOptions Options; +  std::cout << "Logging before init." << std::endl; +  // CHECK: Logging before init. +  auto status = __xray_log_init(kBufferSize, kBufferMax, &Options, +                                sizeof(FDRLoggingOptions)); +  assert(status == XRayLogInitStatus::XRAY_LOG_INITIALIZED); +  std::cout << "Init status " << status << std::endl; +  // CHECK: Init status {{.*}} +  std::cout << "Patching..." << std::endl; +  // CHECK: Patching... +  __xray_patch(); +  fA(); +  fC(); +  fB(); +  fA(); +  fC(); +  std::thread other_thread([]() { +    fC(); +    fB(); +    fA(); +  }); +  other_thread.join(); +  std::cout << "Joined" << std::endl; +  // CHECK: Joined +  std::cout << "Finalize status " << __xray_log_finalize() << std::endl; +  // CHECK: Finalize status {{.*}} +  fC(); +  std::cout << "Main execution var = " << var << std::endl; +  // CHECK: Main execution var = 6 +  std::cout << "Flush status " << __xray_log_flushLog() << std::endl; +  // CHECK: Flush status {{.*}} +  __xray_unpatch(); +  return 0; +} + +// TRACE: { function } diff --git a/compiler-rt/test/xray/lit.cfg b/compiler-rt/test/xray/lit.cfg index 9142ad13618..b07dcbd791f 100644 --- a/compiler-rt/test/xray/lit.cfg +++ b/compiler-rt/test/xray/lit.cfg @@ -16,6 +16,9 @@ clang_xray_cxxflags = config.cxx_mode_flags + clang_xray_cflags  def build_invocation(compile_flags):    return ' ' + ' '.join([config.clang] + compile_flags) + ' ' +# Assume that llvm-xray is in the config.llvm_tools_dir. +llvm_xray = os.path.join(config.llvm_tools_dir, 'llvm-xray') +  # Setup substitutions.  config.substitutions.append(      ('%clang ', build_invocation([config.target_cflags]))) @@ -26,6 +29,8 @@ config.substitutions.append(      ('%clang_xray ', build_invocation(clang_xray_cflags)))  config.substitutions.append(      ('%clangxx_xray', build_invocation(clang_xray_cxxflags))) +config.substitutions.append( +    ('%llvm_xray', llvm_xray))  # Default test suffixes.  config.suffixes = ['.c', '.cc', '.cpp'] | 

