96 lines · cpp
1// Check that we can install an implementation associated with a mode.2//3// RUN: rm -f xray-log.logging-modes*4// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=none5// RUN: %run %t | FileCheck %s6//7// UNSUPPORTED: target-is-mips64,target-is-mips64el8 9#include "xray/xray_interface.h"10#include "xray/xray_log_interface.h"11#include <cassert>12#include <cstdio>13#include <string>14 15[[clang::xray_never_instrument]] void printing_handler(int32_t fid,16 XRayEntryType) {17 thread_local volatile bool printing = false;18 if (printing)19 return;20 printing = true;21 std::printf("printing %d\n", fid);22 printing = false;23}24 25[[clang::xray_never_instrument]] XRayBuffer next_buffer(XRayBuffer buffer) {26 static const char data[10] = {};27 static const XRayBuffer first_and_last{data, 10};28 if (buffer.Data == nullptr)29 return first_and_last;30 if (buffer.Data == first_and_last.Data)31 return XRayBuffer{nullptr, 0};32 assert(false && "Invalid buffer provided.");33}34 35static constexpr char Options[] = "additional_flags";36 37[[clang::xray_never_instrument]] XRayLogInitStatus38printing_init(size_t BufferSize, size_t MaxBuffers, void *Config,39 size_t ArgsSize) {40 // We require that the printing init is called through the41 // __xray_log_init_mode(...) implementation, and that the promised contract is42 // enforced.43 assert(BufferSize == 0);44 assert(MaxBuffers == 0);45 assert(Config != nullptr);46 assert(ArgsSize == 0 || ArgsSize == sizeof(Options));47 __xray_log_set_buffer_iterator(next_buffer);48 return XRayLogInitStatus::XRAY_LOG_INITIALIZED;49}50 51[[clang::xray_never_instrument]] XRayLogInitStatus printing_finalize() {52 return XRayLogInitStatus::XRAY_LOG_FINALIZED;53}54 55[[clang::xray_never_instrument]] XRayLogFlushStatus printing_flush_log() {56 __xray_log_remove_buffer_iterator();57 return XRayLogFlushStatus::XRAY_LOG_FLUSHED;58}59 60[[clang::xray_always_instrument]] void callme() { std::printf("called me!\n"); }61 62static auto buffer_counter = 0;63 64void process_buffer(const char *, XRayBuffer) { ++buffer_counter; }65 66int main(int argc, char **argv) {67 assert(__xray_log_register_mode("custom",68 {printing_init, printing_finalize,69 printing_handler, printing_flush_log}) ==70 XRayLogRegisterStatus::XRAY_REGISTRATION_OK);71 assert(__xray_log_select_mode("custom") ==72 XRayLogRegisterStatus::XRAY_REGISTRATION_OK);73 assert(__xray_log_get_current_mode() != nullptr);74 std::string current_mode = __xray_log_get_current_mode();75 assert(current_mode == "custom");76 assert(__xray_patch() == XRayPatchingStatus::SUCCESS);77 assert(__xray_log_init_mode("custom", "flags_config_here=true") ==78 XRayLogInitStatus::XRAY_LOG_INITIALIZED);79 80 // Also test that we can use the "binary" version of the81 // __xray_log_niit_mode(...) API.82 assert(__xray_log_init_mode_bin("custom", Options, sizeof(Options)) ==83 XRayLogInitStatus::XRAY_LOG_INITIALIZED);84 85 // CHECK: printing {{.*}}86 callme(); // CHECK: called me!87 // CHECK: printing {{.*}}88 assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);89 assert(__xray_log_process_buffers(process_buffer) ==90 XRayLogFlushStatus::XRAY_LOG_FLUSHED);91 assert(buffer_counter == 1);92 assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);93 assert(__xray_log_select_mode("not-found") ==94 XRayLogRegisterStatus::XRAY_MODE_NOT_FOUND);95}96