]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/Debug.h
2 * Copyright (C) 1996-2017 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 // XXX should be mem/forward.h once it removes dependencies on typedefs.h
15 #include "mem/AllocatorProxy.h"
26 #define assert(EX) ((void)0)
27 #elif defined(NODEBUG)
28 #define assert(EX) ((void)0)
30 #define assert(EX) ((EX)?((void)0):xassert( # EX , __FILE__, __LINE__))
32 #define assert(EX) ((EX)?((void)0):xassert("EX", __FILE__, __LINE__))
35 /* context-based debugging, the actual type is subject to change */
37 Ctx
ctx_enter(const char *descr
);
38 void ctx_exit(Ctx ctx
);
40 /* defined debug section limits */
41 #define MAX_DEBUG_SECTIONS 100
43 /* defined names for Debug Levels */
44 #define DBG_CRITICAL 0 /**< critical messages always shown when they occur */
45 #define DBG_IMPORTANT 1 /**< important messages always shown when their section is being checked */
46 /* levels 2-8 are still being discussed amongst the developers */
47 #define DBG_DATA 9 /**< output is a large data dump only necessary for advanced debugging */
49 #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. */
55 /// meta-information for debugs() or a similar debugging call
59 Context(const int aSectionLevel
, const int aLevel
);
61 int level
; ///< minimum debugging level required by the debugs() call
62 int sectionLevel
; ///< maximum debugging level allowed during the call
66 void rewind(const int aSection
, const int aLevel
);
68 Context
*upper
; ///< previous or parent record in nested debugging calls
69 std::ostringstream buf
; ///< debugs() output sink
72 /// whether debugging the given section and the given level produces output
73 static bool Enabled(const int section
, const int level
)
75 return level
<= Debug::Levels
[section
];
78 static char *debugOptions
;
79 static char *cache_log
;
80 static int rotateNumber
;
81 static int Levels
[MAX_DEBUG_SECTIONS
];
82 static int override_X
;
83 static int log_stderr
;
84 static bool log_syslog
;
86 static void parseOptions(char const *);
88 /// minimum level required by the current debugs() call
89 static int Level() { return Current
? Current
->level
: 1; }
90 /// maximum level currently allowed
91 static int SectionLevel() { return Current
? Current
->sectionLevel
: 1; }
93 /// opens debugging context and returns output buffer
94 static std::ostringstream
&Start(const int section
, const int level
);
95 /// logs output buffer created in Start() and closes debugging context
99 static Context
*Current
; ///< deepest active context; nil outside debugs()
102 extern FILE *debug_log
;
104 size_t BuildPrefixInit();
105 const char * SkipBuildPrefix(const char* path
);
109 * Unit tests can enable full debugging to stderr for one
110 * debug section; to enable this, #define ENABLE_DEBUG_SECTION to the
111 * section number before any header
113 #define debugs(SECTION, LEVEL, CONTENT) \
115 const int _dbg_level = (LEVEL); \
116 if (Debug::Enabled((SECTION), _dbg_level)) { \
117 std::ostream &_dbo = Debug::Start((SECTION), _dbg_level); \
118 if (_dbg_level > DBG_IMPORTANT) { \
119 _dbo << (SECTION) << ',' << _dbg_level << "| " \
120 << SkipBuildPrefix(__FILE__)<<"("<<__LINE__<<") "<<__FUNCTION__<<": "; \
125 } while (/*CONSTCOND*/ 0)
127 /** stream manipulator which does nothing.
128 * \deprecated Do not add to new code, and remove when editing old code
130 * Its purpose is to inactivate calls made following previous debugs()
132 * debugs(1,2, HERE << "some message");
134 * His former objective is now absorbed in the debugs call itself
137 HERE(std::ostream
& s
)
143 * MYNAME is for use at debug levels 0 and 1 where HERE is too messy.
145 * debugs(1,1, MYNAME << "WARNING: some message");
147 #ifdef __PRETTY_FUNCTION__
148 #define MYNAME __PRETTY_FUNCTION__ << " "
150 #define MYNAME __FUNCTION__ << " "
153 /* some uint8_t do not like streaming control-chars (values 0-31, 127+) */
154 inline std::ostream
& operator <<(std::ostream
&os
, const uint8_t d
)
156 return (os
<< (int)d
);
159 /* Legacy debug function definitions */
160 void _db_init(const char *logfile
, const char *options
);
161 void _db_print(const char *,...) PRINTF_FORMAT_ARG1
;
162 void _db_set_syslog(const char *facility
);
163 void _db_rotate_log(void);
165 /// Prints raw and/or non-terminated data safely, efficiently, and beautifully.
166 /// Allows raw data debugging in debugs() statements with low debugging levels
167 /// by printing only if higher section debugging levels are configured:
168 /// debugs(11, DBG_IMPORTANT, "always printed" << Raw(may be printed...));
172 Raw(const char *label
, const char *data
, const size_t size
):
173 level(-1), label_(label
), data_(data
), size_(size
), useHex_(false) {}
175 /// limit data printing to at least the given debugging level
176 Raw
&minLevel(const int aLevel
) { level
= aLevel
; return *this; }
178 /// print data using two hex digits per byte (decoder: xxd -r -p)
179 Raw
&hex() { useHex_
= true; return *this; }
181 /// If debugging is prohibited by the current debugs() or section level,
182 /// prints nothing. Otherwise, dumps data using one of these formats:
183 /// " label[size]=data" if label was set and data size is positive
184 /// " label[0]" if label was set and data size is zero
185 /// " data" if label was not set and data size is positive
186 /// "" (i.e., prints nothing) if label was not set and data size is zero
187 std::ostream
&print(std::ostream
&os
) const;
189 /// Minimum section debugging level necessary for printing. By default,
190 /// small strings are always printed while large strings are only printed
191 /// if DBG_DATA debugging level is enabled.
195 void printHex(std::ostream
&os
) const;
197 const char *label_
; ///< optional data name or ID; triggers size printing
198 const char *data_
; ///< raw data to be printed
199 size_t size_
; ///< data length
200 bool useHex_
; ///< whether hex() has been called
204 std::ostream
&operator <<(std::ostream
&os
, const Raw
&raw
)
206 return raw
.print(os
);
209 /// debugs objects pointed by possibly nil pointers: label=object
210 template <class Pointer
>
213 RawPointerT(const char *aLabel
, const Pointer
&aPtr
):
214 label(aLabel
), ptr(aPtr
) {}
215 const char *label
; /// the name or description of the being-debugged object
216 const Pointer
&ptr
; /// a possibly nil pointer to the being-debugged object
219 /// convenience wrapper for creating RawPointerT<> objects
220 template <class Pointer
>
221 inline RawPointerT
<Pointer
>
222 RawPointer(const char *label
, const Pointer
&ptr
)
224 return RawPointerT
<Pointer
>(label
, ptr
);
227 /// prints RawPointerT<>, dereferencing the raw pointer if possible
228 template <class Pointer
>
229 inline std::ostream
&
230 operator <<(std::ostream
&os
, const RawPointerT
<Pointer
> &pd
)
232 os
<< pd
.label
<< '=';
234 return os
<< *pd
.ptr
;
236 return os
<< "[nil]";
239 #endif /* SQUID_DEBUG_H */