18 #ifndef _FAULT_INJECTION_H
19 #define _FAULT_INJECTION_H
25 #define fiu_init(flags) 0
26 #define fiu_fail(name) 0
27 #define fiu_failinfo() NULL
28 #define fiu_do_on(name, action)
29 #define fiu_exit_on(name)
30 #define fiu_return_on(name, retval)
33 static inline std::string fault_injection_last_info() {
return ""; }
38 #include <sys/types.h>
44 #include <fiu-control.h>
47 static constexpr
size_t fault_injection_info_bs = 256;
49 static inline const char *fault_injection_info_fn() {
50 static std::mutex mutex;
51 static std::array<char, 128> info_fn{};
53 std::lock_guard<std::mutex> lock(mutex);
55 if (info_fn[0] !=
'\0') {
56 return info_fn.data();
59 snprintf(info_fn.data(), info_fn.size(),
"/tmp/fiu-ctrl-info-%lu",
static_cast<uint64_t
>(getpid()));
61 return info_fn.data();
64 static inline std::string fault_injection_last_info() {
65 auto info_id =
reinterpret_cast<uint64_t
>(fiu_failinfo());
67 std::array<char, fault_injection_info_bs> arr{};
68 std::streamoff offset = (info_id & 0xfffffff) * fault_injection_info_bs;
70 f.exceptions(std::ifstream::failbit | std::ifstream::badbit);
75 const char *fn =
nullptr;
76 if ((info_id & (1LU << 31)) != 0) {
77 fn = getenv(
"FIU_INFO_FILE");
79 fn = fault_injection_info_fn();
81 f.open(fn, std::ios::binary);
83 f.get(arr.data(), arr.size());
85 std::string info(arr.data());
87 }
catch (std::ifstream::failure &e) {
93 static inline int fault_injection_enable(
const char *name,
int failnum,
const std::string &failinfo,
95 std::array<char, fault_injection_info_bs> arr{};
96 std::copy(failinfo.cbegin(), failinfo.cend(), arr.data());
98 size_t failinfo_id = 0;
100 if (failinfo !=
"") {
102 f.exceptions(std::ifstream::failbit | std::ifstream::badbit);
105 f.open(fault_injection_info_fn(), std::ios::binary | std::ios::app);
106 size_t fi_id =
static_cast<size_t>(f.tellp()) / fault_injection_info_bs;
107 f.write(arr.data(), arr.size());
109 }
catch (std::ofstream::failure &e) {
113 return fiu_enable(name, failnum,
reinterpret_cast<void *
>(failinfo_id), flags);
118 static inline void fault_injection_init() {
122 f.open(fault_injection_info_fn(), std::ios::binary);
123 }
catch (std::ofstream::failure &e) {
127 #define fault_injection_disable fiu_disable