-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdebug.cpp
More file actions
92 lines (79 loc) · 2.32 KB
/
debug.cpp
File metadata and controls
92 lines (79 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "debug.h"
#include "containers.h"
#include "parse_flags.h"
#include "typedefs.h"
#include <execinfo.h>
using namespace __otfcpt;
std::atomic<uint32_t> current_verbosity{0};
void print_stack(CptStreamBuffer &stream) {
#ifdef USE_BACKWARD
using namespace backward;
StackTrace st;
st.load_here(CALLSTACK_SIZE);
st.skip_n_firsts(SKIP_FRAMES);
Printer p;
p.object = true;
p.color_mode = ColorMode::always;
p.address = true;
std::stringstream stringbuffer;
p.print(st, stringbuffer);
stream << stringbuffer.str().c_str() << "\n";
#else
int nptrs;
void *buf[CALLSTACK_SIZE + 1];
nptrs = backtrace(buf, CALLSTACK_SIZE);
char **symbols = backtrace_symbols(buf, nptrs);
if (!symbols) {
stream << "Stack trace failed\n";
return;
}
for (int i = 0; i < nptrs; i++) {
stream << symbols[i] << "\n";
}
free(symbols);
#endif
}
void print_stack() {
char buffer[DBG_BUFFER_SIZE];
CptStreamBuffer stream(buffer, DBG_BUFFER_SIZE);
FILE *out =
(get_otfcpt_flags()->output ? get_otfcpt_flags()->output : stderr);
print_stack(stream);
stream.fflush(out);
}
void NORETURN Die() {
if (get_otfcpt_flags()->abort_on_error)
abort();
exit(get_otfcpt_flags()->exitcode);
}
void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2,
std::initializer_list<const char *> msgs) {
char buffer[DBG_BUFFER_SIZE];
CptStreamBuffer stream(buffer, DBG_BUFFER_SIZE);
FILE *out =
(get_otfcpt_flags()->output ? get_otfcpt_flags()->output : stderr);
stream << "\nCheck failed in " << file << ":" << line << " "
<< (unsigned long long)v1 << " " << cond << " "
<< (unsigned long long)v2 << "\n";
for (auto &m : msgs) {
stream << m;
}
print_stack(stream);
stream.fflush(out);
if (!get_otfcpt_flags()->continue_on_error) {
Die();
}
}
// std::atomic needs this function in debug config
#ifndef USE_STL
namespace std {
extern "C++" _GLIBCXX_NORETURN __attribute__((__cold__)) void
__glibcxx_assert_fail /* Called when a precondition violation is detected.
*/
(const char *__file, int __line, const char *__function,
const char *__condition) _GLIBCXX_NOEXCEPT {
CheckFailed(__file, __line, __condition, 0, 0, {__function});
abort(); // this function should be noreturn
}
} // namespace std
#endif