VirtualBox

source: vbox/trunk/include/iprt/log.h@ 11391

Last change on this file since 11391 was 11391, checked in by vboxsync, 17 years ago

Moved annoying log messages to either level4 or private logging. Added private logging macro LogAleksey.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 53.7 KB
Line 
1/** @file
2 * IPRT - Logging.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 *
25 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___iprt_log_h
31#define ___iprt_log_h
32
33#include <iprt/cdefs.h>
34#include <iprt/types.h>
35#include <iprt/stdarg.h>
36
37__BEGIN_DECLS
38
39/** @defgroup grp_rt_log RTLog - Logging
40 * @ingroup grp_rt
41 * @{
42 */
43
44/**
45 * IPRT Logging Groups.
46 * (Remember to update RT_LOGGROUP_NAMES!)
47 *
48 * @remark It should be pretty obvious, but just to have
49 * mentioned it, the values are sorted alphabetically (using the
50 * english alphabet) except for _DEFAULT which is always first.
51 *
52 * If anyone might be wondering what the alphabet looks like:
53 * a b c d e f g h i j k l m n o p q r s t u v w x y z
54 */
55typedef enum RTLOGGROUP
56{
57 /** Default logging group. */
58 RTLOGGROUP_DEFAULT,
59 RTLOGGROUP_DIR,
60 RTLOGGROUP_FILE,
61 RTLOGGROUP_FS,
62 RTLOGGROUP_LDR,
63 RTLOGGROUP_PATH,
64 RTLOGGROUP_PROCESS,
65 RTLOGGROUP_THREAD,
66 RTLOGGROUP_TIME,
67 RTLOGGROUP_TIMER,
68 RTLOGGROUP_ZIP = 31,
69 RTLOGGROUP_FIRST_USER = 32
70} RTLOGGROUP;
71
72/** @def RT_LOGGROUP_NAMES
73 * IPRT Logging group names.
74 *
75 * Must correspond 100% to RTLOGGROUP!
76 * Don't forget commas!
77 *
78 * @remark It should be pretty obvious, but just to have
79 * mentioned it, the values are sorted alphabetically (using the
80 * english alphabet) except for _DEFAULT which is always first.
81 *
82 * If anyone might be wondering what the alphabet looks like:
83 * a b c d e f g h i j k l m n o p q r s t u v w x y z
84 */
85#define RT_LOGGROUP_NAMES \
86 "DEFAULT", \
87 "RT_DIR", \
88 "RT_FILE", \
89 "RT_FS", \
90 "RT_LDR", \
91 "RT_PATH", \
92 "RT_PROCESS", \
93 "RT_THREAD", \
94 "RT_TIME", \
95 "RT_TIMER", \
96 "RT_10", \
97 "RT_11", \
98 "RT_12", \
99 "RT_13", \
100 "RT_14", \
101 "RT_15", \
102 "RT_16", \
103 "RT_17", \
104 "RT_18", \
105 "RT_19", \
106 "RT_20", \
107 "RT_21", \
108 "RT_22", \
109 "RT_23", \
110 "RT_24", \
111 "RT_25", \
112 "RT_26", \
113 "RT_27", \
114 "RT_28", \
115 "RT_29", \
116 "RT_30", \
117 "RT_ZIP" \
118
119
120/** @def LOG_GROUP
121 * Active logging group.
122 */
123#ifndef LOG_GROUP
124# define LOG_GROUP RTLOGGROUP_DEFAULT
125#endif
126
127/** @def LOG_INSTANCE
128 * Active logging instance.
129 */
130#ifndef LOG_INSTANCE
131# define LOG_INSTANCE NULL
132#endif
133
134/** @def LOG_REL_INSTANCE
135 * Active release logging instance.
136 */
137#ifndef LOG_REL_INSTANCE
138# define LOG_REL_INSTANCE NULL
139#endif
140
141/** @def LOG_FN_FMT
142 * You can use this to specify you desired way of printing __PRETTY_FUNCTION__
143 * if you dislike the default one.
144 */
145#ifndef LOG_FN_FMT
146# define LOG_FN_FMT "%Rfn"
147#endif
148
149/** Logger structure. */
150#ifdef IN_GC
151typedef struct RTLOGGERRC RTLOGGER;
152#else
153typedef struct RTLOGGER RTLOGGER;
154#endif
155/** Pointer to logger structure. */
156typedef RTLOGGER *PRTLOGGER;
157/** Pointer to const logger structure. */
158typedef const RTLOGGER *PCRTLOGGER;
159
160
161/** Guest context logger structure. */
162typedef struct RTLOGGERRC RTLOGGERRC;
163/** Pointer to guest context logger structure. */
164typedef RTLOGGERRC *PRTLOGGERRC;
165/** Pointer to const guest context logger structure. */
166typedef const RTLOGGERRC *PCRTLOGGERRC;
167
168
169/**
170 * Logger function.
171 *
172 * @param pszFormat Format string.
173 * @param ... Optional arguments as specified in the format string.
174 */
175typedef DECLCALLBACK(void) FNRTLOGGER(const char *pszFormat, ...);
176/** Pointer to logger function. */
177typedef FNRTLOGGER *PFNRTLOGGER;
178
179/**
180 * Flush function.
181 *
182 * @param pLogger Pointer to the logger instance which is to be flushed.
183 */
184typedef DECLCALLBACK(void) FNRTLOGFLUSH(PRTLOGGER pLogger);
185/** Pointer to logger function. */
186typedef FNRTLOGFLUSH *PFNRTLOGFLUSH;
187
188/**
189 * Flush function.
190 *
191 * @param pLogger Pointer to the logger instance which is to be flushed.
192 */
193typedef DECLCALLBACK(void) FNRTLOGFLUSHGC(PRTLOGGERRC pLogger);
194/** Pointer to logger function. */
195typedef RCPTRTYPE(FNRTLOGFLUSHGC *) PFNRTLOGFLUSHGC;
196
197
198/**
199 * Logger instance structure for GC.
200 */
201struct RTLOGGERRC
202{
203 /** Pointer to temporary scratch buffer.
204 * This is used to format the log messages. */
205 char achScratch[16384];
206 /** Current scratch buffer position. */
207 RTUINT offScratch;
208 /** This is set if a prefix is pending. */
209 RTUINT fPendingPrefix;
210 /** Pointer to the logger function.
211 * This is actually pointer to a wrapper which will push a pointer to the
212 * instance pointer onto the stack before jumping to the real logger function.
213 * A very unfortunate hack to work around the missing variadic macro support in C++. */
214 RCPTRTYPE(PFNRTLOGGER) pfnLogger;
215 /** Pointer to the flush function. */
216 PFNRTLOGFLUSHGC pfnFlush;
217 /** Magic number (RTLOGGERRC_MAGIC). */
218 uint32_t u32Magic;
219 /** Logger instance flags - RTLOGFLAGS. */
220 RTUINT fFlags;
221 /** Number of groups in the afGroups member. */
222 RTUINT cGroups;
223 /** Group flags array - RTLOGGRPFLAGS.
224 * This member have variable length and may extend way beyond
225 * the declared size of 1 entry. */
226 RTUINT afGroups[1];
227};
228
229/** RTLOGGERRC::u32Magic value. (John Rogers Searle) */
230#define RTLOGGERRC_MAGIC 0x19320731
231
232
233
234#ifndef IN_GC
235/**
236 * Logger instance structure.
237 */
238struct RTLOGGER
239{
240 /** Pointer to temporary scratch buffer.
241 * This is used to format the log messages. */
242 char achScratch[16384];
243 /** Current scratch buffer position. */
244 RTUINT offScratch;
245 /** This is set if a prefix is pending. */
246 RTUINT fPendingPrefix;
247 /** Pointer to the logger function.
248 * This is actually pointer to a wrapper which will push a pointer to the
249 * instance pointer onto the stack before jumping to the real logger function.
250 * A very unfortunate hack to work around the missing variadic macro support in C++.
251 * (The memory is (not R0) allocated using RTMemExecAlloc().) */
252 PFNRTLOGGER pfnLogger;
253 /** Pointer to the flush function. */
254 PFNRTLOGFLUSH pfnFlush;
255 /** Mutex. */
256 RTSEMFASTMUTEX MutexSem;
257 /** Magic number. */
258 uint32_t u32Magic;
259 /** Logger instance flags - RTLOGFLAGS. */
260 RTUINT fFlags;
261 /** Destination flags - RTLOGDEST. */
262 RTUINT fDestFlags;
263 /** Handle to log file (if open). */
264 RTFILE File;
265 /** Pointer to filename.
266 * (The memory is allocated in the smae block as RTLOGGER.) */
267 char *pszFilename;
268 /** Pointer to the group name array.
269 * (The data is readonly and provided by the user.) */
270 const char * const *papszGroups;
271 /** The max number of groups that there is room for in afGroups and papszGroups.
272 * Used by RTLogCopyGroupAndFlags(). */
273 RTUINT cMaxGroups;
274 /** Number of groups in the afGroups and papszGroups members. */
275 RTUINT cGroups;
276 /** Group flags array - RTLOGGRPFLAGS.
277 * This member have variable length and may extend way beyond
278 * the declared size of 1 entry. */
279 RTUINT afGroups[1];
280};
281
282/** RTLOGGER::u32Magic value. (Avram Noam Chomsky) */
283#define RTLOGGER_MAGIC 0x19281207
284
285#endif
286
287
288/**
289 * Logger flags.
290 */
291typedef enum RTLOGFLAGS
292{
293 /** The logger instance is disabled for normal output. */
294 RTLOGFLAGS_DISABLED = 0x00000001,
295 /** The logger instance is using buffered output. */
296 RTLOGFLAGS_BUFFERED = 0x00000002,
297 /** The logger instance expands LF to CR/LF. */
298 RTLOGFLAGS_USECRLF = 0x00000010,
299 /** Show relative timestamps with PREFIX_TSC and PREFIX_TS */
300 RTLOGFLAGS_REL_TS = 0x00000020,
301 /** Show decimal timestamps with PREFIX_TSC and PREFIX_TS */
302 RTLOGFLAGS_DECIMAL_TS = 0x00000040,
303 /** New lines should be prefixed with the write and read lock counts. */
304 RTLOGFLAGS_PREFIX_LOCK_COUNTS = 0x00008000,
305 /** New lines should be prefixed with the CPU id (ApicID on intel/amd). */
306 RTLOGFLAGS_PREFIX_CPUID = 0x00010000,
307 /** New lines should be prefixed with the native process id. */
308 RTLOGFLAGS_PREFIX_PID = 0x00020000,
309 /** New lines should be prefixed with group flag number causing the output. */
310 RTLOGFLAGS_PREFIX_FLAG_NO = 0x00040000,
311 /** New lines should be prefixed with group flag name causing the output. */
312 RTLOGFLAGS_PREFIX_FLAG = 0x00080000,
313 /** New lines should be prefixed with group number. */
314 RTLOGFLAGS_PREFIX_GROUP_NO = 0x00100000,
315 /** New lines should be prefixed with group name. */
316 RTLOGFLAGS_PREFIX_GROUP = 0x00200000,
317 /** New lines should be prefixed with the native thread id. */
318 RTLOGFLAGS_PREFIX_TID = 0x00400000,
319 /** New lines should be prefixed with thread name. */
320 RTLOGFLAGS_PREFIX_THREAD = 0x00800000,
321 /** New lines should be prefixed with formatted timestamp since program start. */
322 RTLOGFLAGS_PREFIX_TIME_PROG = 0x04000000,
323 /** New lines should be prefixed with formatted timestamp (UCT). */
324 RTLOGFLAGS_PREFIX_TIME = 0x08000000,
325 /** New lines should be prefixed with milliseconds since program start. */
326 RTLOGFLAGS_PREFIX_MS_PROG = 0x10000000,
327 /** New lines should be prefixed with timestamp. */
328 RTLOGFLAGS_PREFIX_TSC = 0x20000000,
329 /** New lines should be prefixed with timestamp. */
330 RTLOGFLAGS_PREFIX_TS = 0x40000000,
331 /** The prefix mask. */
332 RTLOGFLAGS_PREFIX_MASK = 0x7cff8000
333} RTLOGFLAGS;
334
335/**
336 * Logger per group flags.
337 */
338typedef enum RTLOGGRPFLAGS
339{
340 /** Enabled. */
341 RTLOGGRPFLAGS_ENABLED = 0x00000001,
342 /** Level 1 logging. */
343 RTLOGGRPFLAGS_LEVEL_1 = 0x00000002,
344 /** Level 2 logging. */
345 RTLOGGRPFLAGS_LEVEL_2 = 0x00000004,
346 /** Level 3 logging. */
347 RTLOGGRPFLAGS_LEVEL_3 = 0x00000008,
348 /** Level 4 logging. */
349 RTLOGGRPFLAGS_LEVEL_4 = 0x00000010,
350 /** Level 5 logging. */
351 RTLOGGRPFLAGS_LEVEL_5 = 0x00000020,
352 /** Level 6 logging. */
353 RTLOGGRPFLAGS_LEVEL_6 = 0x00000040,
354 /** Flow logging. */
355 RTLOGGRPFLAGS_FLOW = 0x00000080,
356
357 /** Lelik logging. */
358 RTLOGGRPFLAGS_LELIK = 0x00000100,
359 /** Michael logging. */
360 RTLOGGRPFLAGS_MICHAEL = 0x00000200,
361 /** dmik logging. */
362 RTLOGGRPFLAGS_DMIK = 0x00000400,
363 /** sunlover logging. */
364 RTLOGGRPFLAGS_SUNLOVER = 0x00000800,
365 /** Achim logging. */
366 RTLOGGRPFLAGS_ACHIM = 0x00001000,
367 /** Sander logging. */
368 RTLOGGRPFLAGS_SANDER = 0x00002000,
369 /** Klaus logging. */
370 RTLOGGRPFLAGS_KLAUS = 0x00004000,
371 /** Frank logging. */
372 RTLOGGRPFLAGS_FRANK = 0x00008000,
373 /** bird logging. */
374 RTLOGGRPFLAGS_BIRD = 0x00010000,
375 /** aleksey logging. */
376 RTLOGGRPFLAGS_ALEKSEY = 0x00020000,
377 /** NoName logging. */
378 RTLOGGRPFLAGS_NONAME = 0x00040000
379} RTLOGGRPFLAGS;
380
381/**
382 * Logger destination type.
383 */
384typedef enum RTLOGDEST
385{
386 /** Log to file. */
387 RTLOGDEST_FILE = 0x00000001,
388 /** Log to stdout. */
389 RTLOGDEST_STDOUT = 0x00000002,
390 /** Log to stderr. */
391 RTLOGDEST_STDERR = 0x00000004,
392 /** Log to debugger (win32 only). */
393 RTLOGDEST_DEBUGGER = 0x00000008,
394 /** Log to com port. */
395 RTLOGDEST_COM = 0x00000010,
396 /** Just a dummy flag to be used when no other flag applies. */
397 RTLOGDEST_DUMMY = 0x20000000,
398 /** Log to a user defined output stream. */
399 RTLOGDEST_USER = 0x40000000
400} RTLOGDEST;
401
402
403RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
404
405
406/*
407 * Determin whether logging is enabled and forcefully normalize the indicators.
408 */
409#if (defined(DEBUG) || defined(LOG_ENABLED)) && !defined(LOG_DISABLED)
410# undef LOG_DISABLED
411# undef LOG_ENABLED
412# define LOG_ENABLED
413#else
414# undef LOG_ENABLED
415# undef LOG_DISABLED
416# define LOG_DISABLED
417#endif
418
419
420/** @def LOG_USE_C99
421 * Governs the use of variadic macros.
422 */
423#ifndef LOG_USE_C99
424# if defined(RT_ARCH_AMD64)
425# define LOG_USE_C99
426# endif
427#endif
428
429
430/** @def LogIt
431 * Write to specific logger if group enabled.
432 */
433#ifdef LOG_ENABLED
434# if defined(LOG_USE_C99)
435# define _LogRemoveParentheseis(...) __VA_ARGS__
436# define _LogIt(pvInst, fFlags, iGroup, ...) RTLogLoggerEx((PRTLOGGER)pvInst, fFlags, iGroup, __VA_ARGS__)
437# define LogIt(pvInst, fFlags, iGroup, fmtargs) _LogIt(pvInst, fFlags, iGroup, _LogRemoveParentheseis fmtargs)
438# define _LogItAlways(pvInst, fFlags, iGroup, ...) RTLogLoggerEx((PRTLOGGER)pvInst, fFlags, ~0U, __VA_ARGS__)
439# define LogItAlways(pvInst, fFlags, iGroup, fmtargs) _LogItAlways(pvInst, fFlags, iGroup, _LogRemoveParentheseis fmtargs)
440 /** @todo invent a flag or something for skipping the group check so we can pass iGroup. LogItAlways. */
441# else
442# define LogIt(pvInst, fFlags, iGroup, fmtargs) \
443 do \
444 { \
445 register PRTLOGGER LogIt_pLogger = (PRTLOGGER)(pvInst) ? (PRTLOGGER)(pvInst) : RTLogDefaultInstance(); \
446 if (LogIt_pLogger) \
447 { \
448 register unsigned LogIt_fFlags = LogIt_pLogger->afGroups[(unsigned)(iGroup) < LogIt_pLogger->cGroups ? (unsigned)(iGroup) : 0]; \
449 if ((LogIt_fFlags & ((fFlags) | RTLOGGRPFLAGS_ENABLED)) == ((fFlags) | RTLOGGRPFLAGS_ENABLED)) \
450 LogIt_pLogger->pfnLogger fmtargs; \
451 } \
452 } while (0)
453# define LogItAlways(pvInst, fFlags, iGroup, fmtargs) \
454 do \
455 { \
456 register PRTLOGGER LogIt_pLogger = (PRTLOGGER)(pvInst) ? (PRTLOGGER)(pvInst) : RTLogDefaultInstance(); \
457 if (LogIt_pLogger) \
458 LogIt_pLogger->pfnLogger fmtargs; \
459 } while (0)
460# endif
461#else
462# define LogIt(pvInst, fFlags, iGroup, fmtargs) do { } while (0)
463# define LogItAlways(pvInst, fFlags, iGroup, fmtargs) do { } while (0)
464# if defined(LOG_USE_C99)
465# define _LogRemoveParentheseis(...) __VA_ARGS__
466# define _LogIt(pvInst, fFlags, iGroup, ...) do { } while (0)
467# define _LogItAlways(pvInst, fFlags, iGroup, ...) do { } while (0)
468# endif
469#endif
470
471
472/** @def Log
473 * Level 1 logging that works regardless of the group settings.
474 */
475#define LogAlways(a) LogItAlways(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
476
477/** @def Log
478 * Level 1 logging.
479 */
480#define Log(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
481
482/** @def Log2
483 * Level 2 logging.
484 */
485#define Log2(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
486
487/** @def Log3
488 * Level 3 logging.
489 */
490#define Log3(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
491
492/** @def Log4
493 * Level 4 logging.
494 */
495#define Log4(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
496
497/** @def Log5
498 * Level 5 logging.
499 */
500#define Log5(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
501
502/** @def Log6
503 * Level 6 logging.
504 */
505#define Log6(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
506
507/** @def LogFlow
508 * Logging of execution flow.
509 */
510#define LogFlow(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
511
512/** @def LogLelik
513 * lelik logging.
514 */
515#define LogLelik(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LELIK, LOG_GROUP, a)
516
517
518/** @def LogMichael
519 * michael logging.
520 */
521#define LogMichael(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_MICHAEL, LOG_GROUP, a)
522
523/** @def LogDmik
524 * dmik logging.
525 */
526#define LogDmik(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_DMIK, LOG_GROUP, a)
527
528/** @def LogSunlover
529 * sunlover logging.
530 */
531#define LogSunlover(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_SUNLOVER, LOG_GROUP, a)
532
533/** @def LogAchim
534 * Achim logging.
535 */
536#define LogAchim(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_ACHIM, LOG_GROUP, a)
537
538/** @def LogSander
539 * Sander logging.
540 */
541#define LogSander(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_SANDER, LOG_GROUP, a)
542
543/** @def LogKlaus
544 * klaus logging.
545 */
546#define LogKlaus(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_KLAUS, LOG_GROUP, a)
547
548/** @def LogFrank
549 * frank logging.
550 */
551#define LogFrank(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FRANK, LOG_GROUP, a)
552
553/** @def LogBird
554 * bird logging.
555 */
556#define LogBird(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_BIRD, LOG_GROUP, a)
557
558/** @def LogAleksey
559 * aleksey logging.
560 */
561#define LogAleksey(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_ALEKSEY, LOG_GROUP, a)
562
563/** @def LogNoName
564 * NoName logging.
565 */
566#define LogNoName(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_NONAME, LOG_GROUP, a)
567
568
569/** @def LogWarning
570 * The same as Log(), but prepents a <tt>"WARNING! "</tt> string to the message.
571 *
572 * @param a Custom log message in format <tt>("string\n" [, args])</tt>.
573 */
574#if defined(LOG_USE_C99)
575# define LogWarning(a) \
576 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "WARNING! %M", _LogRemoveParentheseis a )
577#else
578# define LogWarning(a) \
579 do { Log(("WARNING! ")); Log(a); } while (0)
580#endif
581
582/** @def LogTrace
583 * Macro to trace the execution flow: logs the file name, line number and
584 * function name. Can be easily searched for in log files using the
585 * ">>>>>" pattern (prepended to the beginning of each line).
586 */
587#define LogTrace() \
588 LogFlow((">>>>> %s (%d): " LOG_FN_FMT "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__))
589
590/** @def LogTraceMsg
591 * The same as LogTrace but logs a custom log message right after the trace line.
592 *
593 * @param a Custom log message in format <tt>("string\n" [, args])</tt>.
594 */
595#ifdef LOG_USE_C99
596# define LogTraceMsg(a) \
597 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, ">>>>> %s (%d): %M" LOG_FN_FMT, __FILE__, __LINE__, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
598#else
599# define LogTraceMsg(a) \
600 do { LogFlow((">>>>> %s (%d): " LOG_FN_FMT, __FILE__, __LINE__, __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
601#endif
602
603/** @def LogFunc
604 * Level 1 logging inside C/C++ functions.
605 *
606 * Prepends the given log message with the function name followed by a
607 * semicolon and space.
608 *
609 * @param a Log message in format <tt>("string\n" [, args])</tt>.
610 */
611#ifdef LOG_USE_C99
612# define LogFunc(a) \
613 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
614#else
615# define LogFunc(a) \
616 do { Log((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); Log(a); } while (0)
617#endif
618
619/** @def LogThisFunc
620 * The same as LogFunc but for class functions (methods): the resulting log
621 * line is additionally prepended with a hex value of |this| pointer.
622 *
623 * @param a Log message in format <tt>("string\n" [, args])</tt>.
624 */
625#ifdef LOG_USE_C99
626# define LogThisFunc(a) \
627 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
628#else
629# define LogThisFunc(a) \
630 do { Log(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log(a); } while (0)
631#endif
632
633/** @def LogFlowFunc
634 * Macro to log the execution flow inside C/C++ functions.
635 *
636 * Prepends the given log message with the function name followed by
637 * a semicolon and space.
638 *
639 * @param a Log message in format <tt>("string\n" [, args])</tt>.
640 */
641#ifdef LOG_USE_C99
642# define LogFlowFunc(a) \
643 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
644#else
645# define LogFlowFunc(a) \
646 do { LogFlow((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
647#endif
648
649/** @def LogWarningFunc
650 * The same as LogWarning(), but prepents the log message with the function name.
651 *
652 * @param a Log message in format <tt>("string\n" [, args])</tt>.
653 */
654#ifdef LOG_USE_C99
655# define LogWarningFunc(a) \
656 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": WARNING! %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
657#else
658# define LogWarningFunc(a) \
659 do { Log((LOG_FN_FMT ": WARNING! ", __PRETTY_FUNCTION__)); Log(a); } while (0)
660#endif
661
662/** @def LogFlowThisFunc
663 * The same as LogFlowFunc but for class functions (methods): the resulting log
664 * line is additionally prepended with a hex value of |this| pointer.
665 *
666 * @param a Log message in format <tt>("string\n" [, args])</tt>.
667 */
668#ifdef LOG_USE_C99
669# define LogFlowThisFunc(a) \
670 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
671#else
672# define LogFlowThisFunc(a) \
673 do { LogFlow(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
674#endif
675
676/** @def LogWarningThisFunc
677 * The same as LogWarningFunc() but for class functions (methods): the resulting
678 * log line is additionally prepended with a hex value of |this| pointer.
679 *
680 * @param a Log message in format <tt>("string\n" [, args])</tt>.
681 */
682#ifdef LOG_USE_C99
683# define LogWarningThisFunc(a) \
684 _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": WARNING! %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
685#else
686# define LogWarningThisFunc(a) \
687 do { Log(("{%p} " LOG_FN_FMT ": WARNING! ", this, __PRETTY_FUNCTION__)); Log(a); } while (0)
688#endif
689
690/** Shortcut to |LogFlowFunc ("ENTER\n")|, marks the beginnig of the function. */
691#define LogFlowFuncEnter() LogFlowFunc(("ENTER\n"))
692
693/** Shortcut to |LogFlowFunc ("LEAVE\n")|, marks the end of the function. */
694#define LogFlowFuncLeave() LogFlowFunc(("LEAVE\n"))
695
696/** Shortcut to |LogFlowThisFunc ("ENTER\n")|, marks the beginnig of the function. */
697#define LogFlowThisFuncEnter() LogFlowThisFunc(("ENTER\n"))
698
699/** Shortcut to |LogFlowThisFunc ("LEAVE\n")|, marks the end of the function. */
700#define LogFlowThisFuncLeave() LogFlowThisFunc(("LEAVE\n"))
701
702/** @def LogObjRefCnt
703 * Helper macro to print the current reference count of the given COM object
704 * to the log file.
705 *
706 * @param pObj Pointer to the object in question (must be a pointer to an
707 * IUnknown subclass or simply define COM-style AddRef() and
708 * Release() methods)
709 *
710 * @note Use it only for temporary debugging. It leaves dummy code even if
711 * logging is disabled.
712 */
713#define LogObjRefCnt(pObj) \
714 do { \
715 int refc = (pObj)->AddRef(); \
716 LogFlow((#pObj "{%p}.refCnt=%d\n", (pObj), refc - 1)); \
717 (pObj)->Release(); \
718 } while (0)
719
720
721/** @def LogIsItEnabled
722 * Checks whether the specified logging group is enabled or not.
723 */
724#ifdef LOG_ENABLED
725# define LogIsItEnabled(pvInst, fFlags, iGroup) \
726 LogIsItEnabledInternal((pvInst), (unsigned)(iGroup), (unsigned)(fFlags))
727#else
728# define LogIsItEnabled(pvInst, fFlags, iGroup) (false)
729#endif
730
731/** @def LogIsEnabled
732 * Checks whether level 1 logging is enabled.
733 */
734#define LogIsEnabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
735
736/** @def LogIs2Enabled
737 * Checks whether level 2 logging is enabled.
738 */
739#define LogIs2Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
740
741/** @def LogIs3Enabled
742 * Checks whether level 3 logging is enabled.
743 */
744#define LogIs3Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
745
746/** @def LogIs4Enabled
747 * Checks whether level 4 logging is enabled.
748 */
749#define LogIs4Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
750
751/** @def LogIs5Enabled
752 * Checks whether level 5 logging is enabled.
753 */
754#define LogIs5Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
755
756/** @def LogIs6Enabled
757 * Checks whether level 6 logging is enabled.
758 */
759#define LogIs6Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
760
761/** @def LogIsFlowEnabled
762 * Checks whether execution flow logging is enabled.
763 */
764#define LogIsFlowEnabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP)
765
766
767#ifdef DOXYGEN_RUNNING
768# define LOG_DISABLED
769# define LOG_ENABLED
770# define LOG_ENABLE_FLOW
771#endif
772
773/** @def LOG_DISABLED
774 * Use this compile time define to disable all logging macros. It can
775 * be overriden for each of the logging macros by the LOG_ENABLE*
776 * compile time defines.
777 */
778
779/** @def LOG_ENABLED
780 * Use this compile time define to enable logging when not in debug mode
781 * or LOG_DISABLED is set.
782 * This will enabled Log() only.
783 */
784
785/** @def LOG_ENABLE_FLOW
786 * Use this compile time define to enable flow logging when not in
787 * debug mode or LOG_DISABLED is defined.
788 * This will enable LogFlow() only.
789 */
790
791
792
793/** @name Release Logging
794 * @{
795 */
796
797/** @def LogIt
798 * Write to specific logger if group enabled.
799 */
800#if defined(LOG_USE_C99)
801# define _LogRelRemoveParentheseis(...) __VA_ARGS__
802# define _LogRelIt(pvInst, fFlags, iGroup, ...) RTLogLoggerEx((PRTLOGGER)pvInst, fFlags, iGroup, __VA_ARGS__)
803# define LogRelIt(pvInst, fFlags, iGroup, fmtargs) \
804 do \
805 { \
806 PRTLOGGER LogRelIt_pLogger = (PRTLOGGER)(pvInst) ? (PRTLOGGER)(pvInst) : RTLogRelDefaultInstance(); \
807 if (LogRelIt_pLogger) \
808 _LogRelIt(LogRelIt_pLogger, fFlags, iGroup, _LogRelRemoveParentheseis fmtargs); \
809 LogIt(LOG_INSTANCE, fFlags, iGroup, fmtargs); \
810 } while (0)
811#else
812# define LogRelIt(pvInst, fFlags, iGroup, fmtargs) \
813 do \
814 { \
815 PRTLOGGER LogRelIt_pLogger = (PRTLOGGER)(pvInst) ? (PRTLOGGER)(pvInst) : RTLogRelDefaultInstance(); \
816 if (LogRelIt_pLogger) \
817 { \
818 unsigned LogIt_fFlags = LogRelIt_pLogger->afGroups[(unsigned)(iGroup) < LogRelIt_pLogger->cGroups ? (unsigned)(iGroup) : 0]; \
819 if ((LogIt_fFlags & ((fFlags) | RTLOGGRPFLAGS_ENABLED)) == ((fFlags) | RTLOGGRPFLAGS_ENABLED)) \
820 LogRelIt_pLogger->pfnLogger fmtargs; \
821 } \
822 LogIt(LOG_INSTANCE, fFlags, iGroup, fmtargs); \
823 } while (0)
824#endif
825
826
827/** @def LogRel
828 * Level 1 logging.
829 */
830#define LogRel(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
831
832/** @def LogRel2
833 * Level 2 logging.
834 */
835#define LogRel2(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
836
837/** @def LogRel3
838 * Level 3 logging.
839 */
840#define LogRel3(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
841
842/** @def LogRel4
843 * Level 4 logging.
844 */
845#define LogRel4(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
846
847/** @def LogRel5
848 * Level 5 logging.
849 */
850#define LogRel5(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
851
852/** @def LogRel6
853 * Level 6 logging.
854 */
855#define LogRel6(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
856
857/** @def LogRelFlow
858 * Logging of execution flow.
859 */
860#define LogRelFlow(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
861
862/** @def LogRelFunc
863 * Release logging. Prepends the given log message with the function name
864 * followed by a semicolon and space.
865 */
866#define LogRelFunc(a) \
867 do { LogRel((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRel(a); } while (0)
868
869/** @def LogRelThisFunc
870 * The same as LogRelFunc but for class functions (methods): the resulting log
871 * line is additionally prepended with a hex value of |this| pointer.
872 */
873#define LogRelThisFunc(a) \
874 do { LogRel(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogRel(a); } while (0)
875
876/** @def LogRelLelik
877 * lelik logging.
878 */
879#define LogRelLelik(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LELIK, LOG_GROUP, a)
880
881/** @def LogRelMichael
882 * michael logging.
883 */
884#define LogRelMichael(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_MICHAEL, LOG_GROUP, a)
885
886/** @def LogRelDmik
887 * dmik logging.
888 */
889#define LogRelDmik(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_DMIK, LOG_GROUP, a)
890
891/** @def LogRelSunlover
892 * sunlover logging.
893 */
894#define LogRelSunlover(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_SUNLOVER, LOG_GROUP, a)
895
896/** @def LogRelAchim
897 * Achim logging.
898 */
899#define LogRelAchim(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_ACHIM, LOG_GROUP, a)
900
901/** @def LogRelSander
902 * Sander logging.
903 */
904#define LogRelSander(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_SANDER, LOG_GROUP, a)
905
906/** @def LogRelKlaus
907 * klaus logging.
908 */
909#define LogRelKlaus(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_KLAUS, LOG_GROUP, a)
910
911/** @def LogRelFrank
912 * frank logging.
913 */
914#define LogRelFrank(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_FRANK, LOG_GROUP, a)
915
916/** @def LogRelBird
917 * bird logging.
918 */
919#define LogRelBird(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_BIRD, LOG_GROUP, a)
920
921/** @def LogRelNoName
922 * NoName logging.
923 */
924#define LogRelNoName(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_NONAME, LOG_GROUP, a)
925
926
927/** @def LogRelIsItEnabled
928 * Checks whether the specified logging group is enabled or not.
929 */
930#define LogRelIsItEnabled(pvInst, fFlags, iGroup) \
931 LogRelIsItEnabledInternal((pvInst), (unsigned)(iGroup), (unsigned)(fFlags))
932
933/** @def LogRelIsEnabled
934 * Checks whether level 1 logging is enabled.
935 */
936#define LogRelIsEnabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
937
938/** @def LogRelIs2Enabled
939 * Checks whether level 2 logging is enabled.
940 */
941#define LogRelIs2Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
942
943/** @def LogRelIs3Enabled
944 * Checks whether level 3 logging is enabled.
945 */
946#define LogRelIs3Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
947
948/** @def LogRelIs4Enabled
949 * Checks whether level 4 logging is enabled.
950 */
951#define LogRelIs4Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
952
953/** @def LogRelIs5Enabled
954 * Checks whether level 5 logging is enabled.
955 */
956#define LogRelIs5Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
957
958/** @def LogRelIs6Enabled
959 * Checks whether level 6 logging is enabled.
960 */
961#define LogRelIs6Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
962
963/** @def LogRelIsFlowEnabled
964 * Checks whether execution flow logging is enabled.
965 */
966#define LogRelIsFlowEnabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP)
967
968
969#ifndef IN_GC
970/**
971 * Sets the default release logger instance.
972 *
973 * @returns The old default instance.
974 * @param pLogger The new default release logger instance.
975 */
976RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger);
977#endif /* !IN_GC */
978
979/**
980 * Gets the default release logger instance.
981 *
982 * @returns Pointer to default release logger instance.
983 * @returns NULL if no default release logger instance available.
984 */
985RTDECL(PRTLOGGER) RTLogRelDefaultInstance(void);
986
987/** Internal worker function.
988 * Don't call directly, use the LogRelIsItEnabled macro!
989 */
990DECLINLINE(bool) LogRelIsItEnabledInternal(void *pvInst, unsigned iGroup, unsigned fFlags)
991{
992 register PRTLOGGER pLogger = (PRTLOGGER)pvInst ? (PRTLOGGER)pvInst : RTLogRelDefaultInstance();
993 if (pLogger)
994 {
995 register unsigned fGrpFlags = pLogger->afGroups[(unsigned)iGroup < pLogger->cGroups ? (unsigned)iGroup : 0];
996 if ((fGrpFlags & (fFlags | RTLOGGRPFLAGS_ENABLED)) == (fFlags | RTLOGGRPFLAGS_ENABLED))
997 return true;
998 }
999 return false;
1000}
1001
1002/**
1003 * Write to a logger instance, defaulting to the release one.
1004 *
1005 * This function will check whether the instance, group and flags makes up a
1006 * logging kind which is currently enabled before writing anything to the log.
1007 *
1008 * @param pLogger Pointer to logger instance.
1009 * @param fFlags The logging flags.
1010 * @param iGroup The group.
1011 * The value ~0U is reserved for compatability with RTLogLogger[V] and is
1012 * only for internal usage!
1013 * @param pszFormat Format string.
1014 * @param ... Format arguments.
1015 * @remark This is a worker function for LogRelIt.
1016 */
1017RTDECL(void) RTLogRelLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
1018
1019/**
1020 * Write to a logger instance, defaulting to the release one.
1021 *
1022 * This function will check whether the instance, group and flags makes up a
1023 * logging kind which is currently enabled before writing anything to the log.
1024 *
1025 * @param pLogger Pointer to logger instance. If NULL the default release instance is attempted.
1026 * @param fFlags The logging flags.
1027 * @param iGroup The group.
1028 * The value ~0U is reserved for compatability with RTLogLogger[V] and is
1029 * only for internal usage!
1030 * @param pszFormat Format string.
1031 * @param args Format arguments.
1032 */
1033RTDECL(void) RTLogRelLoggerV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
1034
1035/**
1036 * printf like function for writing to the default release log.
1037 *
1038 * @param pszFormat Printf like format string.
1039 * @param ... Optional arguments as specified in pszFormat.
1040 *
1041 * @remark The API doesn't support formatting of floating point numbers at the moment.
1042 */
1043RTDECL(void) RTLogRelPrintf(const char *pszFormat, ...);
1044
1045/**
1046 * vprintf like function for writing to the default release log.
1047 *
1048 * @param pszFormat Printf like format string.
1049 * @param args Optional arguments as specified in pszFormat.
1050 *
1051 * @remark The API doesn't support formatting of floating point numbers at the moment.
1052 */
1053RTDECL(void) RTLogRelPrintfV(const char *pszFormat, va_list args);
1054
1055
1056/** @} */
1057
1058
1059
1060/** @name COM port logging
1061 * {
1062 */
1063
1064#ifdef DOXYGEN_RUNNING
1065# define LOG_TO_COM
1066# define LOG_NO_COM
1067#endif
1068
1069/** @def LOG_TO_COM
1070 * Redirects the normal loging macros to the serial versions.
1071 */
1072
1073/** @def LOG_NO_COM
1074 * Disables all LogCom* macros.
1075 */
1076
1077/** @def LogCom
1078 * Generic logging to serial port.
1079 */
1080#if defined(LOG_ENABLED) && !defined(LOG_NO_COM)
1081# define LogCom(a) RTLogComPrintf a
1082#else
1083# define LogCom(a) do { } while (0)
1084#endif
1085
1086/** @def LogComFlow
1087 * Logging to serial port of execution flow.
1088 */
1089#if defined(LOG_ENABLED) && defined(LOG_ENABLE_FLOW) && !defined(LOG_NO_COM)
1090# define LogComFlow(a) RTLogComPrintf a
1091#else
1092# define LogComFlow(a) do { } while (0)
1093#endif
1094
1095#ifdef LOG_TO_COM
1096# undef Log
1097# define Log(a) LogCom(a)
1098# undef LogFlow
1099# define LogFlow(a) LogComFlow(a)
1100#endif
1101
1102/** @} */
1103
1104
1105/** @name Backdoor Logging
1106 * @{
1107 */
1108
1109#ifdef DOXYGEN_RUNNING
1110# define LOG_TO_BACKDOOR
1111# define LOG_NO_BACKDOOR
1112#endif
1113
1114/** @def LOG_TO_BACKDOOR
1115 * Redirects the normal logging macros to the backdoor versions.
1116 */
1117
1118/** @def LOG_NO_BACKDOOR
1119 * Disables all LogBackdoor* macros.
1120 */
1121
1122/** @def LogBackdoor
1123 * Generic logging to the VBox backdoor via port I/O.
1124 */
1125#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
1126# define LogBackdoor(a) RTLogBackdoorPrintf a
1127#else
1128# define LogBackdoor(a) do { } while (0)
1129#endif
1130
1131/** @def LogBackdoorFlow
1132 * Logging of execution flow messages to the backdoor I/O port.
1133 */
1134#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
1135# define LogBackdoorFlow(a) RTLogBackdoorPrintf a
1136#else
1137# define LogBackdoorFlow(a) do { } while (0)
1138#endif
1139
1140/** @def LogRelBackdoor
1141 * Release logging to the VBox backdoor via port I/O.
1142 */
1143#if !defined(LOG_NO_BACKDOOR)
1144# define LogRelBackdoor(a) RTLogBackdoorPrintf a
1145#else
1146# define LogRelBackdoor(a) do { } while (0)
1147#endif
1148
1149#ifdef LOG_TO_BACKDOOR
1150# undef Log
1151# define Log(a) LogBackdoor(a)
1152# undef LogFlow
1153# define LogFlow(a) LogBackdoorFlow(a)
1154# undef LogRel
1155# define LogRel(a) LogRelBackdoor(a)
1156#endif
1157
1158/** @} */
1159
1160
1161
1162/**
1163 * Gets the default logger instance.
1164 *
1165 * @returns Pointer to default logger instance.
1166 * @returns NULL if no default logger instance available.
1167 */
1168RTDECL(PRTLOGGER) RTLogDefaultInstance(void);
1169
1170#ifndef IN_GC
1171/**
1172 * Sets the default logger instance.
1173 *
1174 * @returns The old default instance.
1175 * @param pLogger The new default logger instance.
1176 */
1177RTDECL(PRTLOGGER) RTLogSetDefaultInstance(PRTLOGGER pLogger);
1178#endif /* !IN_GC */
1179
1180#ifdef IN_RING0
1181/**
1182 * Changes the default logger instance for the current thread.
1183 *
1184 * @returns IPRT status code.
1185 * @param pLogger The logger instance. Pass NULL for deregistration.
1186 * @param uKey Associated key for cleanup purposes. If pLogger is NULL,
1187 * all instances with this key will be deregistered. So in
1188 * order to only deregister the instance associated with the
1189 * current thread use 0.
1190 */
1191RTDECL(int) RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey);
1192#endif /* IN_RING0 */
1193
1194
1195#ifdef LOG_ENABLED
1196/** Internal worker function.
1197 * Don't call directly, use the LogIsItEnabled macro!
1198 */
1199DECLINLINE(bool) LogIsItEnabledInternal(void *pvInst, unsigned iGroup, unsigned fFlags)
1200{
1201 register PRTLOGGER pLogger = (PRTLOGGER)pvInst ? (PRTLOGGER)pvInst : RTLogDefaultInstance();
1202 if (pLogger)
1203 {
1204 register unsigned fGrpFlags = pLogger->afGroups[(unsigned)iGroup < pLogger->cGroups ? (unsigned)iGroup : 0];
1205 if ((fGrpFlags & (fFlags | RTLOGGRPFLAGS_ENABLED)) == (fFlags | RTLOGGRPFLAGS_ENABLED))
1206 return true;
1207 }
1208 return false;
1209}
1210#endif
1211
1212
1213#ifndef IN_GC
1214/**
1215 * Creates the default logger instance for a iprt users.
1216 *
1217 * Any user of the logging features will need to implement
1218 * this or use the generic dummy.
1219 *
1220 * @returns Pointer to the logger instance.
1221 */
1222RTDECL(PRTLOGGER) RTLogDefaultInit(void);
1223
1224/**
1225 * Create a logger instance.
1226 *
1227 * @returns iprt status code.
1228 *
1229 * @param ppLogger Where to store the logger instance.
1230 * @param fFlags Logger instance flags, a combination of the RTLOGFLAGS_* values.
1231 * @param pszGroupSettings The initial group settings.
1232 * @param pszEnvVarBase Base name for the environment variables for this instance.
1233 * @param cGroups Number of groups in the array.
1234 * @param papszGroups Pointer to array of groups. This must stick around for the life of the
1235 * logger instance.
1236 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed if pszFilenameFmt specified.
1237 * @param pszFilenameFmt Log filename format string. Standard RTStrFormat().
1238 * @param ... Format arguments.
1239 */
1240RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, RTUINT fFlags, const char *pszGroupSettings,
1241 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
1242 RTUINT fDestFlags, const char *pszFilenameFmt, ...);
1243
1244/**
1245 * Create a logger instance.
1246 *
1247 * @returns iprt status code.
1248 *
1249 * @param ppLogger Where to store the logger instance.
1250 * @param fFlags Logger instance flags, a combination of the RTLOGFLAGS_* values.
1251 * @param pszGroupSettings The initial group settings.
1252 * @param pszEnvVarBase Base name for the environment variables for this instance.
1253 * @param cGroups Number of groups in the array.
1254 * @param papszGroups Pointer to array of groups. This must stick around for the life of the
1255 * logger instance.
1256 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed if pszFilenameFmt specified.
1257 * @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL.
1258 * @param cchErrorMsg The size of the error message buffer.
1259 * @param pszFilenameFmt Log filename format string. Standard RTStrFormat().
1260 * @param ... Format arguments.
1261 */
1262RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, RTUINT fFlags, const char *pszGroupSettings,
1263 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
1264 RTUINT fDestFlags, char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, ...);
1265
1266/**
1267 * Create a logger instance.
1268 *
1269 * @returns iprt status code.
1270 *
1271 * @param ppLogger Where to store the logger instance.
1272 * @param fFlags Logger instance flags, a combination of the RTLOGFLAGS_* values.
1273 * @param pszGroupSettings The initial group settings.
1274 * @param pszEnvVarBase Base name for the environment variables for this instance.
1275 * @param cGroups Number of groups in the array.
1276 * @param papszGroups Pointer to array of groups. This must stick around for the life of the
1277 * logger instance.
1278 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed if pszFilenameFmt specified.
1279 * @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL.
1280 * @param cchErrorMsg The size of the error message buffer.
1281 * @param pszFilenameFmt Log filename format string. Standard RTStrFormat().
1282 * @param args Format arguments.
1283 */
1284RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, RTUINT fFlags, const char *pszGroupSettings,
1285 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
1286 RTUINT fDestFlags, char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args);
1287
1288/**
1289 * Create a logger instance for singled threaded ring-0 usage.
1290 *
1291 * @returns iprt status code.
1292 *
1293 * @param pLogger Where to create the logger instance.
1294 * @param cbLogger The amount of memory available for the logger instance.
1295 * @param pfnLogger Pointer to logger wrapper function for the clone.
1296 * @param pfnFlush Pointer to flush function for the clone.
1297 * @param fFlags Logger instance flags for the clone, a combination of the RTLOGFLAGS_* values.
1298 * @param fDestFlags The destination flags.
1299 */
1300RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger, PFNRTLOGGER pfnLogger, PFNRTLOGFLUSH pfnFlush, RTUINT fFlags, RTUINT fDestFlags);
1301
1302/**
1303 * Destroys a logger instance.
1304 *
1305 * The instance is flushed and all output destinations closed (where applicable).
1306 *
1307 * @returns iprt status code.
1308 * @param pLogger The logger instance which close destroyed. NULL is fine.
1309 */
1310RTDECL(int) RTLogDestroy(PRTLOGGER pLogger);
1311
1312/**
1313 * Create a logger instance clone for RC usage.
1314 *
1315 * @returns iprt status code.
1316 *
1317 * @param pLogger The logger instance to be cloned.
1318 * @param pLoggerGC Where to create the GC logger instance.
1319 * @param cbLoggerGC Amount of memory allocated to for the GC logger instance clone.
1320 * @param pfnLoggerGCPtr Pointer to logger wrapper function for this instance (GC Ptr).
1321 * @param pfnFlushGCPtr Pointer to flush function (GC Ptr).
1322 * @param fFlags Logger instance flags, a combination of the RTLOGFLAGS_* values.
1323 */
1324RTDECL(int) RTLogCloneRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerGC, size_t cbLoggerGC,
1325 RTRCPTR pfnLoggerGCPtr, RTRCPTR pfnFlushGCPtr, RTUINT fFlags);
1326
1327/**
1328 * Flushes a GC logger instance to a HC logger.
1329 *
1330 * @returns iprt status code.
1331 * @param pLogger The HC logger instance to flush pLoggerGC to.
1332 * If NULL the default logger is used.
1333 * @param pLoggerGC The GC logger instance to flush.
1334 */
1335RTDECL(void) RTLogFlushGC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerGC);
1336
1337/**
1338 * Flushes the buffer in one logger instance onto another logger.
1339 *
1340 * @returns iprt status code.
1341 *
1342 * @param pSrcLogger The logger instance to flush.
1343 * @param pDstLogger The logger instance to flush onto.
1344 * If NULL the default logger will be used.
1345 */
1346RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger);
1347
1348/**
1349 * Copies the group settings and flags from logger instance to another.
1350 *
1351 * @returns IPRT status code.
1352 * @param pDstLogger The destination logger instance.
1353 * @param pSrcLogger The source logger instance. If NULL the default one is used.
1354 * @param fFlagsOr OR mask for the flags.
1355 * @param fFlagsAnd AND mask for the flags.
1356 */
1357RTDECL(int) RTLogCopyGroupsAndFlags(PRTLOGGER pDstLogger, PCRTLOGGER pSrcLogger, unsigned fFlagsOr, unsigned fFlagsAnd);
1358
1359/**
1360 * Updates the group settings for the logger instance using the specified
1361 * specification string.
1362 *
1363 * @returns iprt status code.
1364 * Failures can safely be ignored.
1365 * @param pLogger Logger instance (NULL for default logger).
1366 * @param pszVar Value to parse.
1367 */
1368RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszVar);
1369#endif /* !IN_GC */
1370
1371/**
1372 * Updates the flags for the logger instance using the specified
1373 * specification string.
1374 *
1375 * @returns iprt status code.
1376 * Failures can safely be ignored.
1377 * @param pLogger Logger instance (NULL for default logger).
1378 * @param pszVar Value to parse.
1379 */
1380RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszVar);
1381
1382/**
1383 * Flushes the specified logger.
1384 *
1385 * @param pLogger The logger instance to flush.
1386 * If NULL the default instance is used. The default instance
1387 * will not be initialized by this call.
1388 */
1389RTDECL(void) RTLogFlush(PRTLOGGER pLogger);
1390
1391/**
1392 * Write to a logger instance.
1393 *
1394 * @param pLogger Pointer to logger instance.
1395 * @param pvCallerRet Ignored.
1396 * @param pszFormat Format string.
1397 * @param ... Format arguments.
1398 */
1399RTDECL(void) RTLogLogger(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...);
1400
1401/**
1402 * Write to a logger instance.
1403 *
1404 * @param pLogger Pointer to logger instance.
1405 * @param pszFormat Format string.
1406 * @param args Format arguments.
1407 */
1408RTDECL(void) RTLogLoggerV(PRTLOGGER pLogger, const char *pszFormat, va_list args);
1409
1410/**
1411 * Write to a logger instance.
1412 *
1413 * This function will check whether the instance, group and flags makes up a
1414 * logging kind which is currently enabled before writing anything to the log.
1415 *
1416 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
1417 * @param fFlags The logging flags.
1418 * @param iGroup The group.
1419 * The value ~0U is reserved for compatability with RTLogLogger[V] and is
1420 * only for internal usage!
1421 * @param pszFormat Format string.
1422 * @param ... Format arguments.
1423 * @remark This is a worker function of LogIt.
1424 */
1425RTDECL(void) RTLogLoggerEx(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
1426
1427/**
1428 * Write to a logger instance.
1429 *
1430 * This function will check whether the instance, group and flags makes up a
1431 * logging kind which is currently enabled before writing anything to the log.
1432 *
1433 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
1434 * @param fFlags The logging flags.
1435 * @param iGroup The group.
1436 * The value ~0U is reserved for compatability with RTLogLogger[V] and is
1437 * only for internal usage!
1438 * @param pszFormat Format string.
1439 * @param args Format arguments.
1440 */
1441RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
1442
1443/**
1444 * printf like function for writing to the default log.
1445 *
1446 * @param pszFormat Printf like format string.
1447 * @param ... Optional arguments as specified in pszFormat.
1448 *
1449 * @remark The API doesn't support formatting of floating point numbers at the moment.
1450 */
1451RTDECL(void) RTLogPrintf(const char *pszFormat, ...);
1452
1453/**
1454 * vprintf like function for writing to the default log.
1455 *
1456 * @param pszFormat Printf like format string.
1457 * @param args Optional arguments as specified in pszFormat.
1458 *
1459 * @remark The API doesn't support formatting of floating point numbers at the moment.
1460 */
1461RTDECL(void) RTLogPrintfV(const char *pszFormat, va_list args);
1462
1463
1464#ifndef DECLARED_FNRTSTROUTPUT /* duplicated in iprt/string.h */
1465#define DECLARED_FNRTSTROUTPUT
1466/**
1467 * Output callback.
1468 *
1469 * @returns number of bytes written.
1470 * @param pvArg User argument.
1471 * @param pachChars Pointer to an array of utf-8 characters.
1472 * @param cbChars Number of bytes in the character array pointed to by pachChars.
1473 */
1474typedef DECLCALLBACK(size_t) FNRTSTROUTPUT(void *pvArg, const char *pachChars, size_t cbChars);
1475/** Pointer to callback function. */
1476typedef FNRTSTROUTPUT *PFNRTSTROUTPUT;
1477#endif
1478
1479/**
1480 * Partial vsprintf worker implementation.
1481 *
1482 * @returns number of bytes formatted.
1483 * @param pfnOutput Output worker.
1484 * Called in two ways. Normally with a string an it's length.
1485 * For termination, it's called with NULL for string, 0 for length.
1486 * @param pvArg Argument to output worker.
1487 * @param pszFormat Format string.
1488 * @param args Argument list.
1489 */
1490RTDECL(size_t) RTLogFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArg, const char *pszFormat, va_list args);
1491
1492/**
1493 * Write log buffer to COM port.
1494 *
1495 * @param pach Pointer to the buffer to write.
1496 * @param cb Number of bytes to write.
1497 */
1498RTDECL(void) RTLogWriteCom(const char *pach, size_t cb);
1499
1500/**
1501 * Prints a formatted string to the serial port used for logging.
1502 *
1503 * @returns Number of bytes written.
1504 * @param pszFormat Format string.
1505 * @param ... Optional arguments specified in the format string.
1506 */
1507RTDECL(size_t) RTLogComPrintf(const char *pszFormat, ...);
1508
1509/**
1510 * Prints a formatted string to the serial port used for logging.
1511 *
1512 * @returns Number of bytes written.
1513 * @param pszFormat Format string.
1514 * @param args Optional arguments specified in the format string.
1515 */
1516RTDECL(size_t) RTLogComPrintfV(const char *pszFormat, va_list args);
1517
1518
1519#if 0 /* not implemented yet */
1520
1521/** Indicates that the semaphores shall be used to notify the other
1522 * part about buffer changes. */
1523#define LOGHOOKBUFFER_FLAGS_SEMAPHORED 1
1524
1525/**
1526 * Log Hook Buffer.
1527 * Use to commuicate between the logger and a log consumer.
1528 */
1529typedef struct RTLOGHOOKBUFFER
1530{
1531 /** Write pointer. */
1532 volatile void *pvWrite;
1533 /** Read pointer. */
1534 volatile void *pvRead;
1535 /** Buffer start. */
1536 void *pvStart;
1537 /** Buffer end (exclusive). */
1538 void *pvEnd;
1539 /** Signaling semaphore used by the writer to wait on a full buffer.
1540 * Only used when indicated in flags. */
1541 void *pvSemWriter;
1542 /** Signaling semaphore used by the read to wait on an empty buffer.
1543 * Only used when indicated in flags. */
1544 void *pvSemReader;
1545 /** Buffer flags. Current reserved and set to zero. */
1546 volatile unsigned fFlags;
1547} RTLOGHOOKBUFFER;
1548/** Pointer to a log hook buffer. */
1549typedef RTLOGHOOKBUFFER *PRTLOGHOOKBUFFER;
1550
1551
1552/**
1553 * Register a logging hook.
1554 *
1555 * This type of logging hooks are expecting different threads acting
1556 * producer and consumer. They share a circular buffer which have two
1557 * pointers one for each end. When the buffer is full there are two
1558 * alternatives (indicated by a buffer flag), either wait for the
1559 * consumer to get it's job done, or to write a generic message saying
1560 * buffer overflow.
1561 *
1562 * Since the waiting would need a signal semaphore, we'll skip that for now.
1563 *
1564 * @returns iprt status code.
1565 * @param pBuffer Pointer to a logger hook buffer.
1566 */
1567RTDECL(int) RTLogRegisterHook(PRTLOGGER pLogger, PRTLOGHOOKBUFFER pBuffer);
1568
1569/**
1570 * Deregister a logging hook registerd with RTLogRegisterHook().
1571 *
1572 * @returns iprt status code.
1573 * @param pBuffer Pointer to a logger hook buffer.
1574 */
1575RTDECL(int) RTLogDeregisterHook(PRTLOGGER pLogger, PRTLOGHOOKBUFFER pBuffer);
1576
1577#endif /* not implemented yet */
1578
1579
1580
1581/**
1582 * Write log buffer to a debugger (RTLOGDEST_DEBUGGER).
1583 *
1584 * @param pach What to write.
1585 * @param cb How much to write.
1586 * @remark When linking statically, this function can be replaced by defining your own.
1587 */
1588RTDECL(void) RTLogWriteDebugger(const char *pach, size_t cb);
1589
1590/**
1591 * Write log buffer to a user defined output stream (RTLOGDEST_USER).
1592 *
1593 * @param pach What to write.
1594 * @param cb How much to write.
1595 * @remark When linking statically, this function can be replaced by defining your own.
1596 */
1597RTDECL(void) RTLogWriteUser(const char *pach, size_t cb);
1598
1599/**
1600 * Write log buffer to stdout (RTLOGDEST_STDOUT).
1601 *
1602 * @param pach What to write.
1603 * @param cb How much to write.
1604 * @remark When linking statically, this function can be replaced by defining your own.
1605 */
1606RTDECL(void) RTLogWriteStdOut(const char *pach, size_t cb);
1607
1608/**
1609 * Write log buffer to stdout (RTLOGDEST_STDERR).
1610 *
1611 * @param pach What to write.
1612 * @param cb How much to write.
1613 * @remark When linking statically, this function can be replaced by defining your own.
1614 */
1615RTDECL(void) RTLogWriteStdErr(const char *pach, size_t cb);
1616
1617#ifdef VBOX
1618
1619/**
1620 * Prints a formatted string to the backdoor port.
1621 *
1622 * @returns Number of bytes written.
1623 * @param pszFormat Format string.
1624 * @param ... Optional arguments specified in the format string.
1625 */
1626RTDECL(size_t) RTLogBackdoorPrintf(const char *pszFormat, ...);
1627
1628/**
1629 * Prints a formatted string to the backdoor port.
1630 *
1631 * @returns Number of bytes written.
1632 * @param pszFormat Format string.
1633 * @param args Optional arguments specified in the format string.
1634 */
1635RTDECL(size_t) RTLogBackdoorPrintfV(const char *pszFormat, va_list args);
1636
1637#endif /* VBOX */
1638
1639__END_DECLS
1640
1641/** @} */
1642
1643#endif
1644
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette