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
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 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

source code of compiler-rt/test/xray/TestCases/Posix/fdr-reinit.cpp