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 
func()17 [[clang::xray_always_instrument]] void __attribute__((noinline)) func() {
18   ++var;
19 }
20 
main(int argc,char * argv[])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