//===-- xray_fdr_logging.cpp -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of XRay, a dynamic runtime instrumentation system.
//
// Here we implement the Flight Data Recorder mode for XRay, where we use
// compact structures to store records in memory as well as when writing out the
// data to files.
//
//===----------------------------------------------------------------------===//
#include "xray_fdr_logging.h"
#include <cassert>
#include <cstddef>
#include <errno.h>
#include <limits>
#include <memory>
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "xray/xray_interface.h"
#include "xray/xray_records.h"
#include "xray_allocator.h"
#include "xray_buffer_queue.h"
#include "xray_defs.h"
#include "xray_fdr_controller.h"
#include "xray_fdr_flags.h"
#include "xray_fdr_log_writer.h"
#include "xray_flags.h"
#include "xray_recursion_guard.h"
#include "xray_tsc.h"
#include "xray_utils.h"

namespace __xray {

static atomic_sint32_t LoggingStatus = {
    XRayLogInitStatus::XRAY_LOG_UNINITIALIZED};

namespace {

// Group together thread-local-data in a struct, then hide it behind a function
// call so that it can be initialized on first use instead of as a global. We
// force the alignment to 64-bytes for x86 cache line alignment, as this
// structure is used in the hot path of implementation.
struct XRAY_TLS_ALIGNAS(64) ThreadLocalData {
  BufferQueue::Buffer Buffer{};
  BufferQueue *BQ = nullptr;

  using LogWriterStorage = std::byte[sizeof(FDRLogWriter)];
  alignas(FDRLogWriter) LogWriterStorage LWStorage;
  FDRLogWriter *Writer = nullptr;

