1 // This will sometimes segfault on the AArch64 and Arm bots 2 // UNSUPPORTED: aarch64, arm 3 // RUN: %clangxx_xray -g -std=c++11 %s -o %t 4 // RUN: rm xray-log.fdr-reinit* || true 5 // RUN: XRAY_OPTIONS="verbosity=1" %run %t 6 // RUN: rm xray-log.fdr-reinit* || true 7 #include "xray/xray_log_interface.h" 8 #include <atomic> 9 #include <cassert> 10 #include <cstddef> 11 #include <thread> 12 13 volatile uint64_t var = 0; 14 15 std::atomic_flag keep_going = ATOMIC_FLAG_INIT; 16 17 [[clang::xray_always_instrument]] void __attribute__((noinline)) func() { 18 ++var; 19 } 20 21 int main(int argc, char *argv[]) { 22 // Start a thread that will just keep calling the function, to spam calls to 23 // 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