rippled
Loading...
Searching...
No Matches
instrumentation.h
1//------------------------------------------------------------------------------
2/*
3This file is part of rippled: https://github.com/ripple/rippled
4Copyright (c) 2024 Ripple Labs Inc.
5
6Permission to use, copy, modify, and/or distribute this software for any
7purpose with or without fee is hereby granted, provided that the above
8copyright notice and this permission notice appear in all copies.
9
10THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef BEAST_UTILITY_INSTRUMENTATION_H_INCLUDED
21#define BEAST_UTILITY_INSTRUMENTATION_H_INCLUDED
22
23#include <cassert>
24
25#ifdef ENABLE_VOIDSTAR
26#ifdef NDEBUG
27#error "Antithesis instrumentation requires Debug build"
28#endif
29#include <antithesis_sdk.h>
30#else
31// Macros below are copied from antithesis_sdk.h and slightly simplified
32// The duplication is because Visual Studio 2019 cannot compile that header
33// even with the option -Zc:__cplusplus added.
34#define ALWAYS(cond, message, ...) assert((message) && (cond))
35#define ALWAYS_OR_UNREACHABLE(cond, message, ...) assert((message) && (cond))
36#define SOMETIMES(cond, message, ...)
37#define REACHABLE(message, ...)
38#define UNREACHABLE(message, ...) assert((message) && false)
39#endif
40
41#define XRPL_ASSERT ALWAYS_OR_UNREACHABLE
42#define XRPL_ASSERT_PARTS(cond, function, description, ...) \
43 XRPL_ASSERT(cond, function " : " description)
44
45// How to use the instrumentation macros:
46//
47// * XRPL_ASSERT if cond must be true but the line might not be reached during
48// fuzzing. Same like `assert` in normal use.
49// * XRPL_ASSERT_PARTS is for convenience, and works like XRPL_ASSERT, but
50// splits the message param into "function" and "description", then joins
51// them with " : " before passing to XRPL_ASSERT.
52// * ALWAYS if cond must be true _and_ the line must be reached during fuzzing.
53// Same like `assert` in normal use.
54// * REACHABLE if the line must be reached during fuzzing
55// * SOMETIMES a hint for the fuzzer to try to make the cond true
56// * UNREACHABLE if the line must not be reached (in fuzzing or in normal use).
57// Same like `assert(false)` in normal use.
58//
59// NOTE: XRPL_ASSERT has similar semantics as C `assert` macro, with only minor
60// differences:
61// * XRPL_ASSERT must have an unique name (naming convention in CONTRIBUTING.md)
62// * during fuzzing, the program will continue execution past failed XRPL_ASSERT
63//
64// We continue to use regular C `assert` inside unit tests and inside constexpr
65// functions.
66//
67// NOTE: UNREACHABLE does *not* have the same semantics as std::unreachable.
68// The program will continue execution past an UNREACHABLE in a Release build
69// and during fuzzing (similar to failed XRPL_ASSERT).
70// Also, the naming convention in UNREACHABLE is subtly different from other
71// instrumentation macros - its name describes the condition which was _not_
72// meant to happen, while name in other macros describes the condition that is
73// meant to happen (e.g. as in "assert that this happens").
74
75#endif