jaulib v1.3.0
Jau Support Library (C++, Java, ..)
debug.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 * Copyright (c) 2020 ZAFENA AB
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef JAU_DEBUG_HPP_
27#define JAU_DEBUG_HPP_
28
29#include <memory>
30
31#include <cstdint>
32#include <cinttypes>
33#include <cstring>
34#include <string>
35#include <cstdio>
36#include <cstdarg>
37
38extern "C" {
39 #include <errno.h>
40}
41
42#include <jau/environment.hpp>
43#include <jau/backtrace.hpp>
44
45// #define PERF_PRINT_ON 1
46
47namespace jau {
48
49 void DBG_PRINT_impl(const char * format, ...) noexcept;
50
51 /** Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] Debug: '. */
52 #define DBG_PRINT(...) { if( jau::environment::get().debug ) { jau::DBG_PRINT_impl(__VA_ARGS__); } }
53
54 /** Use for environment-variable environment::DEBUG conditional warning messages, prefix '[elapsed_time] Warning @ FILE:LINE FUNC: ' */
55 #define DBG_WARN_PRINT(...) { if( jau::environment::get().debug ) { jau::WARN_PRINT_impl(__func__, __FILE__, __LINE__, __VA_ARGS__); } }
56
57 /** Use for environment-variable environment::DEBUG_JNI conditional debug messages, prefix '[elapsed_time] Debug: '. */
58 #define DBG_JNI_PRINT(...) { if( jau::environment::get().debug_jni ) { jau::DBG_PRINT_impl(__VA_ARGS__); } }
59
60 void WORDY_PRINT_impl(const char * format, ...) noexcept;
61
62 /**
63 * Use for environment-variable environment::VERBOSE conditional verbose messages, prefix '[elapsed_time] Wordy: '.
64 * <p>
65 * 'Wordy' is the shorter English form of the Latin word 'verbosus', from which the word 'verbosity' is sourced.
66 * </p>
67 */
68 #define WORDY_PRINT(...) { if( jau::environment::get().verbose ) { jau::WORDY_PRINT_impl(__VA_ARGS__); } }
69
70
71 #define PERF_TS_T0_BASE() const uint64_t _t0 = jau::getCurrentMilliseconds()
72
73 #define PERF_TS_TD_BASE(m) { const uint64_t _td = jau::getCurrentMilliseconds() - _t0; \
74 fprintf(stderr, "[%s] PERF %s done in %d ms,\n", jau::to_decstring(jau::environment::getElapsedMillisecond(), ',', 9).c_str(), (m), (int)_td); }
75 #ifdef PERF_PRINT_ON
76 #define PERF_TS_T0() PERF_TS_T0_BASE()
77 #define PERF_TS_TD(m) PERF_TS_TD_BASE(m)
78 #else
79 #define PERF_TS_T0()
80 #define PERF_TS_TD(m)
81 #endif
82 #ifdef PERF2_PRINT_ON
83 #define PERF2_TS_T0() PERF_TS_T0_BASE()
84 #define PERF2_TS_TD(m) PERF_TS_TD_BASE(m)
85 #else
86 #define PERF2_TS_T0()
87 #define PERF2_TS_TD(m)
88 #endif
89 #ifdef PERF3_PRINT_ON
90 #define PERF3_TS_T0() PERF_TS_T0_BASE()
91 #define PERF3_TS_TD(m) PERF_TS_TD_BASE(m)
92 #else
93 #define PERF3_TS_T0()
94 #define PERF3_TS_TD(m)
95 #endif
96
97 /** Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line func: '. Function also appends last errno and strerror(errno). */
98 void ABORT_impl(const char *func, const char *file, const int line, const char * format, ...) noexcept;
99
100 /** Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line func: '. Function also appends last errno and strerror(errno). */
101 #define ABORT(...) { jau::ABORT_impl(__func__, __FILE__, __LINE__, __VA_ARGS__); }
102
103 /** Use for unconditional error messages, prefix '[elapsed_time] Error @ file:line func: '. Function also appends last errno and strerror(errno). */
104 void ERR_PRINTv(const char *func, const char *file, const int line, const char * format, va_list args) noexcept;
105
106 void ERR_PRINT_impl(const char *prefix, const bool backtrace, const char *func, const char *file, const int line, const char * format, ...) noexcept;
107
108 /** Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '. Function also appends last errno, strerror(errno) and full backtrace*/
109 #define ERR_PRINT(...) { jau::ERR_PRINT_impl("Error", true /* backtrace */, __func__, __FILE__, __LINE__, __VA_ARGS__); }
110
111 /** Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '. Function also appends last errno and strerror(errno). No backtrace. */
112 #define ERR_PRINT2(...) { jau::ERR_PRINT_impl("Error", false /* backtrace */, __func__, __FILE__, __LINE__, __VA_ARGS__); }
113
114 /** Use for unconditional interruption messages, prefix '[elapsed_time] Interrupted @ FILE:LINE FUNC: '. Function also appends last errno and strerror(errno). */
115 #define IRQ_PRINT(...) { jau::ERR_PRINT_impl("Interrupted", false /* backtrace */, __func__, __FILE__, __LINE__, __VA_ARGS__); }
116
117 /** Use for unconditional warning messages, prefix '[elapsed_time] Warning @ file:line func: ' */
118 void WARN_PRINTv(const char *func, const char *file, const int line, const char * format, va_list args) noexcept;
119
120 void WARN_PRINT_impl(const char *func, const char *file, const int line, const char * format, ...) noexcept;
121
122 /** Use for unconditional warning messages, prefix '[elapsed_time] Warning @ FILE:LINE FUNC: ' */
123 #define WARN_PRINT(...) { jau::WARN_PRINT_impl(__func__, __FILE__, __LINE__, __VA_ARGS__); }
124
125 /** Use for unconditional informal messages, prefix '[elapsed_time] Info: '. */
126 void INFO_PRINT(const char * format, ...) noexcept;
127
128 /** Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true. */
129 void PLAIN_PRINT(const bool printPrefix, const char * format, ...) noexcept;
130
131 /**
132 * Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
133 * @param elapsed_ms the given elapsed time in milliseconds
134 * @param stream the output stream
135 * @param format the format
136 * @param args the optional arguments
137 */
138 int fprintf_td(const uint64_t elapsed_ms, FILE* stream, const char * format, ...) noexcept;
139
140 /**
141 * Convenient fprintf() invocation, prepending the environment::getElapsedMillisecond() timestamp.
142 * @param stream the output stream
143 * @param format the format
144 * @param args the optional arguments
145 */
146 int fprintf_td(FILE* stream, const char * format, ...) noexcept;
147
148 void COND_PRINT_impl(const char * format, ...) noexcept;
149
150 /** Use for conditional plain messages, prefix '[elapsed_time] '. */
151 #define COND_PRINT(C, ...) { if( C ) { jau::COND_PRINT_impl(__VA_ARGS__); } }
152
153
154 template<class List>
155 inline void printSharedPtrList(const std::string& prefix, List & list) noexcept {
156 fprintf(stderr, "%s: Start: %zu elements\n", prefix.c_str(), (size_t)list.size());
157 int idx = 0;
158 for (auto it = list.begin(); it != list.end(); idx++) {
159 typename List::value_type & e = *it;
160 if ( nullptr != e ) {
161 fprintf(stderr, "%s[%d]: useCount %zu, mem %p\n", prefix.c_str(), idx, (size_t)e.use_count(), e.get());
162 } else {
163 fprintf(stderr, "%s[%d]: NULL\n", prefix.c_str(), idx);
164 }
165 ++it;
166 }
167 }
168
169} // namespace jau
170
171#endif /* JAU_DEBUG_HPP_ */
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
void ABORT_impl(const char *func, const char *file, const int line, const char *format,...) noexcept
Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line fu...
Definition: debug.cpp:198
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
Definition: debug.cpp:258
void ERR_PRINTv(const char *func, const char *file, const int line, const char *format, va_list args) noexcept
Use for unconditional error messages, prefix '[elapsed_time] Error @ file:line func: '.
Definition: debug.cpp:210
void INFO_PRINT(const char *format,...) noexcept
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.
Definition: debug.cpp:248
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
Definition: debug.cpp:270
void WARN_PRINTv(const char *func, const char *file, const int line, const char *format, va_list args) noexcept
Use for unconditional warning messages, prefix '[elapsed_time] Warning @ file:line func: '.
Definition: debug.cpp:231
void DBG_PRINT_impl(const char *format,...) noexcept
Definition: debug.cpp:178
void ERR_PRINT_impl(const char *prefix, const bool backtrace, const char *func, const char *file, const int line, const char *format,...) noexcept
Definition: debug.cpp:218
void COND_PRINT_impl(const char *format,...) noexcept
Definition: debug.cpp:287
void WORDY_PRINT_impl(const char *format,...) noexcept
Definition: debug.cpp:188
void WARN_PRINT_impl(const char *func, const char *file, const int line, const char *format,...) noexcept
Definition: debug.cpp:238
void printSharedPtrList(const std::string &prefix, List &list) noexcept
Definition: debug.hpp:155