VAPOR3 3.9.4
debug.h
Go to the documentation of this file.
1#ifndef DEBUG_H
2#define DEBUG_H
3
4#ifdef NDEBUG
5 #define dLog(...)
6 #define dBreak()
7 #define dBreakIf(x)
8 #define dBreakCount(x)
9 #define FTRACE(...)
10 #define PERF_TIMER_START
11 #define PERF_TIMER_STOP
12 #define PERF_TIMER_DELTA 1
13#else
14
15 #include <signal.h>
16 #include <stdio.h>
17 #include <string>
18 #include <vector>
19
20 #define DLOG_BASENAME_ONLY 1
21
22 #ifdef WIN32
23 #undef DLOG_BASENAME_ONLY
24 #endif
25
26 #if DLOG_BASENAME_ONLY
27 #include <libgen.h>
28 #define dLog_pre() fprintf(stderr, "[%s:%i:%s] ", basename(__FILE__), __LINE__, __func__)
29 #else
30 #define dLog_pre() fprintf(stderr, "[%s:%i:%s] ", __FILE__, __LINE__, __func__)
31 #endif
32
33 #define dLog(...) \
34 { \
35 dLog_pre(); \
36 fprintf(stderr, __VA_ARGS__); \
37 fprintf(stderr, "\n"); \
38 }
39 #define dBreak() \
40 { \
41 dLog("Breakpoint"); \
42 raise(SIGTRAP); \
43 }
44 #define dBreakIf(x) \
45 { \
46 if (x) { dBreak(); } \
47 }
48 #define dBreakCount(x) \
49 { \
50 static int count = 0; \
51 if (++count == (x)) dBreak(); \
52 }
53
54 #if WIN32
55 #define PERF_TIMER_START
56 #define PERF_TIMER_STOP
57 #define PERF_TIMER_DELTA 1
58 #else
59 #include <sys/time.h>
60 #define PERF_TIMER_START \
61 struct timeval PERF_TIMER_T1, PERF_TIMER_T2; \
62 gettimeofday(&PERF_TIMER_T1, NULL);
63 #define PERF_TIMER_STOP gettimeofday(&PERF_TIMER_T2, NULL);
64 #define PERF_TIMER_DELTA ((PERF_TIMER_T2.tv_usec - PERF_TIMER_T1.tv_usec) / 1000000.0 + (double)(PERF_TIMER_T2.tv_sec - PERF_TIMER_T1.tv_sec))
65 #endif
66
67 #ifdef WIN32
68 #define PRINT_BACKTRACE()
69 #else
70 #include <execinfo.h>
71 #define PRINT_BACKTRACE(...) \
72 { \
73 printf("------------------ %s", __func__); \
74 printf(__VA_ARGS__); \
75 printf(" ------------------\n"); \
76 void **buffer = (void **)malloc(sizeof(void *) * 32); \
77 int depth = backtrace(buffer, 32); \
78 fflush(stdout); \
79 backtrace_symbols_fd(buffer, depth, fileno(stdout)); \
80 free(buffer); \
81 }
82 #endif
83
84using std::string;
85using std::vector;
86
87 #define VDC_LIBTRACE
88 // #define VDC_LIBTRACE_RUNNABLE
89 #ifdef VDC_LIBTRACE
90
91 #define NARG(...) NARG_(__VA_ARGS__, RSEQ_N())
92 #define NARG_(...) ARG_N(__VA_ARGS__)
93 #define ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
94 #define RSEQ_N() 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
95
96inline void PRINTARG() {}
97inline void PRINTARG(int x) { printf("%i", x); }
98inline void PRINTARG(long x) { printf("%li", x); }
99inline void PRINTARG(size_t x) { printf("%li", x); }
100inline void PRINTARG(float x) { printf("%g", x); }
101inline void PRINTARG(double x) { printf("%g", x); }
102inline void PRINTARG(bool x) { printf("%s", x ? "true" : "false"); }
103inline void PRINTARG(const std::string x) { printf("\"%s\"", x.c_str()); }
104inline void PRINTARG(const char *x) { printf("\"%s\"", x); }
105 #ifdef VDC_LIBTRACE_RUNNABLE
106inline void PRINTARG(const int *i) { printf("(int[]){%i}", *i); }
107inline void PRINTARG(const float *f) { printf("(float[]){%f}", *f); }
108inline void PRINTARG(const double *d) { printf("(double[]){%d}", *d); }
109inline void PRINTARG(const size_t *li) { printf("(size_t[]){%li}", *li); }
110inline void PRINTARG(const long *li) { printf("(long[]){%li}", *li); }
111 #else
112inline void PRINTARG(const int *i) { printf("*[%i]", *i); }
113inline void PRINTARG(const float *f) { printf("*[%f]", *f); }
114inline void PRINTARG(const double *d) { printf("*[%f]", *d); }
115inline void PRINTARG(const size_t *li) { printf("*[%li]", *li); }
116inline void PRINTARG(const long *li) { printf("*[%li]", *li); }
117 #endif
118inline void PRINTARG(const void *x) { printf("%s", x ? "<ptr>" : "NULL"); }
119// void PRINTARG(const VAPoR::VDC::AccessMode x) { printf("VDC::AccessMode::%s", x==VAPoR::VDC::AccessMode::R?"R":x==VAPoR::VDC::AccessMode::W?"W":"A"); }
120// void PRINTARG(const VAPoR::DC::XType x)
121// {
122// switch (x) {
123// case VAPoR::DC::XType::INVALID: printf("DC::INVALID"); break;
124// case VAPoR::DC::XType::FLOAT: printf("DC::FLOAT"); break;
125// case VAPoR::DC::XType::DOUBLE: printf("DC::DOUBLE"); break;
126// case VAPoR::DC::XType::UINT8: printf("DC::UINT8"); break;
127// case VAPoR::DC::XType::INT8: printf("DC::INT8"); break;
128// case VAPoR::DC::XType::INT32: printf("DC::INT32"); break;
129// case VAPoR::DC::XType::INT64: printf("DC::INT64"); break;
130// case VAPoR::DC::XType::TEXT: printf("DC::TEXT"); break;
131// }
132// }
133template<class T> void PRINTARG(const std::vector<T> v)
134{
135 #ifdef VDC_LIBTRACE_RUNNABLE
136 if (v.size() == 1) {
137 string t(__PRETTY_FUNCTION__);
138 int s = t.find("[T = ") + strlen("[T = ");
139 int f = t.find("]", s);
140 t = t.substr(s, f - s);
141 printf("vector<%s>(1, ", t.c_str());
142 } else
143 #endif
144 printf("{");
145 for (int i = 0; i < v.size(); i++) {
146 PRINTARG(v[i]);
147 if (i != v.size() - 1) printf(", ");
148 }
149 #ifdef VDC_LIBTRACE_RUNNABLE
150 if (v.size() == 1)
151 printf(")");
152 else
153 #endif
154 printf("}");
155}
156
157inline std::string classScopeFromPrettyFunc(const std::string &pretty)
158{
159 size_t args = pretty.find("(");
160 size_t colons = pretty.substr(0, args).rfind("::");
161 if (colons == std::string::npos) return "";
162 size_t begin = pretty.substr(0, colons).rfind(" ") + 1;
163 size_t end = colons - begin;
164
165 return pretty.substr(begin, end) + "::";
166}
167
168 #define _CONCAT(a, b) a##b
169 #define PRINTARGS_1(x, ...) \
170 { \
171 PRINTARG(x); \
172 }
173 #define PRINTARGS_2(x, ...) \
174 { \
175 PRINTARG(x); \
176 printf(", "); \
177 PRINTARGS_1(__VA_ARGS__); \
178 }
179 #define PRINTARGS_3(x, ...) \
180 { \
181 PRINTARG(x); \
182 printf(", "); \
183 PRINTARGS_2(__VA_ARGS__); \
184 }
185 #define PRINTARGS_4(x, ...) \
186 { \
187 PRINTARG(x); \
188 printf(", "); \
189 PRINTARGS_3(__VA_ARGS__); \
190 }
191 #define PRINTARGS_5(x, ...) \
192 { \
193 PRINTARG(x); \
194 printf(", "); \
195 PRINTARGS_4(__VA_ARGS__); \
196 }
197 #define PRINTARGS_6(x, ...) \
198 { \
199 PRINTARG(x); \
200 printf(", "); \
201 PRINTARGS_5(__VA_ARGS__); \
202 }
203 #define PRINTARGS_7(x, ...) \
204 { \
205 PRINTARG(x); \
206 printf(", "); \
207 PRINTARGS_6(__VA_ARGS__); \
208 }
209 #define PRINTARGS_8(x, ...) \
210 { \
211 PRINTARG(x); \
212 printf(", "); \
213 PRINTARGS_7(__VA_ARGS__); \
214 }
215 #define PRINTARGS_9(x, ...) \
216 { \
217 PRINTARG(x); \
218 printf(", "); \
219 PRINTARGS_8(__VA_ARGS__); \
220 }
221 #define _PRINTARGS(n, ...) \
222 _CONCAT(PRINTARGS_, n) \
223 (__VA_ARGS__)
224 #define PRINTARGS(...) _PRINTARGS(NARG(__VA_ARGS__), __VA_ARGS__)
225 #define FTRACE_PRE() printf("%s%s(", classScopeFromPrettyFunc(__PRETTY_FUNCTION__).c_str(), __func__)
226 #define FTRACE(...) \
227 do { \
228 FTRACE_PRE(); \
229 PRINTARGS(__VA_ARGS__); \
230 printf(");\n"); \
231 } while (0)
232
233 #else
234 #define FTRACE(...)
235 #endif
236
237#endif
238
239#endif
void PRINTARG()
Definition: debug.h:96
std::string classScopeFromPrettyFunc(const std::string &pretty)
Definition: debug.h:157