78 lines · cpp
1// This will sometimes segfault on the AArch64 and Arm bots2// UNSUPPORTED: target={{(aarch64|arm).*}}3// RUN: %clangxx_xray -g -std=c++11 %s -o %t4// RUN: rm xray-log.fdr-reinit* || true5// RUN: env XRAY_OPTIONS="verbosity=1" %run %t6// RUN: rm xray-log.fdr-reinit* || true7#include "xray/xray_log_interface.h"8#include <atomic>9#include <cassert>10#include <cstddef>11#include <thread>12 13volatile uint64_t var = 0;14 15std::atomic_flag keep_going = ATOMIC_FLAG_INIT;16 17[[clang::xray_always_instrument]] void __attribute__((noinline)) func() {18 ++var;19}20 21int main(int argc, char *argv[]) {22 // Start a thread that will just keep calling the function, to spam calls to23 // the function call handler.24 keep_going.test_and_set(std::memory_order_acquire);25 std::thread t([] {26 while (keep_going.test_and_set(std::memory_order_acquire))27 func();28 });29 30 static constexpr char kConfig[] =31 "buffer_size=1024:buffer_max=10:no_file_flush=true";32 33 // Then we initialize the FDR mode implementation.34 assert(__xray_log_select_mode("xray-fdr") ==35 XRayLogRegisterStatus::XRAY_REGISTRATION_OK);36 auto init_status = __xray_log_init_mode("xray-fdr", kConfig);37 assert(init_status == XRayLogInitStatus::XRAY_LOG_INITIALIZED);38 39 // Now we patch the instrumentation points.40 __xray_patch();41 42 // Spin for a bit, calling func() enough times.43 for (auto i = 0; i < 1 << 20; ++i)44 func();45 46 // Then immediately finalize the implementation.47 auto finalize_status = __xray_log_finalize();48 assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED);49 50 // Once we're here, we should then flush.51 auto flush_status = __xray_log_flushLog();52 assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);53 54 for (auto trial = 0; trial < 3; trial++) {55 // Without doing anything else, we should re-initialize.56 init_status = __xray_log_init_mode("xray-fdr", kConfig);57 assert(init_status == XRayLogInitStatus::XRAY_LOG_INITIALIZED);58 59 // Then we spin for a bit again calling func() enough times.60 for (auto i = 0; i < 1 << 20; ++i)61 func();62 63 // Then immediately finalize the implementation.64 finalize_status = __xray_log_finalize();65 assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED);66 67 // Once we're here, we should then flush.68 flush_status = __xray_log_flushLog();69 assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);70 }71 72 // Finally, we should signal the sibling thread to stop.73 keep_going.clear(std::memory_order_release);74 75 // Then join.76 t.join();77}78