1 | // This will sometimes segfault on the AArch64 and Arm bots |
2 | // UNSUPPORTED: target={{(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(m: std::memory_order_acquire); |
25 | std::thread t([] { |
26 | while (keep_going.test_and_set(m: 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(Mode: "xray-fdr" , Config: 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(Mode: "xray-fdr" , Config: 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(m: std::memory_order_release); |
74 | |
75 | // Then join. |
76 | t.join(); |
77 | } |
78 | |