VirtualBox

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

Last change on this file since 529 was 529, checked in by vboxsync, 18 years ago

Fixed bug in LogRelIt in C99/AMD64 mode.

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