jaulib v1.4.0-2-g788cf73
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
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 <cstdlib>
30
31#include <cstdint>
32#include <cstring>
33#include <string>
34#include <cstdio>
35#include <cstdarg>
36
37#include <jau/cpp_lang_util.hpp>
38#include <jau/environment.hpp>
39#include <jau/backtrace.hpp>
40
41#include <jau/string_util.hpp>
42
43// #define PERF_PRINT_ON 1
44
45namespace jau {
46
47 namespace impl {
48 void dbgPrint1(const char * format, ...) noexcept;
49 void dbgPrint2(const char *s) noexcept;
50
51 /** Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line func: '. Function also appends last errno and strerror(errno). */
52 void abortImpl(const char *func, const char *file, const int line, const char * format, ...) noexcept;
53
54 void errPrint(const char *prefix, const bool backtrace, const char *func, const char *file, const int line, const char * format, ...) noexcept;
55 void warnPrint(const char *func, const char *file, const int line, const char * format, ...) noexcept;
56 void wordyPrint(const char * format, ...) noexcept;
57 }
58
59 /** Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line func: '. Function also appends last errno and strerror(errno). */
60 #define ABORT(...) { jau::impl::abortImpl(__func__, __FILE__, __LINE__, __VA_ARGS__); }
61
62 /** Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] Debug: '. */
63 template <typename... Args>
64 void dbgPrint(std::string_view format, const Args &...args) {
65 const jau::cfmt::PResult pr = jau::cfmt::checkR2<Args...>(format);
66 if ( pr.argCount() < 0 ) {
67 throw jau::IllegalArgumentError("format/arg mismatch `"+std::string(format)+"`: "+pr.toString(), E_FILE_LINE);
68 }
69 impl::dbgPrint2(impl::format_string_h(1023, format, args...).c_str());
70 }
71 /** Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] Debug: '. */
72 #define DBG_PRINT(...) { if( jau::environment::get().debug ) { jau::impl::dbgPrint1(__VA_ARGS__); } }
73
74 /** Use for environment-variable environment::DEBUG conditional warning messages, prefix '[elapsed_time] Warning @ FILE:LINE FUNC: ' */
75 #define DBG_WARN_PRINT(...) { if( jau::environment::get().debug ) { jau::impl::warnPrint(__func__, __FILE__, __LINE__, __VA_ARGS__); } }
76
77 /** Use for environment-variable environment::DEBUG conditional error messages, prefix '[elapsed_time] Warning @ FILE:LINE FUNC: '. Function also appends last errno, strerror(errno) and full backtrace*/
78 #define DBG_ERR_PRINT(...) { if( jau::environment::get().debug ) { jau::impl::errPrint("Debug", true /* backtrace */, __func__, __FILE__, __LINE__, __VA_ARGS__); } }
79
80 /** Use for environment-variable environment::DEBUG_JNI conditional debug messages, prefix '[elapsed_time] Debug: '. */
81 #define DBG_JNI_PRINT(...) { if( jau::environment::get().debug_jni ) { jau::impl::dbgPrint1(__VA_ARGS__); } }
82
83 /**
84 * Use for environment-variable environment::VERBOSE conditional verbose messages, prefix '[elapsed_time] Wordy: '.
85 * <p>
86 * 'Wordy' is the shorter English form of the Latin word 'verbosus', from which the word 'verbosity' is sourced.
87 * </p>
88 */
89 #define WORDY_PRINT(...) { if( jau::environment::get().verbose ) { jau::impl::wordyPrint(__VA_ARGS__); } }
90
91
92 #define PERF_TS_T0_BASE() const uint64_t _t0 = jau::getCurrentMilliseconds()
93
94 #define PERF_TS_TD_BASE(m) { const uint64_t _td = jau::getCurrentMilliseconds() - _t0; \
95 fprintf(stderr, "[%s] PERF %s done in %d ms,\n", jau::to_decstring(jau::environment::getElapsedMillisecond(), ',', 9).c_str(), (m), (int)_td); }
96 #ifdef PERF_PRINT_ON
97 #define PERF_TS_T0() PERF_TS_T0_BASE()
98 #define PERF_TS_TD(m) PERF_TS_TD_BASE(m)
99 #else
100 #define PERF_TS_T0()
101 #define PERF_TS_TD(m)
102 #endif
103 #ifdef PERF2_PRINT_ON
104 #define PERF2_TS_T0() PERF_TS_T0_BASE()
105 #define PERF2_TS_TD(m) PERF_TS_TD_BASE(m)
106 #else
107 #define PERF2_TS_T0()
108 #define PERF2_TS_TD(m)
109 #endif
110 #ifdef PERF3_PRINT_ON
111 #define PERF3_TS_T0() PERF_TS_T0_BASE()
112 #define PERF3_TS_TD(m) PERF_TS_TD_BASE(m)
113 #else
114 #define PERF3_TS_T0()
115 #define PERF3_TS_TD(m)
116 #endif
117
118 /** Use for unconditional error messages, prefix '[elapsed_time] Error @ file:line func: '. Function also appends last errno and strerror(errno). */
119 void ERR_PRINTv(const char *func, const char *file, const int line, const char * format, va_list args) noexcept;
120
121 /** Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '. Function also appends last errno, strerror(errno) and full backtrace*/
122 #define ERR_PRINT(...) { jau::impl::errPrint("Error", true /* backtrace */, __func__, __FILE__, __LINE__, __VA_ARGS__); }
123
124 /** Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '. Function also appends last errno and strerror(errno). No backtrace. */
125 #define ERR_PRINT2(...) { jau::impl::errPrint("Error", false /* backtrace */, __func__, __FILE__, __LINE__, __VA_ARGS__); }
126
127 /** Use for unconditional interruption messages, prefix '[elapsed_time] Interrupted @ FILE:LINE FUNC: '. Function also appends last errno and strerror(errno). */
128 #define IRQ_PRINT(...) { jau::impl::errPrint("Interrupted", false /* backtrace */, __func__, __FILE__, __LINE__, __VA_ARGS__); }
129
130 /** Use for unconditional warning messages, prefix '[elapsed_time] Warning @ file:line func: ' */
131 void WARN_PRINTv(const char *func, const char *file, const int line, const char * format, va_list args) noexcept;
132
133 /** Use for unconditional warning messages, prefix '[elapsed_time] Warning @ FILE:LINE FUNC: ' */
134 #define WARN_PRINT(...) { jau::impl::warnPrint(__func__, __FILE__, __LINE__, __VA_ARGS__); }
135
136 /** Use for unconditional informal messages, prefix '[elapsed_time] Info: '. */
137 void INFO_PRINT(const char * format, ...) noexcept;
138
139 /** Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true. */
140 void PLAIN_PRINT(const bool printPrefix, const char * format, ...) noexcept;
141
142 /**
143 * Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
144 * @param elapsed_ms the given elapsed time in milliseconds
145 * @param stream the output stream
146 * @param format the format
147 * @param args the optional arguments
148 */
149 int fprintf_td(const uint64_t elapsed_ms, FILE* stream, const char * format, ...) noexcept;
150
151 /**
152 * Convenient fprintf() invocation, prepending the environment::getElapsedMillisecond() timestamp.
153 * @param stream the output stream
154 * @param format the format
155 * @param args the optional arguments
156 */
157 int fprintf_td(FILE* stream, const char * format, ...) noexcept;
158
159 void COND_PRINT_impl(const char * format, ...) noexcept;
160
161 /** Use for conditional plain messages, prefix '[elapsed_time] '. */
162 #define COND_PRINT(C, ...) { if( C ) { jau::COND_PRINT_impl(__VA_ARGS__); } }
163
164
165 template<class List>
166 void printSharedPtrList(const std::string& prefix, List & list) noexcept {
167 fprintf(stderr, "%s: Start: %zu elements\n", prefix.c_str(), (size_t)list.size());
168 int idx = 0;
169 for (auto it = list.begin(); it != list.end(); idx++) {
170 typename List::value_type & e = *it;
171 if ( nullptr != e ) {
172 fprintf(stderr, "%s[%d]: useCount %zu, mem %p\n", prefix.c_str(), idx, (size_t)e.use_count(), e.get());
173 } else {
174 fprintf(stderr, "%s[%d]: NULL\n", prefix.c_str(), idx);
175 }
176 ++it;
177 }
178 }
179
180} // namespace jau
181
182#endif /* JAU_DEBUG_HPP_ */
#define E_FILE_LINE
constexpr PResult checkR2(const std::string_view fmt) noexcept
Strict type validation of arguments against the format string.
void abortImpl(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:204
void wordyPrint(const char *format,...) noexcept
Definition debug.cpp:194
void dbgPrint1(const char *format,...) noexcept
Definition debug.cpp:184
void dbgPrint2(const char *s) noexcept
Definition debug.cpp:178
void errPrint(const char *prefix, const bool backtrace, const char *func, const char *file, const int line, const char *format,...) noexcept
Definition debug.cpp:224
constexpr std::string format_string_h(const std::size_t strLenHint, const std::string_view format, const Args &...args)
void warnPrint(const char *func, const char *file, const int line, const char *format,...) noexcept
Definition debug.cpp:244
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
Definition debug.cpp:264
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:216
void INFO_PRINT(const char *format,...) noexcept
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.
Definition debug.cpp:254
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:276
void dbgPrint(std::string_view format, const Args &...args)
Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] De...
Definition debug.hpp:64
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:237
void COND_PRINT_impl(const char *format,...) noexcept
Definition debug.cpp:293
void printSharedPtrList(const std::string &prefix, List &list) noexcept
Definition debug.hpp:166
constexpr ssize_t argCount() const noexcept
std::string toString() const