]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/Debug.h
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 00 Debug Routines */
14 #include "base/Here.h"
15 // XXX should be mem/forward.h once it removes dependencies on typedefs.h
16 #include "mem/AllocatorProxy.h"
27 #define assert(EX) ((void)0)
28 #elif defined(NODEBUG)
29 #define assert(EX) ((void)0)
31 #define assert(EX) ((EX)?((void)0):xassert( # EX , __FILE__, __LINE__))
33 #define assert(EX) ((EX)?((void)0):xassert("EX", __FILE__, __LINE__))
36 /* context-based debugging, the actual type is subject to change */
38 Ctx
ctx_enter(const char *descr
);
39 void ctx_exit(Ctx ctx
);
41 /* defined debug section limits */
42 #define MAX_DEBUG_SECTIONS 100
44 /* defined names for Debug Levels */
45 #define DBG_CRITICAL 0 /**< critical messages always shown when they occur */
46 #define DBG_IMPORTANT 1 /**< important messages always shown when their section is being checked */
47 /* levels 2-8 are still being discussed amongst the developers */
48 #define DBG_DATA 9 /**< output is a large data dump only necessary for advanced debugging */
50 #define DBG_PARSE_NOTE(x) (opt_parse_cfg_only?0:(x)) /**< output is always to be displayed on '-k parse' but at level-x normally. */
56 /// meta-information for debugs() or a similar debugging call
60 Context(const int aSectionLevel
, const int aLevel
);
62 int level
; ///< minimum debugging level required by the debugs() call
63 int sectionLevel
; ///< maximum debugging level allowed during the call
67 void rewind(const int aSection
, const int aLevel
);
69 Context
*upper
; ///< previous or parent record in nested debugging calls
70 std::ostringstream buf
; ///< debugs() output sink
71 bool forceAlert
; ///< the current debugs() will be a syslog ALERT
74 /// whether debugging the given section and the given level produces output
75 static bool Enabled(const int section
, const int level
)
77 return level
<= Debug::Levels
[section
];
80 static char *debugOptions
;
81 static char *cache_log
;
82 static int rotateNumber
;
83 static int Levels
[MAX_DEBUG_SECTIONS
];
84 static int override_X
;
85 static int log_stderr
;
86 static bool log_syslog
;
88 static void parseOptions(char const *);
90 /// minimum level required by the current debugs() call
91 static int Level() { return Current
? Current
->level
: 1; }
92 /// maximum level currently allowed
93 static int SectionLevel() { return Current
? Current
->sectionLevel
: 1; }
95 /// opens debugging context and returns output buffer
96 static std::ostringstream
&Start(const int section
, const int level
);
97 /// logs output buffer created in Start() and closes debugging context
100 /// configures the active debugging context to write syslog ALERT
101 static void ForceAlert();
103 /// prefixes each grouped debugs() line after the first one in the group
104 static std::ostream
& Extra(std::ostream
&os
) { return os
<< "\n "; }
107 static Context
*Current
; ///< deepest active context; nil outside debugs()
110 /// cache.log FILE or, as the last resort, stderr stream;
111 /// may be nil during static initialization and destruction!
113 /// change-avoidance macro; new code should call DebugStream() instead
114 #define debug_log DebugStream()
116 /// start logging to stderr (instead of cache.log, if any)
117 void StopUsingDebugLog();
119 /// a hack for low-level file descriptor manipulations in ipcCreate()
120 void ResyncDebugLog(FILE *newDestination
);
124 * Unit tests can enable full debugging to stderr for one
125 * debug section; to enable this, #define ENABLE_DEBUG_SECTION to the
126 * section number before any header
128 #define debugs(SECTION, LEVEL, CONTENT) \
130 const int _dbg_level = (LEVEL); \
131 if (Debug::Enabled((SECTION), _dbg_level)) { \
132 std::ostream &_dbo = Debug::Start((SECTION), _dbg_level); \
133 if (_dbg_level > DBG_IMPORTANT) { \
134 _dbo << (SECTION) << ',' << _dbg_level << "| " \
140 } while (/*CONSTCOND*/ 0)
142 /// Does not change the stream being manipulated. Exists for its side effect:
143 /// In a debugs() context, forces the message to become a syslog ALERT.
144 /// Outside of debugs() context, has no effect and should not be used.
145 std::ostream
& ForceAlert(std::ostream
& s
);
147 /** stream manipulator which does nothing.
148 * \deprecated Do not add to new code, and remove when editing old code
150 * Its purpose is to inactivate calls made following previous debugs()
152 * debugs(1,2, HERE << "some message");
154 * His former objective is now absorbed in the debugs call itself
157 HERE(std::ostream
& s
)
163 * MYNAME is for use at debug levels 0 and 1 where HERE is too messy.
165 * debugs(1,1, MYNAME << "WARNING: some message");
167 #ifdef __PRETTY_FUNCTION__
168 #define MYNAME __PRETTY_FUNCTION__ << " "
170 #define MYNAME __FUNCTION__ << " "
173 /* some uint8_t do not like streaming control-chars (values 0-31, 127+) */
174 inline std::ostream
& operator <<(std::ostream
&os
, const uint8_t d
)
176 return (os
<< (int)d
);
179 /* Legacy debug function definitions */
180 void _db_init(const char *logfile
, const char *options
);
181 void _db_set_syslog(const char *facility
);
182 void _db_rotate_log(void);
184 /// Prints raw and/or non-terminated data safely, efficiently, and beautifully.
185 /// Allows raw data debugging in debugs() statements with low debugging levels
186 /// by printing only if higher section debugging levels are configured:
187 /// debugs(11, DBG_IMPORTANT, "always printed" << Raw(may be printed...));
191 Raw(const char *label
, const char *data
, const size_t size
):
192 level(-1), label_(label
), data_(data
), size_(size
), useHex_(false), useGap_(true) {}
194 /// limit data printing to at least the given debugging level
195 Raw
&minLevel(const int aLevel
) { level
= aLevel
; return *this; }
197 /// print data using two hex digits per byte (decoder: xxd -r -p)
198 Raw
&hex() { useHex_
= true; return *this; }
200 Raw
&gap(bool useGap
= true) { useGap_
= useGap
; return *this; }
202 /// If debugging is prohibited by the current debugs() or section level,
203 /// prints nothing. Otherwise, dumps data using one of these formats:
204 /// " label[size]=data" if label was set and data size is positive
205 /// " label[0]" if label was set and data size is zero
206 /// " data" if label was not set and data size is positive
207 /// "" (i.e., prints nothing) if label was not set and data size is zero
208 std::ostream
&print(std::ostream
&os
) const;
210 /// Minimum section debugging level necessary for printing. By default,
211 /// small strings are always printed while large strings are only printed
212 /// if DBG_DATA debugging level is enabled.
216 void printHex(std::ostream
&os
) const;
218 const char *label_
; ///< optional data name or ID; triggers size printing
219 const char *data_
; ///< raw data to be printed
220 size_t size_
; ///< data length
221 bool useHex_
; ///< whether hex() has been called
222 bool useGap_
; ///< whether to print leading space if label is missing
226 std::ostream
&operator <<(std::ostream
&os
, const Raw
&raw
)
228 return raw
.print(os
);
231 /// debugs objects pointed by possibly nil pointers: label=object
232 template <class Pointer
>
235 RawPointerT(const char *aLabel
, const Pointer
&aPtr
):
236 label(aLabel
), ptr(aPtr
) {}
237 const char *label
; /// the name or description of the being-debugged object
238 const Pointer
&ptr
; /// a possibly nil pointer to the being-debugged object
241 /// convenience wrapper for creating RawPointerT<> objects
242 template <class Pointer
>
243 inline RawPointerT
<Pointer
>
244 RawPointer(const char *label
, const Pointer
&ptr
)
246 return RawPointerT
<Pointer
>(label
, ptr
);
249 /// prints RawPointerT<>, dereferencing the raw pointer if possible
250 template <class Pointer
>
251 inline std::ostream
&
252 operator <<(std::ostream
&os
, const RawPointerT
<Pointer
> &pd
)
254 os
<< pd
.label
<< '=';
256 return os
<< *pd
.ptr
;
258 return os
<< "[nil]";
261 /// std::ostream manipulator to print integers as hex numbers prefixed by 0x
262 template <class Integer
>
266 explicit AsHex(const Integer n
): raw(n
) {}
267 Integer raw
; ///< the integer to print
270 template <class Integer
>
271 inline std::ostream
&
272 operator <<(std::ostream
&os
, const AsHex
<Integer
> number
)
274 const auto oldFlags
= os
.flags();
275 os
<< std::hex
<< std::showbase
<< number
.raw
;
280 /// a helper to ease AsHex object creation
281 template <class Integer
>
282 inline AsHex
<Integer
> asHex(const Integer n
) { return AsHex
<Integer
>(n
); }
284 #endif /* SQUID_DEBUG_H */