// RUN: %clangxx_xray -g -std=c++11 %s -o %t // RUN: rm xray-log.fdr-reinit* || true // RUN: XRAY_OPTIONS="verbosity=1" %run %t // RUN: rm xray-log.fdr-reinit* || true #include "xray/xray_log_interface.h" #include #include #include #include volatile uint64_t var = 0; std::atomic_flag keep_going = ATOMIC_FLAG_INIT; [[clang::xray_always_instrument]] void __attribute__((noinline)) func() { ++var; } int main(int argc, char *argv[]) { // Start a thread that will just keep calling the function, to spam calls to // the function call handler. keep_going.test_and_set(std::memory_order_acquire); std::thread t([] { while (keep_going.test_and_set(std::memory_order_acquire)) func(); }); static constexpr char kConfig[] = "buffer_size=1024:buffer_max=10:no_file_flush=true"; // Then we initialize the FDR mode implementation. assert(__xray_log_select_mode("xray-fdr") == XRayLogRegisterStatus::XRAY_REGISTRATION_OK); auto init_status = __xray_log_init_mode("xray-fdr", kConfig); assert(init_status == XRayLogInitStatus::XRAY_LOG_INITIALIZED); // Now we patch the instrumentation points. __xray_patch(); // Spin for a bit, calling func() enough times. for (auto i = 0; i < 1 << 20; ++i) func(); // Then immediately finalize the implementation. auto finalize_status = __xray_log_finalize(); assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED); // Once we're here, we should then flush. auto flush_status = __xray_log_flushLog(); assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED); // Without doing anything else, we should re-initialize. init_status = __xray_log_init_mode("xray-fdr", kConfig); assert(init_status == XRayLogInitStatus::XRAY_LOG_INITIALIZED); // Then we spin for a bit again calling func() enough times. for (auto i = 0; i < 1 << 20; ++i) func(); // Then immediately finalize the implementation. finalize_status = __xray_log_finalize(); assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED); // Once we're here, we should then flush. flush_status = __xray_log_flushLog(); assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED); // Finally, we should signal the sibling thread to stop. keep_going.clear(std::memory_order_release); // Then join. t.join(); }