  using ControllerStorage = std::byte[sizeof(FDRController<>)];
  alignas(FDRController<>) ControllerStorage CStorage;
  FDRController<> *Controller = nullptr;
};

} // namespace

static_assert(std::is_trivially_destructible<ThreadLocalData>::value,
              "ThreadLocalData must be trivially destructible");

// Use a global pthread key to identify thread-local data for logging.
static pthread_key_t Key;

// Global BufferQueue.
static std::byte BufferQueueStorage[sizeof(BufferQueue)];
static BufferQueue *BQ = nullptr;

// Global thresholds for function durations.
static atomic_uint64_t ThresholdTicks{0};

// Global for ticks per second.
static atomic_uint64_t TicksPerSec{0};

static atomic_sint32_t LogFlushStatus = {
    XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING};

// This function will initialize the thread-local data structure used by the FDR
// logging implementation and return a reference to it. The implementation
// details require a bit of care to maintain.
//
// First, some requirements on the implementation in general:
//
//   - XRay handlers should not call any memory allocation routines that may
//     delegate to an instrumented implementation. This means functions like
//     malloc() and free() should not be called while instrumenting.
//
//   - We would like to use some thread-local data initialized on first-use of
//     the XRay instrumentation. These allow us to implement unsynchronized
//     routines that access resources associated with the thread.
//
// The implementation here uses a few mechanisms that allow us to provide both
// the requirements listed above. We do this by:
//
//   1. Using a thread-local aligned storage buffer for representing the
//      ThreadLocalData struct. This data will be uninitialized memory by
//      design.
//
//   2. Not requiring a thread exit handler/implementation, keeping the
//      thread-local as purely a collection of references/data that do not
//      require cleanup.
//
// We're doing this to avoid using a `thread_local` object that has a
// non-trivial destructor, because the C++ runtime might call std::malloc(...)
// to register calls to destructors. Deadlocks may arise when, for example, an
// externally provided malloc implementation is XRay instrumented, and
// initializing the thread-locals involves calling into malloc. A malloc
// implementation that does global synchronization might be holding a lock for a
// critical section, calling a function that might be XRay instrumented (and
// thus in turn calling into malloc by virtue of registration of the
// thread_local's destructor).
#if XRAY_HAS_TLS_ALIGNAS
static_assert(alignof(ThreadLocalData) >= 64,
              "ThreadLocalData must be cache line aligned.");
#endif
static ThreadLocalData &getThreadLocalData() {
  alignas(ThreadLocalData) thread_local std::byte
      TLDStorage[sizeof(ThreadLocalData)];

  if (pthread_getspecific(Key) == NULL) {
    new (reinterpret_cast<ThreadLocalData *>(&TLDStorage)) ThreadLocalData{};
    pthread_setspecific(Key, &TLDStorage);
  }

  return *reinterpret_cast<ThreadLocalData *>(&TLDStorage);
}

static XRayFileHeader &fdrCommonHeaderInfo() {
  alignas(XRayFileHeader) static std::byte HStorage[sizeof(XRayFileHeader)];
  static pthread_once_t OnceInit = PTHREAD_ONCE_INIT;
  static bool TSCSupported = true;
  static uint64_t CycleFrequency = NanosecondsPerSecond;
  pthread_once(
      &OnceInit, +[] {
        XRayFileHeader &H = reinterpret_cast<XRayFileHeader &>(HStorage);
        // Version 2 of the log writes the extents of the buffer, instead of
        // relying on an end-of-buffer record.
        // Version 3 includes PID metadata record.
        // Version 4 includes CPU data in the custom event records.
        // Version 5 uses relative deltas for custom and typed event records,
        // and removes the CPU data in custom event records (similar to how
        // function records use deltas instead of full TSCs and rely on other
        // metadata records for TSC wraparound and CPU migration).
        H.Version = 5;
        H.Type = FileTypes::FDR_LOG;

        // Test for required CPU features and cache the cycle frequency
        TSCSupported = probeRequiredCPUFeatures();
        if (TSCSupported)
          CycleFrequency = getTSCFrequency();
        H.CycleFrequency = CycleFrequency;

        // FIXME: Actually check whether we have 'constant_tsc' and
        // 'nonstop_tsc' before setting the values in the header.
        H.ConstantTSC = 1;
        H.NonstopTSC = 1;
      });
  return reinterpret_cast<XRayFileHeader &>(HStorage);
}

// This is the iterator implementation, which knows how to handle FDR-mode
// specific buffers. This is used as an implementation of the iterator function
// needed by __xray_set_buffer_iterator(...). It maintains a global state of the
// buffer iteration for the currently installed FDR mode buffers. In particular:
//
//   - If the argument represents the initial state of XRayBuffer ({nullptr, 0})
//     then the iterator returns the header information.
//   - If the argument represents the header information ({address of header
//     info, size of the header info}) then it returns the first FDR buffer's
//     address and extents.
//   - It will keep returning the next buffer and extents as there are more
//     buffers to process. When the input represents the last buffer, it will
//     return the initial state to signal completion ({nullptr, 0}).
//
// See xray/xray_log_interface.h for more details on the requirements for the
// implementations of __xray_set_buffer_iterator(...) and
// __xray_log_process_buffers(...).
XRayBuffer fdrIterator(const XRayBuffer B) {
  DCHECK(internal_strcmp(__xray_log_get_current_mode(), "xray-fdr") == 0);
  DCHECK(BQ->finalizing());

  if (BQ == nullptr || !BQ->finalizing()) {
    if (Verbosity())
      Report(
          "XRay FDR: Failed global buffer queue is null or not finalizing!\n");
    return {nullptr, 0};
  }

  // We use a global scratch-pad for the header information, which only gets
  // initialized the first time this function is called. We'll update one part
  // of this information with some relevant data (in particular the number of
  // buffers to expect).
  alignas(
      XRayFileHeader) static std::byte HeaderStorage[sizeof(XRayFileHeader)];
  static pthread_once_t HeaderOnce = PTHREAD_ONCE_INIT;
  pthread_once(
      &HeaderOnce, +[] {
        reinterpret_cast<XRayFileHeader &>(HeaderStorage) =
            fdrCommonHeaderInfo();
      });

  // We use a convenience alias for code referring to Header from here on out.
  auto &Header = reinterpret_cast<XRayFileHeader &>(HeaderStorage);
  if (B.Data == nullptr && B.Size == 0) {
    Header.FdrData = FdrAdditionalHeaderData{BQ->ConfiguredBufferSize()};
    return XRayBuffer{static_cast<void *>(&Header), sizeof(Header)};
  }

  static BufferQueue::const_iterator It{};
  static BufferQueue::const_iterator End{};
  static uint8_t *CurrentBuffer{nullptr};
  static size_t SerializedBufferSize = 0;
  if (B.Data == static_cast<void *>(&Header) && B.Size == sizeof(Header)) {
    // From this point on, we provide raw access to the raw buffer we're getting
    // from the BufferQueue. We're relying on the iterators from the current
    // Buffer queue.
    It = BQ->cbegin();
    End = BQ->cend();
  }

  if (CurrentBuffer != nullptr) {
    deallocateBuffer(CurrentBuffer, SerializedBufferSize);
    CurrentBuffer = nullptr;
  }

  if (It == End)
    return {nullptr, 0};

  // Set up the current buffer to contain the extents like we would when writing
  // out to disk. The difference here would be that we still write "empty"
  // buffers, or at least go through the iterators faithfully to let the
  // handlers see the empty buffers in the queue.
  //
  // We need this atomic fence here to ensure that writes happening to the
  // buffer have been committed before we load the extents atomically. Because
  // the buffer is not explicitly synchronised across threads, we rely on the
  // fence ordering to ensure that writes we expect to have been completed
  // before the fence are fully committed before we read the extents.
  atomic_thread_fence(memory_order_acquire);
  auto BufferSize = atomic_load(It->Extents, memory_order_acquire);
  SerializedBufferSize = BufferSize + sizeof(MetadataRecord);
  CurrentBuffer = allocateBuffer(SerializedBufferSize);
  if (CurrentBuffer == nullptr)
    return {nullptr, 0};

  // Write out the extents as a Metadata Record into the CurrentBuffer.
  MetadataRecord ExtentsRecord;
  ExtentsRecord.Type = uint8_t(RecordType::Metadata);
  ExtentsRecord.RecordKind =
      uint8_t(MetadataRecord::RecordKinds::BufferExtents);
  internal_memcpy(ExtentsRecord.Data, &BufferSize, sizeof(BufferSize));
  auto AfterExtents =
      static_cast<char *>(internal_memcpy(CurrentBuffer, &ExtentsRecord,
                                          sizeof(MetadataRecord))) +
      sizeof(MetadataRecord);
  internal_memcpy(AfterExtents, It->Data, BufferSize);

  XRayBuffer Result;
  Result.Data = CurrentBuffer;
  Result.Size = SerializedBufferSize;
  ++It;
  return Result;
}

// Must finalize before flushing.
XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT {
  if (atomic_load(&LoggingStatus, memory_order_acquire) !=
      XRayLogInitStatus::XRAY_LOG_FINALIZED) {
    if (Verbosity())
      Report("Not flushing log, implementation is not finalized.\n");
    return XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
  }

  if (atomic_exchange(&LogFlushStatus, XRayLogFlushStatus::XRAY_LOG_FLUSHING,
                      memory_order_release) ==
      XRayLogFlushStatus::XRAY_LOG_FLUSHING) {
    if (Verbosity())
      Report("Not flushing log, implementation is still flushing.\n");
    return XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
  }

  if (BQ == nullptr) {
    if (Verbosity())
      Report("Cannot flush when global buffer queue is null.\n");
    return XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
  }

  // We wait a number of milliseconds to allow threads to see that we've
  // finalised before attempting to flush the log.
  SleepForMillis(fdrFlags()->grace_period_ms);

  // At this point, we're going to uninstall the iterator implementation, before
  // we decide to do anything further with the global buffer queue.
  __xray_log_remove_buffer_iterator();

  // Once flushed, we should set the global status of the logging implementation
  // to "uninitialized" to allow for FDR-logging multiple runs.
  auto ResetToUnitialized = at_scope_exit([] {
    atomic_store(&LoggingStatus, XRayLogInitStatus::XRAY_LOG_UNINITIALIZED,
                 memory_order_release);
  });

  auto CleanupBuffers = at_scope_exit([] {
    auto &TLD = getThreadLocalData();
    if (TLD.Controller != nullptr)
      TLD.Controller->flush();
  });

  if (fdrFlags()->no_file_flush) {
    if (Verbosity())
      Report("XRay FDR: Not flushing to file, 'no_file_flush=true'.\n");

    atomic_store(&LogFlushStatus, XRayLogFlushStatus::XRAY_LOG_FLUSHED,
                 memory_order_release);
    return XRayLogFlushStatus::XRAY_LOG_FLUSHED;
  }

  // We write out the file in the following format:
  //
  //   1) We write down the XRay file header with version 1, type FDR_LOG.
  //   2) Then we use the 'apply' member of the BufferQueue that's live, to
  //      ensure that at this point in time we write down the buffers that have
  //      been released (and marked "used") -- we dump the full buffer for now
  //      (fixed-sized) and let the tools reading the buffers deal with the data
  //      afterwards.
  //
  LogWriter *LW = LogWriter::Open();
  if (LW == nullptr) {
    auto Result = XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
    atomic_store(&LogFlushStatus, Result, memory_order_release);
    return Result;
  }

  XRayFileHeader Header = fdrCommonHeaderInfo();
  Header.FdrData = FdrAdditionalHeaderData{BQ->ConfiguredBufferSize()};
  LW->WriteAll(reinterpret_cast<char *>(&Header),
               reinterpret_cast<char *>(&Header) + sizeof(Header));

  // Release the current thread's buffer before we attempt to write out all the
  // buffers. This ensures that in case we had only a single thread going, that
  // we are able to capture the data nonetheless.
  auto &TLD = getThreadLocalData();
  if (TLD.Controller != nullptr)
    TLD.Controller->flush();

  BQ->apply([&](const BufferQueue::Buffer &B) {
    // Starting at version 2 of the FDR logging implementation, we only write
    // the records identified by the extents of the buffer. We use the Extents
    // from the Buffer and write that out as the first record in the buffer.  We
    // still use a Metadata record, but fill in the extents instead for the
    // data.
    MetadataRecord ExtentsRecord;
    auto BufferExtents = atomic_load(B.Extents, memory_order_acquire);
    DCHECK(BufferExtents <= B.Size);
    ExtentsRecord.Type = uint8_t(RecordType::Metadata);
    ExtentsRecord.RecordKind =
        uint8_t(MetadataRecord::RecordKinds::BufferExtents);
    internal_memcpy(ExtentsRecord.Data, &BufferExtents, sizeof(BufferExtents));
    if (BufferExtents > 0) {
      LW->WriteAll(reinterpret_cast<char *>(&ExtentsRecord),
                   reinterpret_cast<char *>(&ExtentsRecord) +
                       sizeof(MetadataRecord));
      LW->WriteAll(reinterpret_cast<char *>(B.Data),
                   reinterpret_cast<char *>(B.Data) + BufferExtents);
    }
  });

  atomic_store(&LogFlushStatus, XRayLogFlushStatus::XRAY_LOG_FLUSHED,
               memory_order_release);
  return XRayLogFlushStatus::XRAY_LOG_FLUSHED;
}

XRayLogInitStatus fdrLoggingFinalize() XRAY_NEVER_INSTRUMENT {
  s32 CurrentStatus = XRayLogInitStatus::XRAY_LOG_INITIALIZED;
  if (!atomic_compare_exchange_strong(&LoggingStatus, &CurrentStatus,
                                      XRayLogInitStatus::XRAY_LOG_FINALIZING,
                                      memory_order_release)) {
    if (Verbosity())
      Report("Cannot finalize log, implementation not initialized.\n");
    return static_cast<XRayLogInitStatus>(CurrentStatus);
  }

  // Do special things to make the log finalize itself, and not allow any more
  // operations to be performed until re-initialized.
  if (BQ == nullptr) {
    if (Verbosity())
      Report("Attempting to finalize an uninitialized global buffer!\n");
  } else {
    BQ->finalize();
  }

  atomic_store(&LoggingStatus, XRayLogInitStatus::XRAY_LOG_FINALIZED,
               memory_order_release);
  return XRayLogInitStatus::XRAY_LOG_FINALIZED;
}

struct TSCAndCPU {
  uint64_t TSC = 0;
  unsigned char CPU = 0;
};

static TSCAndCPU getTimestamp() XRAY_NEVER_INSTRUMENT {
  // We want to get the TSC as early as possible, so that we can check whether
  // we've seen this CPU before. We also do it before we load anything else,
  // to allow for forward progress with the scheduling.
  TSCAndCPU Result;

  // Test once for required CPU features
  static pthread_once_t OnceProbe = PTHREAD_ONCE_INIT;
  static bool TSCSupported = true;
  pthread_once(
      &OnceProbe, +[] { TSCSupported = probeRequiredCPUFeatures(); });

  if (TSCSupported) {
    Result.TSC = __xray::readTSC(Result.CPU);
  } else {
    // FIXME: This code needs refactoring as it appears in multiple locations
    timespec TS;
    int result = clock_gettime(CLOCK_REALTIME, &TS);
    if (result != 0) {
      Report("clock_gettime(2) return %d, errno=%d", result, int(errno));
      TS = {0, 0};
    }
    Result.CPU = 0;
    Result.TSC = TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
  }
  return Result;
}

thread_local atomic_uint8_t Running{0};

static bool setupTLD(ThreadLocalData &TLD) XRAY_NEVER_INSTRUMENT {
  // Check if we're finalizing, before proceeding.
  {
    auto Status = atomic_load(&LoggingStatus, memory_order_acquire);
    if (Status == XRayLogInitStatus::XRAY_LOG_FINALIZING ||
        Status == XRayLogInitStatus::XRAY_LOG_FINALIZED) {
      if (TLD.Controller != nullptr) {
        TLD.Controller->flush();
        TLD.Controller = nullptr;
      }
      return false;
    }
  }

  if (UNLIKELY(TLD.Controller == nullptr)) {
    // Set up the TLD buffer queue.
    if (UNLIKELY(BQ == nullptr))
      return false;
    TLD.BQ = BQ;

    // Check that we have a valid buffer.
    if (TLD.Buffer.Generation != BQ->generation() &&
        TLD.BQ->releaseBuffer(TLD.Buffer) != BufferQueue::ErrorCode::Ok)
      return false;

    // Set up a buffer, before setting up the log writer. Bail out on failure.
    if (TLD.BQ->getBuffer(TLD.Buffer) != BufferQueue::ErrorCode::Ok)
      return false;

    // Set up the Log Writer for this thread.
    if (UNLIKELY(TLD.Writer == nullptr)) {
      auto *LWStorage = reinterpret_cast<FDRLogWriter *>(&TLD.LWStorage);
      new (LWStorage) FDRLogWriter(TLD.Buffer);
      TLD.Writer = LWStorage;
    } else {
      TLD.Writer->resetRecord();
    }

    auto *CStorage = reinterpret_cast<FDRController<> *>(&TLD.CStorage);
    new (CStorage)
        FDRController<>(TLD.BQ, TLD.Buffer, *TLD.Writer, clock_gettime,
                        atomic_load_relaxed(&ThresholdTicks));
    TLD.Controller = CStorage;
  }

  DCHECK_NE(TLD.Controller, nullptr);
  return true;
}

void fdrLoggingHandleArg0(int32_t FuncId,
                          XRayEntryType Entry) XRAY_NEVER_INSTRUMENT {
  auto TC = getTimestamp();
  auto &TSC = TC.TSC;
  auto &CPU = TC.CPU;
  RecursionGuard Guard{Running};
  if (!Guard)
    return;

  auto &TLD = getThreadLocalData();
  if (!setupTLD(TLD))
    return;

  switch (Entry) {
  case XRayEntryType::ENTRY:
  case XRayEntryType::LOG_ARGS_ENTRY:
    TLD.Controller->functionEnter(FuncId, TSC, CPU);
    return;
  case XRayEntryType::EXIT:
    TLD.Controller->functionExit(FuncId, TSC, CPU);
    return;
  case XRayEntryType::TAIL:
    TLD.Controller->functionTailExit(FuncId, TSC, CPU);
    return;
  case XRayEntryType::CUSTOM_EVENT:
  case XRayEntryType::TYPED_EVENT:
    break;
  }
}

void fdrLoggingHandleArg1(int32_t FuncId, XRayEntryType Entry,
                          uint64_t Arg) XRAY_NEVER_INSTRUMENT {
  auto TC = getTimestamp();
  auto &TSC = TC.TSC;
  auto &CPU = TC.CPU;
  RecursionGuard Guard{Running};
  if (!Guard)
    return;

  auto &TLD = getThreadLocalData();
  if (!setupTLD(TLD))
    return;

  switch (Entry) {
  case XRayEntryType::ENTRY:
  case XRayEntryType::LOG_ARGS_ENTRY:
    TLD.Controller->functionEnterArg(FuncId, TSC, CPU, Arg);
    return;
  case XRayEntryType::EXIT:
    TLD.Controller->functionExit(FuncId, TSC, CPU);
    return;
  case XRayEntryType::TAIL:
    TLD.Controller->functionTailExit(FuncId, TSC, CPU);
    return;
  case XRayEntryType::CUSTOM_EVENT:
  case XRayEntryType::TYPED_EVENT:
    break;
  }
}

void fdrLoggingHandleCustomEvent(void *Event,
                                 std::size_t EventSize) XRAY_NEVER_INSTRUMENT {
  auto TC = getTimestamp();
  auto &TSC = TC.TSC;
  auto &CPU = TC.CPU;
  RecursionGuard Guard{Running};
  if (!Guard)
    return;

  // Complain when we ever get at least one custom event that's larger than what
  // we can possibly support.
  if (EventSize >
      static_cast<std::size_t>(std::numeric_limits<int32_t>::max())) {
    static pthread_once_t Once = PTHREAD_ONCE_INIT;
    pthread_once(
        &Once, +[] {
          Report("Custom event size too large; truncating to %d.\n",
                 std::numeric_limits<int32_t>::max());
        });
  }

  auto &TLD = getThreadLocalData();
  if (!setupTLD(TLD))
    return;

  int32_t ReducedEventSize = static_cast<int32_t>(EventSize);
  TLD.Controller->customEvent(TSC, CPU, Event, ReducedEventSize);
}

void fdrLoggingHandleTypedEvent(size_t EventType, const void *Event,
                                size_t EventSize) noexcept
    XRAY_NEVER_INSTRUMENT {
  auto TC = getTimestamp();
  auto &TSC = TC.TSC;
  auto &CPU = TC.CPU;
  RecursionGuard Guard{Running};
  if (!Guard)
    return;

  // Complain when we ever get at least one typed event that's larger than what
  // we can possibly support.
  if (EventSize >
      static_cast<std::size_t>(std::numeric_limits<int32_t>::max())) {
    static pthread_once_t Once = PTHREAD_ONCE_INIT;
    pthread_once(
        &Once, +[] {
          Report("Typed event size too large; truncating to %d.\n",
                 std::numeric_limits<int32_t>::max());
        });
  }

  auto &TLD = getThreadLocalData();
  if (!setupTLD(TLD))
    return;

  int32_t ReducedEventSize = static_cast<int32_t>(EventSize);
  TLD.Controller->typedEvent(TSC, CPU, static_cast<uint16_t>(EventType), Event,
                             ReducedEventSize);
}

XRayLogInitStatus fdrLoggingInit(size_t, size_t, void *Options,
                                 size_t OptionsSize) XRAY_NEVER_INSTRUMENT {
  if (Options == nullptr)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

  s32 CurrentStatus = XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
  if (!atomic_compare_exchange_strong(&LoggingStatus, &CurrentStatus,
                                      XRayLogInitStatus::XRAY_LOG_INITIALIZING,
                                      memory_order_release)) {
    if (Verbosity())
      Report("Cannot initialize already initialized implementation.\n");
    return static_cast<XRayLogInitStatus>(CurrentStatus);
  }

  if (Verbosity())
    Report("Initializing FDR mode with options: %s\n",
           static_cast<const char *>(Options));

  // TODO: Factor out the flags specific to the FDR mode implementation. For
  // now, use the global/single definition of the flags, since the FDR mode
  // flags are already defined there.
  FlagParser FDRParser;
  FDRFlags FDRFlags;
  registerXRayFDRFlags(&FDRParser, &FDRFlags);
  FDRFlags.setDefaults();

  // Override first from the general XRAY_DEFAULT_OPTIONS compiler-provided
  // options until we migrate everyone to use the XRAY_FDR_OPTIONS
  // compiler-provided options.
  FDRParser.ParseString(useCompilerDefinedFlags());
  FDRParser.ParseString(useCompilerDefinedFDRFlags());
  auto *EnvOpts = GetEnv("XRAY_FDR_OPTIONS");
  if (EnvOpts == nullptr)
    EnvOpts = "";
  FDRParser.ParseString(EnvOpts);

  // FIXME: Remove this when we fully remove the deprecated flags.
  if (internal_strlen(EnvOpts) == 0) {
    FDRFlags.func_duration_threshold_us =
        flags()->xray_fdr_log_func_duration_threshold_us;
    FDRFlags.grace_period_ms = flags()->xray_fdr_log_grace_period_ms;
  }

  // The provided options should always override the compiler-provided and
  // environment-variable defined options.
  FDRParser.ParseString(static_cast<const char *>(Options));
  *fdrFlags() = FDRFlags;
  auto BufferSize = FDRFlags.buffer_size;
  auto BufferMax = FDRFlags.buffer_max;

  if (BQ == nullptr) {
    bool Success = false;
    BQ = reinterpret_cast<BufferQueue *>(&BufferQueueStorage);
    new (BQ) BufferQueue(BufferSize, BufferMax, Success);
    if (!Success) {
      Report("BufferQueue init failed.\n");
      return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
    }
  } else {
    if (BQ->init(BufferSize, BufferMax) != BufferQueue::ErrorCode::Ok) {
      if (Verbosity())
        Report("Failed to re-initialize global buffer queue. Init failed.\n");
      return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
    }
  }

  static pthread_once_t OnceInit = PTHREAD_ONCE_INIT;
  pthread_once(
      &OnceInit, +[] {
        atomic_store(&TicksPerSec,
                     probeRequiredCPUFeatures() ? getTSCFrequency()
                                                : __xray::NanosecondsPerSecond,
                     memory_order_release);
        pthread_key_create(
            &Key, +[](void *TLDPtr) {
              if (TLDPtr == nullptr)
                return;
              auto &TLD = *reinterpret_cast<ThreadLocalData *>(TLDPtr);
              if (TLD.BQ == nullptr)
                return;
              if (TLD.Buffer.Data == nullptr)
                return;
              auto EC = TLD.BQ->releaseBuffer(TLD.Buffer);
              if (EC != BufferQueue::ErrorCode::Ok)
                Report("At thread exit, failed to release buffer at %p; "
                       "error=%s\n",
                       TLD.Buffer.Data, BufferQueue::getErrorString(EC));
            });
      });

  atomic_store(&ThresholdTicks,
               atomic_load_relaxed(&TicksPerSec) *
                   fdrFlags()->func_duration_threshold_us / 1000000,
               memory_order_release);
  // Arg1 handler should go in first to avoid concurrent code accidentally
  // falling back to arg0 when it should have ran arg1.
  __xray_set_handler_arg1(fdrLoggingHandleArg1);
  // Install the actual handleArg0 handler after initialising the buffers.
  __xray_set_handler(fdrLoggingHandleArg0);
  __xray_set_customevent_handler(fdrLoggingHandleCustomEvent);
  __xray_set_typedevent_handler(fdrLoggingHandleTypedEvent);

  // Install the buffer iterator implementation.
  __xray_log_set_buffer_iterator(fdrIterator);

  atomic_store(&LoggingStatus, XRayLogInitStatus::XRAY_LOG_INITIALIZED,
               memory_order_release);

  if (Verbosity())
    Report("XRay FDR init successful.\n");
  return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
}

bool fdrLogDynamicInitializer() XRAY_NEVER_INSTRUMENT {
  XRayLogImpl Impl{
      fdrLoggingInit,
      fdrLoggingFinalize,
      fdrLoggingHandleArg0,
      fdrLoggingFlush,
  };
  auto RegistrationResult = __xray_log_register_mode("xray-fdr", Impl);
  if (RegistrationResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK &&
      Verbosity()) {
    Report("Cannot register XRay FDR mode to 'xray-fdr'; error = %d\n",
           RegistrationResult);
    return false;
  }

  if (flags()->xray_fdr_log ||
      !internal_strcmp(flags()->xray_mode, "xray-fdr")) {
    auto SelectResult = __xray_log_select_mode("xray-fdr");
    if (SelectResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK &&
        Verbosity()) {
      Report("Cannot select XRay FDR mode as 'xray-fdr'; error = %d\n",
             SelectResult);
      return false;
    }
  }
  return true;
}

} // namespace __xray

static auto UNUSED Unused = __xray::fdrLogDynamicInitializer();
