VirtualBox

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

Last change on this file was 104286, checked in by vboxsync, 3 months ago

IPRT/log,Main: Open the parent directory of the log file on Windows before we opening the log file and do any log rotating to prevent reparse hacks. bugref:10632

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 104.1 KB
Line 
1/** @file
2 * IPRT - Logging.
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_log_h
37#define IPRT_INCLUDED_log_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/cdefs.h>
43#include <iprt/types.h>
44#include <iprt/stdarg.h>
45
46RT_C_DECLS_BEGIN
47
48/** @defgroup grp_rt_log RTLog - Logging
49 * @ingroup grp_rt
50 * @{
51 */
52
53/**
54 * IPRT Logging Groups.
55 * (Remember to update RT_LOGGROUP_NAMES!)
56 *
57 * @remark It should be pretty obvious, but just to have
58 * mentioned it, the values are sorted alphabetically (using the
59 * english alphabet) except for _DEFAULT which is always first.
60 *
61 * If anyone might be wondering what the alphabet looks like:
62 * 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
63 */
64typedef enum RTLOGGROUP
65{
66 /** Default logging group. */
67 RTLOGGROUP_DEFAULT,
68 RTLOGGROUP_CRYPTO,
69 RTLOGGROUP_DBG,
70 RTLOGGROUP_DBG_DWARF,
71 RTLOGGROUP_DIR,
72 RTLOGGROUP_FDT,
73 RTLOGGROUP_FILE,
74 RTLOGGROUP_FS,
75 RTLOGGROUP_FTP,
76 RTLOGGROUP_HTTP,
77 RTLOGGROUP_IOQUEUE,
78 RTLOGGROUP_LDR,
79 RTLOGGROUP_LOCALIPC,
80 RTLOGGROUP_PATH,
81 RTLOGGROUP_PROCESS,
82 RTLOGGROUP_REST,
83 RTLOGGROUP_SYMLINK,
84 RTLOGGROUP_THREAD,
85 RTLOGGROUP_TIME,
86 RTLOGGROUP_TIMER,
87 RTLOGGROUP_VFS,
88 RTLOGGROUP_ZIP = 31,
89 RTLOGGROUP_FIRST_USER = 32
90} RTLOGGROUP;
91
92/** @def RT_LOGGROUP_NAMES
93 * IPRT Logging group names.
94 *
95 * Must correspond 100% to RTLOGGROUP!
96 * Don't forget commas!
97 *
98 * @remark It should be pretty obvious, but just to have
99 * mentioned it, the values are sorted alphabetically (using the
100 * english alphabet) except for _DEFAULT which is always first.
101 *
102 * If anyone might be wondering what the alphabet looks like:
103 * 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
104 *
105 * The RT_XX log group names are placeholders for new modules being added,
106 * to make sure that there always is a total of 32 log group entries.
107 */
108#define RT_LOGGROUP_NAMES \
109 "DEFAULT", \
110 "RT_CRYPTO", \
111 "RT_DBG", \
112 "RT_DBG_DWARF", \
113 "RT_DIR", \
114 "RT_FDT", \
115 "RT_FILE", \
116 "RT_FS", \
117 "RT_FTP", \
118 "RT_HTTP", \
119 "RT_IOQUEUE", \
120 "RT_LDR", \
121 "RT_LOCALIPC", \
122 "RT_PATH", \
123 "RT_PROCESS", \
124 "RT_REST", \
125 "RT_SYMLINK", \
126 "RT_THREAD", \
127 "RT_TIME", \
128 "RT_TIMER", \
129 "RT_VFS", \
130 "RT_21", \
131 "RT_22", \
132 "RT_23", \
133 "RT_24", \
134 "RT_25", \
135 "RT_26", \
136 "RT_27", \
137 "RT_28", \
138 "RT_29", \
139 "RT_30", \
140 "RT_ZIP"
141
142
143/** @def LOG_GROUP
144 * Active logging group.
145 */
146#ifndef LOG_GROUP
147# define LOG_GROUP RTLOGGROUP_DEFAULT
148#endif
149
150/** @def LOG_FN_FMT
151 * You can use this to specify your desired way of printing __PRETTY_FUNCTION__
152 * if you dislike the default one.
153 * @todo __PRETTY_FUNCTION__ is not optimal here.
154 */
155#ifndef LOG_FN_FMT
156# define LOG_FN_FMT "%Rfn"
157#endif
158
159/** @def LOG_FN_NAME
160 * Alias for __PRETTY_FUNCTION__ or similar that goes the best with LOG_FN_FMT.
161 * @todo __PRETTY_FUNCTION__ is not optimal here.
162 */
163#ifndef LOG_FN_NAME
164# define LOG_FN_NAME RT_GCC_EXTENSION __PRETTY_FUNCTION__
165#endif
166
167#ifdef LOG_INSTANCE
168# error "LOG_INSTANCE is no longer supported."
169#endif
170#ifdef LOG_REL_INSTANCE
171# error "LOG_REL_INSTANCE is no longer supported."
172#endif
173
174/** Logger structure. */
175typedef struct RTLOGGER RTLOGGER;
176/** Pointer to logger structure. */
177typedef RTLOGGER *PRTLOGGER;
178/** Pointer to const logger structure. */
179typedef const RTLOGGER *PCRTLOGGER;
180
181
182/** Pointer to a log buffer descriptor. */
183typedef struct RTLOGBUFFERDESC *PRTLOGBUFFERDESC;
184
185
186/**
187 * Logger phase.
188 *
189 * Used for signalling the log header/footer callback what to do.
190 */
191typedef enum RTLOGPHASE
192{
193 /** Begin of the logging. */
194 RTLOGPHASE_BEGIN = 0,
195 /** End of the logging. */
196 RTLOGPHASE_END,
197 /** Before rotating the log file. */
198 RTLOGPHASE_PREROTATE,
199 /** After rotating the log file. */
200 RTLOGPHASE_POSTROTATE,
201 /** 32-bit type blow up hack. */
202 RTLOGPHASE_32BIT_HACK = 0x7fffffff
203} RTLOGPHASE;
204
205
206#if 0 /* retired */
207/**
208 * Logger function.
209 *
210 * @param pszFormat Format string.
211 * @param ... Optional arguments as specified in the format string.
212 */
213typedef DECLCALLBACKTYPE(void, FNRTLOGGER,(const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(1, 2);
214/** Pointer to logger function. */
215typedef FNRTLOGGER *PFNRTLOGGER;
216#endif
217
218/**
219 * Custom buffer flushing function.
220 *
221 * @retval true if flushed and the buffer can be reused.
222 * @retval false for switching to the next buffer because an async flush of
223 * @a pBufDesc is still pending. The implementation is responsible for
224 * only returning when the next buffer is ready for reuse, the generic
225 * logger code has no facility to make sure of this.
226 *
227 * @param pLogger Pointer to the logger instance which is to be flushed.
228 * @param pBufDesc The descriptor of the buffer to be flushed.
229 */
230typedef DECLCALLBACKTYPE(bool, FNRTLOGFLUSH,(PRTLOGGER pLogger, PRTLOGBUFFERDESC pBufDesc));
231/** Pointer to flush function. */
232typedef FNRTLOGFLUSH *PFNRTLOGFLUSH;
233
234/**
235 * Header/footer message callback.
236 *
237 * @param pLogger Pointer to the logger instance.
238 * @param pszFormat Format string.
239 * @param ... Optional arguments specified in the format string.
240 */
241typedef DECLCALLBACKTYPE(void, FNRTLOGPHASEMSG,(PRTLOGGER pLogger, const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(2, 3);
242/** Pointer to header/footer message callback function. */
243typedef FNRTLOGPHASEMSG *PFNRTLOGPHASEMSG;
244
245/**
246 * Log file header/footer callback.
247 *
248 * @param pLogger Pointer to the logger instance.
249 * @param enmLogPhase Indicates at what time the callback is invoked.
250 * @param pfnLogPhaseMsg Callback for writing the header/footer (RTLogPrintf
251 * and others are out of bounds).
252 */
253typedef DECLCALLBACKTYPE(void, FNRTLOGPHASE,(PRTLOGGER pLogger, RTLOGPHASE enmLogPhase, PFNRTLOGPHASEMSG pfnLogPhaseMsg));
254/** Pointer to log header/footer callback function. */
255typedef FNRTLOGPHASE *PFNRTLOGPHASE;
256
257/**
258 * Custom log prefix callback.
259 *
260 *
261 * @returns The number of chars written.
262 *
263 * @param pLogger Pointer to the logger instance.
264 * @param pchBuf Output buffer pointer.
265 * No need to terminate the output.
266 * @param cchBuf The size of the output buffer.
267 * @param pvUser The user argument.
268 */
269typedef DECLCALLBACKTYPE(size_t, FNRTLOGPREFIX,(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser));
270/** Pointer to prefix callback function. */
271typedef FNRTLOGPREFIX *PFNRTLOGPREFIX;
272
273
274/** Pointer to a constant log output interface. */
275typedef const struct RTLOGOUTPUTIF *PCRTLOGOUTPUTIF;
276
277/**
278 * Logging output interface.
279 */
280typedef struct RTLOGOUTPUTIF
281{
282 /**
283 * Opens a log directory context to make log rotation changes within.
284 *
285 * @returns IPRT status code.
286 * @param pIf Pointer to this interface.
287 * @param pvUser Opaque user data passed when setting the callbacks.
288 * @param pszFilename The filename to create a context for.
289 * @param ppvDirCtx Where to return the opaque directory context.
290 */
291 DECLR3CALLBACKMEMBER(int, pfnDirCtxOpen, (PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename, void **ppvDirCtx));
292
293 /**
294 * Closes the log directory context.
295 *
296 * @returns IPRT status code.
297 * @param pIf Pointer to this interface.
298 * @param pvUser Opaque user data passed when setting the callbacks.
299 * @param pvDirCtx The opaque directory context returned by
300 * pfnDirCtxOpen.
301 */
302 DECLR3CALLBACKMEMBER(int, pfnDirCtxClose, (PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx));
303
304 /**
305 * Deletes the given file.
306 *
307 * @returns IPRT status code.
308 * @param pIf Pointer to this interface.
309 * @param pvUser Opaque user data passed when setting the callbacks.
310 * @param pvDirCtx The opaque directory context returned by
311 * pfnDirCtxOpen.
312 * @param pszFilename The filename to delete.
313 */
314 DECLR3CALLBACKMEMBER(int, pfnDelete, (PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx, const char *pszFilename));
315
316 /**
317 * Renames the given file.
318 *
319 * @returns IPRT status code.
320 * @param pIf Pointer to this interface.
321 * @param pvUser Opaque user data passed when setting the callbacks.
322 * @param pvDirCtx The opaque directory context returned by
323 * pfnDirCtxOpen.
324 * @param pszFilenameOld The old filename to rename.
325 * @param pszFilenameNew The new filename.
326 * @param fFlags Flags for the operation, combination of RTFILEMOVE_FLAGS_XXX.
327 */
328 DECLR3CALLBACKMEMBER(int, pfnRename, (PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx,
329 const char *pszFilenameOld, const char *pszFilenameNew, uint32_t fFlags));
330
331 /**
332 * Opens a new log file with the given name.
333 *
334 * @returns IPRT status code.
335 * @param pIf Pointer to this interface.
336 * @param pvUser Opaque user data passed when setting the callbacks.
337 * @param pvDirCtx The opaque directory context returned by
338 * pfnDirCtxOpen.
339 * @param pszFilename The filename to open.
340 * @param fFlags Open flags, combination of RTFILE_O_XXX.
341 */
342 DECLR3CALLBACKMEMBER(int, pfnOpen, (PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx,
343 const char *pszFilename, uint32_t fFlags));
344
345 /**
346 * Closes the currently open file.
347 *
348 * @returns IPRT status code.
349 * @param pIf Pointer to this interface.
350 * @param pvUser Opaque user data passed when setting the callbacks.
351 */
352 DECLR3CALLBACKMEMBER(int, pfnClose, (PCRTLOGOUTPUTIF pIf, void *pvUser));
353
354 /**
355 * Queries the size of the log file.
356 *
357 * @returns IPRT status code.
358 * @param pIf Pointer to this interface.
359 * @param pvUser Opaque user data passed when setting the callbacks.
360 * @param pcbFile Where to store the file size in bytes on success.
361 */
362 DECLR3CALLBACKMEMBER(int, pfnQuerySize, (PCRTLOGOUTPUTIF pIf, void *pvUser, uint64_t *pcbSize));
363
364 /**
365 * Writes data to the log file.
366 *
367 * @returns IPRT status code.
368 * @param pIf Pointer to this interface.
369 * @param pvUser Opaque user data passed when setting the callbacks.
370 * @param pvBuf The data to write.
371 * @param cbWrite Number of bytes to write.
372 * @param pcbWritten Where to store the actual number of bytes written on success.
373 */
374 DECLR3CALLBACKMEMBER(int, pfnWrite, (PCRTLOGOUTPUTIF pIf, void *pvUser, const void *pvBuf,
375 size_t cbWrite, size_t *pcbWritten));
376
377 /**
378 * Flushes data to the underlying storage medium.
379 *
380 * @returns IPRT status code.
381 * @param pIf Pointer to this interface.
382 * @param pvUser Opaque user data passed when setting the callbacks.
383 */
384 DECLR3CALLBACKMEMBER(int, pfnFlush, (PCRTLOGOUTPUTIF pIf, void *pvUser));
385} RTLOGOUTPUTIF;
386/** Pointer to a logging output interface. */
387typedef struct RTLOGOUTPUTIF *PRTLOGOUTPUTIF;
388
389
390/**
391 * Auxiliary buffer descriptor.
392 *
393 * This is what we share we ring-3 and use for flushing ring-0 EMT loggers when
394 * we return to ring-3.
395 */
396typedef struct RTLOGBUFFERAUXDESC
397{
398 /** Flush indicator.
399 * Ring-3 sets this if it flushed the buffer, ring-0 clears it again after
400 * writing. */
401 bool volatile fFlushedIndicator;
402 bool afPadding[3];
403 /** Copy of RTLOGBUFFERDESC::offBuf. */
404 uint32_t offBuf;
405} RTLOGBUFFERAUXDESC;
406/** Pointer to auxiliary buffer descriptor. */
407typedef RTLOGBUFFERAUXDESC *PRTLOGBUFFERAUXDESC;
408
409/**
410 * Log buffer desciptor.
411 */
412typedef struct RTLOGBUFFERDESC
413{
414 /** Magic value / eye catcher (RTLOGBUFFERDESC_MAGIC). */
415 uint32_t u32Magic;
416 /** Padding. */
417 uint32_t uReserved;
418 /** The buffer size. */
419 uint32_t cbBuf;
420 /** The current buffer offset. */
421 uint32_t offBuf;
422 /** Pointer to the buffer. */
423 char *pchBuf;
424 /** Pointer to auxiliary desciptor, NULL if not used. */
425 PRTLOGBUFFERAUXDESC pAux;
426} RTLOGBUFFERDESC;
427
428/** RTLOGBUFFERDESC::u32Magic value. (Avram Noam Chomsky) */
429#define RTLOGBUFFERDESC_MAGIC UINT32_C(0x19281207)
430
431/**
432 * The public logger instance part.
433 *
434 * The logger instance is mostly abstract and kept as RTLOGGERINTERNAL within
435 * log.cpp. This public part is at the start of RTLOGGERINTERNAL.
436 */
437struct RTLOGGER
438{
439 /** Magic number (RTLOGGER_MAGIC). */
440 uint32_t u32Magic;
441 /** User value \#1, initialized to zero. */
442 uint32_t u32UserValue1;
443 /** User value \#2, initialized to zero. */
444 uint64_t u64UserValue2;
445 /** User value \#3, initialized to zero. */
446 uint64_t u64UserValue3;
447#if 0
448 /** Pointer to the logger function (used in non-C99 mode only).
449 *
450 * This is actually pointer to a wrapper/stub function which will push a pointer
451 * to the instance pointer onto the stack before jumping to the real logger
452 * function. A very unfortunate hack to work around the missing variadic macro
453 * support in older C++/C standards. (The memory is allocated using
454 * RTMemExecAlloc(), except for agnostic R0 code.) */
455 PFNRTLOGGER pfnLogger;
456#else
457 /** Unused. */
458 uintptr_t uUsedToBeNonC99Logger;
459#endif
460#if ARCH_BITS == 32
461 /** Explicit padding. */
462 uint32_t uReserved1;
463#endif
464};
465
466/** RTLOGGER::u32Magic value. (John Rogers Searle) */
467#define RTLOGGER_MAGIC UINT32_C(0x19320731)
468
469/**
470 * Logger flags.
471 */
472typedef enum RTLOGFLAGS
473{
474 /** The logger instance is disabled for normal output. */
475 RTLOGFLAGS_DISABLED = 0x00000001,
476 /** The logger instance is using buffered output. */
477 RTLOGFLAGS_BUFFERED = 0x00000002,
478 /** The logger instance expands LF to CR/LF. */
479 RTLOGFLAGS_USECRLF = 0x00000010,
480 /** Append to the log destination where applicable. */
481 RTLOGFLAGS_APPEND = 0x00000020,
482 /** Show relative timestamps with PREFIX_TSC and PREFIX_TS */
483 RTLOGFLAGS_REL_TS = 0x00000040,
484 /** Show decimal timestamps with PREFIX_TSC and PREFIX_TS */
485 RTLOGFLAGS_DECIMAL_TS = 0x00000080,
486 /** Open the file in write through mode. */
487 RTLOGFLAGS_WRITE_THROUGH = 0x00000100,
488 /** Flush the file to disk when flushing the buffer. */
489 RTLOGFLAGS_FLUSH = 0x00000200,
490 /** Restrict the number of log entries per group. */
491 RTLOGFLAGS_RESTRICT_GROUPS = 0x00000400,
492 /** New lines should be prefixed with the write and read lock counts. */
493 RTLOGFLAGS_PREFIX_LOCK_COUNTS = 0x00008000,
494 /** New lines should be prefixed with the CPU id (ApicID on intel/amd). */
495 RTLOGFLAGS_PREFIX_CPUID = 0x00010000,
496 /** New lines should be prefixed with the native process id. */
497 RTLOGFLAGS_PREFIX_PID = 0x00020000,
498 /** New lines should be prefixed with group flag number causing the output. */
499 RTLOGFLAGS_PREFIX_FLAG_NO = 0x00040000,
500 /** New lines should be prefixed with group flag name causing the output. */
501 RTLOGFLAGS_PREFIX_FLAG = 0x00080000,
502 /** New lines should be prefixed with group number. */
503 RTLOGFLAGS_PREFIX_GROUP_NO = 0x00100000,
504 /** New lines should be prefixed with group name. */
505 RTLOGFLAGS_PREFIX_GROUP = 0x00200000,
506 /** New lines should be prefixed with the native thread id. */
507 RTLOGFLAGS_PREFIX_TID = 0x00400000,
508 /** New lines should be prefixed with thread name. */
509 RTLOGFLAGS_PREFIX_THREAD = 0x00800000,
510 /** New lines should be prefixed with data from a custom callback. */
511 RTLOGFLAGS_PREFIX_CUSTOM = 0x01000000,
512 /** New lines should be prefixed with formatted timestamp since program start. */
513 RTLOGFLAGS_PREFIX_TIME_PROG = 0x04000000,
514 /** New lines should be prefixed with formatted timestamp (UCT). */
515 RTLOGFLAGS_PREFIX_TIME = 0x08000000,
516 /** New lines should be prefixed with milliseconds since program start. */
517 RTLOGFLAGS_PREFIX_MS_PROG = 0x10000000,
518 /** New lines should be prefixed with timestamp. */
519 RTLOGFLAGS_PREFIX_TSC = 0x20000000,
520 /** New lines should be prefixed with timestamp. */
521 RTLOGFLAGS_PREFIX_TS = 0x40000000,
522 /** The prefix mask. */
523 RTLOGFLAGS_PREFIX_MASK = 0x7dff8000
524} RTLOGFLAGS;
525/** Don't use locking. */
526#define RTLOG_F_NO_LOCKING RT_BIT_64(63)
527/** Mask with all valid log flags (for validation). */
528#define RTLOG_F_VALID_MASK UINT64_C(0x800000007fff87f3)
529
530/**
531 * Logger per group flags.
532 *
533 * @remarks We only use the lower 16 bits here. We'll be combining it with the
534 * group number in a few places (e.g. RTLogDefaultInstanceEx,
535 * RTLogGetDefaultInstanceEx, RTLogRelGetDefaultInstanceEx, ++) where
536 * the high 16-bit word is used for the group number.
537 */
538typedef enum RTLOGGRPFLAGS
539{
540 /** Enabled. */
541 RTLOGGRPFLAGS_ENABLED = 0x0001,
542 /** Flow logging. */
543 RTLOGGRPFLAGS_FLOW = 0x0002,
544 /** Warnings logging. */
545 RTLOGGRPFLAGS_WARN = 0x0004,
546 /* 0x0008 for later. */
547 /** Level 1 logging. */
548 RTLOGGRPFLAGS_LEVEL_1 = 0x0010,
549 /** Level 2 logging. */
550 RTLOGGRPFLAGS_LEVEL_2 = 0x0020,
551 /** Level 3 logging. */
552 RTLOGGRPFLAGS_LEVEL_3 = 0x0040,
553 /** Level 4 logging. */
554 RTLOGGRPFLAGS_LEVEL_4 = 0x0080,
555 /** Level 5 logging. */
556 RTLOGGRPFLAGS_LEVEL_5 = 0x0100,
557 /** Level 6 logging. */
558 RTLOGGRPFLAGS_LEVEL_6 = 0x0200,
559 /** Level 7 logging. */
560 RTLOGGRPFLAGS_LEVEL_7 = 0x0400,
561 /** Level 8 logging. */
562 RTLOGGRPFLAGS_LEVEL_8 = 0x0800,
563 /** Level 9 logging. */
564 RTLOGGRPFLAGS_LEVEL_9 = 0x1000,
565 /** Level 10 logging. */
566 RTLOGGRPFLAGS_LEVEL_10 = 0x2000,
567 /** Level 11 logging. */
568 RTLOGGRPFLAGS_LEVEL_11 = 0x4000,
569 /** Level 12 logging. */
570 RTLOGGRPFLAGS_LEVEL_12 = 0x8000,
571
572 /** Restrict the number of log entries. */
573 RTLOGGRPFLAGS_RESTRICT = 0x40000000,
574 /** Blow up the type. */
575 RTLOGGRPFLAGS_32BIT_HACK = 0x7fffffff
576} RTLOGGRPFLAGS;
577
578/**
579 * Logger destination types and flags.
580 */
581typedef enum RTLOGDEST
582{
583 /** Log to file. */
584 RTLOGDEST_FILE = 0x00000001,
585 /** Log to stdout. */
586 RTLOGDEST_STDOUT = 0x00000002,
587 /** Log to stderr. */
588 RTLOGDEST_STDERR = 0x00000004,
589 /** Log to debugger (win32 only). */
590 RTLOGDEST_DEBUGGER = 0x00000008,
591 /** Log to com port. */
592 RTLOGDEST_COM = 0x00000010,
593 /** Log a memory ring buffer. */
594 RTLOGDEST_RINGBUF = 0x00000020,
595 /** The parent VMM debug log. */
596 RTLOGDEST_VMM = 0x00000040,
597 /** The parent VMM release log. */
598 RTLOGDEST_VMM_REL = 0x00000080,
599 /** Open files with no deny (share read, write, delete) on Windows. */
600 RTLOGDEST_F_NO_DENY = 0x00010000,
601 /** Delay opening the log file, logging to the buffer untill
602 * RTLogClearFileDelayFlag is called. */
603 RTLOGDEST_F_DELAY_FILE = 0x00020000,
604 /** Don't allow changes to the filename or mode of opening it. */
605 RTLOGDEST_FIXED_FILE = 0x01000000,
606 /** Don't allow changing the directory. */
607 RTLOGDEST_FIXED_DIR = 0x02000000,
608 /** Just a dummy flag to be used when no other flag applies. */
609 RTLOGDEST_DUMMY = 0x20000000,
610 /** Log to a user defined output stream. */
611 RTLOGDEST_USER = 0x40000000
612} RTLOGDEST;
613/** Valid log destinations. */
614#define RTLOG_DST_VALID_MASK UINT32_C(0x630300ff)
615/** Log destinations that can be changed via RTLogChangeDestinations. */
616#define RTLOG_DST_CHANGE_MASK UINT32_C(0x400000de)
617
618
619#ifdef DOXYGEN_RUNNING
620# define LOG_DISABLED
621# define LOG_ENABLED
622# define LOG_ENABLE_FLOW
623#endif
624
625/** @def LOG_DISABLED
626 * Use this compile time define to disable all logging macros. It can
627 * be overridden for each of the logging macros by the LOG_ENABLE*
628 * compile time defines.
629 */
630
631/** @def LOG_ENABLED
632 * Use this compile time define to enable logging when not in debug mode
633 * or LOG_DISABLED is set.
634 * This will enable Log() only.
635 */
636
637/** @def LOG_ENABLE_FLOW
638 * Use this compile time define to enable flow logging when not in
639 * debug mode or LOG_DISABLED is defined.
640 * This will enable LogFlow() only.
641 */
642
643/*
644 * Determine whether logging is enabled and forcefully normalize the indicators.
645 */
646#if (defined(DEBUG) || defined(LOG_ENABLED)) && !defined(LOG_DISABLED)
647# undef LOG_DISABLED
648# undef LOG_ENABLED
649# define LOG_ENABLED
650#else
651# undef LOG_ENABLED
652# undef LOG_DISABLED
653# define LOG_DISABLED
654#endif
655
656
657/** @def LOG_USE_C99
658 * Governs the use of variadic macros.
659 */
660#ifndef LOG_USE_C99
661# define LOG_USE_C99
662#endif
663
664
665/** @name Macros for checking whether a log level is enabled.
666 * @{ */
667/** @def LogIsItEnabled
668 * Checks whether the specified logging group is enabled or not.
669 */
670#ifdef LOG_ENABLED
671# define LogIsItEnabled(a_fFlags, a_iGroup) ( RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)) != NULL )
672#else
673# define LogIsItEnabled(a_fFlags, a_iGroup) (false)
674#endif
675
676/** @def LogIsEnabledOnly
677 * Checks whether the group is enabled w/o reference to any specific level.
678 */
679#define LogIsEnabledOnly() LogIsItEnabled(RTLOGGRPFLAGS_ENABLED, LOG_GROUP)
680
681/** @def LogIsEnabled
682 * Checks whether level 1 logging is enabled.
683 */
684#define LogIsEnabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
685
686/** @def LogIs2Enabled
687 * Checks whether level 2 logging is enabled.
688 */
689#define LogIs2Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
690
691/** @def LogIs3Enabled
692 * Checks whether level 3 logging is enabled.
693 */
694#define LogIs3Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
695
696/** @def LogIs4Enabled
697 * Checks whether level 4 logging is enabled.
698 */
699#define LogIs4Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
700
701/** @def LogIs5Enabled
702 * Checks whether level 5 logging is enabled.
703 */
704#define LogIs5Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
705
706/** @def LogIs6Enabled
707 * Checks whether level 6 logging is enabled.
708 */
709#define LogIs6Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
710
711/** @def LogIs7Enabled
712 * Checks whether level 7 logging is enabled.
713 */
714#define LogIs7Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP)
715
716/** @def LogIs8Enabled
717 * Checks whether level 8 logging is enabled.
718 */
719#define LogIs8Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP)
720
721/** @def LogIs9Enabled
722 * Checks whether level 9 logging is enabled.
723 */
724#define LogIs9Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP)
725
726/** @def LogIs10Enabled
727 * Checks whether level 10 logging is enabled.
728 */
729#define LogIs10Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP)
730
731/** @def LogIs11Enabled
732 * Checks whether level 11 logging is enabled.
733 */
734#define LogIs11Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP)
735
736/** @def LogIs12Enabled
737 * Checks whether level 12 logging is enabled.
738 */
739#define LogIs12Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP)
740
741/** @def LogIsFlowEnabled
742 * Checks whether execution flow logging is enabled.
743 */
744#define LogIsFlowEnabled() LogIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
745
746/** @def LogIsWarnEnabled
747 * Checks whether execution flow logging is enabled.
748 */
749#define LogIsWarnEnabled() LogIsItEnabled(RTLOGGRPFLAGS_WARN, LOG_GROUP)
750/** @} */
751
752
753/** @def LogIt
754 * Write to specific logger if group enabled.
755 */
756#ifdef LOG_ENABLED
757# if defined(LOG_USE_C99)
758# define _LogRemoveParentheseis(...) __VA_ARGS__
759# define _LogIt(a_fFlags, a_iGroup, ...) \
760 do \
761 { \
762 PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
763 if (RT_LIKELY(!LogIt_pLogger)) \
764 { /* likely */ } \
765 else \
766 RTLogLoggerEx(LogIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
767 } while (0)
768# define LogIt(a_fFlags, a_iGroup, fmtargs) _LogIt(a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
769# define _LogItAlways(a_fFlags, a_iGroup, ...) RTLogLoggerEx(NULL, a_fFlags, UINT32_MAX, __VA_ARGS__)
770# define LogItAlways(a_fFlags, a_iGroup, fmtargs) _LogItAlways(a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
771 /** @todo invent a flag or something for skipping the group check so we can pass iGroup. LogItAlways. */
772# else
773# define LogIt(a_fFlags, a_iGroup, fmtargs) \
774 do \
775 { \
776 PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
777 if (RT_LIKELY(!LogIt_pLogger)) \
778 { /* likely */ } \
779 else \
780 { \
781 LogIt_pLogger->pfnLogger fmtargs; \
782 } \
783 } while (0)
784# define LogItAlways(a_fFlags, a_iGroup, fmtargs) \
785 do \
786 { \
787 PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX)); \
788 if (LogIt_pLogger) \
789 LogIt_pLogger->pfnLogger fmtargs; \
790 } while (0)
791# endif
792#else
793# define LogIt(a_fFlags, a_iGroup, fmtargs) do { } while (0)
794# define LogItAlways(a_fFlags, a_iGroup, fmtargs) do { } while (0)
795# if defined(LOG_USE_C99)
796# define _LogRemoveParentheseis(...) __VA_ARGS__
797# define _LogIt(a_fFlags, a_iGroup, ...) do { } while (0)
798# define _LogItAlways(a_fFlags, a_iGroup, ...) do { } while (0)
799# endif
800#endif
801
802
803/** @name Basic logging macros
804 * @{ */
805/** @def Log
806 * Level 1 logging that works regardless of the group settings.
807 */
808#define LogAlways(a) LogItAlways(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
809
810/** @def Log
811 * Level 1 logging.
812 */
813#define Log(a) LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
814
815/** @def Log2
816 * Level 2 logging.
817 */
818#define Log2(a) LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
819
820/** @def Log3
821 * Level 3 logging.
822 */
823#define Log3(a) LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
824
825/** @def Log4
826 * Level 4 logging.
827 */
828#define Log4(a) LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
829
830/** @def Log5
831 * Level 5 logging.
832 */
833#define Log5(a) LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
834
835/** @def Log6
836 * Level 6 logging.
837 */
838#define Log6(a) LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
839
840/** @def Log7
841 * Level 7 logging.
842 */
843#define Log7(a) LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, a)
844
845/** @def Log8
846 * Level 8 logging.
847 */
848#define Log8(a) LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, a)
849
850/** @def Log9
851 * Level 9 logging.
852 */
853#define Log9(a) LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, a)
854
855/** @def Log10
856 * Level 10 logging.
857 */
858#define Log10(a) LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
859
860/** @def Log11
861 * Level 11 logging.
862 */
863#define Log11(a) LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
864
865/** @def Log12
866 * Level 12 logging.
867 */
868#define Log12(a) LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
869
870/** @def LogFlow
871 * Logging of execution flow.
872 */
873#define LogFlow(a) LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
874
875/** @def LogWarn
876 * Logging of warnings.
877 */
878#define LogWarn(a) LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, a)
879/** @} */
880
881
882/** @name Logging macros prefixing the current function name.
883 * @{ */
884/** @def LogFunc
885 * Level 1 logging inside C/C++ functions.
886 *
887 * Prepends the given log message with the function name followed by a
888 * semicolon and space.
889 *
890 * @param a Log message in format <tt>("string\n" [, args])</tt>.
891 */
892#ifdef LOG_USE_C99
893# define LogFunc(a) _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
894#else
895# define LogFunc(a) do { Log((LOG_FN_FMT ": ", LOG_FN_NAME)); Log(a); } while (0)
896#endif
897
898/** @def Log2Func
899 * Level 2 logging inside C/C++ functions.
900 *
901 * Prepends the given log message with the function name followed by a
902 * semicolon and space.
903 *
904 * @param a Log message in format <tt>("string\n" [, args])</tt>.
905 */
906#ifdef LOG_USE_C99
907# define Log2Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
908#else
909# define Log2Func(a) do { Log2((LOG_FN_FMT ": ", LOG_FN_NAME)); Log2(a); } while (0)
910#endif
911
912/** @def Log3Func
913 * Level 3 logging inside C/C++ functions.
914 *
915 * Prepends the given log message with the function name followed by a
916 * semicolon and space.
917 *
918 * @param a Log message in format <tt>("string\n" [, args])</tt>.
919 */
920#ifdef LOG_USE_C99
921# define Log3Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
922#else
923# define Log3Func(a) do { Log3((LOG_FN_FMT ": ", LOG_FN_NAME)); Log3(a); } while (0)
924#endif
925
926/** @def Log4Func
927 * Level 4 logging inside C/C++ functions.
928 *
929 * Prepends the given log message with the function name followed by a
930 * semicolon and space.
931 *
932 * @param a Log message in format <tt>("string\n" [, args])</tt>.
933 */
934#ifdef LOG_USE_C99
935# define Log4Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
936#else
937# define Log4Func(a) do { Log4((LOG_FN_FMT ": ", LOG_FN_NAME)); Log4(a); } while (0)
938#endif
939
940/** @def Log5Func
941 * Level 5 logging inside C/C++ functions.
942 *
943 * Prepends the given log message with the function name followed by a
944 * semicolon and space.
945 *
946 * @param a Log message in format <tt>("string\n" [, args])</tt>.
947 */
948#ifdef LOG_USE_C99
949# define Log5Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
950#else
951# define Log5Func(a) do { Log5((LOG_FN_FMT ": ", LOG_FN_NAME)); Log5(a); } while (0)
952#endif
953
954/** @def Log6Func
955 * Level 6 logging inside C/C++ functions.
956 *
957 * Prepends the given log message with the function name followed by a
958 * semicolon and space.
959 *
960 * @param a Log message in format <tt>("string\n" [, args])</tt>.
961 */
962#ifdef LOG_USE_C99
963# define Log6Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
964#else
965# define Log6Func(a) do { Log6((LOG_FN_FMT ": ", LOG_FN_NAME)); Log6(a); } while (0)
966#endif
967
968/** @def Log7Func
969 * Level 7 logging inside C/C++ functions.
970 *
971 * Prepends the given log message with the function name followed by a
972 * semicolon and space.
973 *
974 * @param a Log message in format <tt>("string\n" [, args])</tt>.
975 */
976#ifdef LOG_USE_C99
977# define Log7Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
978#else
979# define Log7Func(a) do { Log7((LOG_FN_FMT ": ", LOG_FN_NAME)); Log7(a); } while (0)
980#endif
981
982/** @def Log8Func
983 * Level 8 logging inside C/C++ functions.
984 *
985 * Prepends the given log message with the function name followed by a
986 * semicolon and space.
987 *
988 * @param a Log message in format <tt>("string\n" [, args])</tt>.
989 */
990#ifdef LOG_USE_C99
991# define Log8Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
992#else
993# define Log8Func(a) do { Log8((LOG_FN_FMT ": ", LOG_FN_NAME)); Log8(a); } while (0)
994#endif
995
996/** @def Log9Func
997 * Level 9 logging inside C/C++ functions.
998 *
999 * Prepends the given log message with the function name followed by a
1000 * semicolon and space.
1001 *
1002 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1003 */
1004#ifdef LOG_USE_C99
1005# define Log9Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1006#else
1007# define Log9Func(a) do { Log9((LOG_FN_FMT ": ", LOG_FN_NAME)); Log9(a); } while (0)
1008#endif
1009
1010/** @def Log10Func
1011 * Level 10 logging inside C/C++ functions.
1012 *
1013 * Prepends the given log message with the function name followed by a
1014 * semicolon and space.
1015 *
1016 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1017 */
1018#ifdef LOG_USE_C99
1019# define Log10Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1020#else
1021# define Log10Func(a) do { Log10((LOG_FN_FMT ": ", LOG_FN_NAME)); Log10(a); } while (0)
1022#endif
1023
1024/** @def Log11Func
1025 * Level 11 logging inside C/C++ functions.
1026 *
1027 * Prepends the given log message with the function name followed by a
1028 * semicolon and space.
1029 *
1030 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1031 */
1032#ifdef LOG_USE_C99
1033# define Log11Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1034#else
1035# define Log11Func(a) do { Log11((LOG_FN_FMT ": ", LOG_FN_NAME)); Log11(a); } while (0)
1036#endif
1037
1038/** @def Log12Func
1039 * Level 12 logging inside C/C++ functions.
1040 *
1041 * Prepends the given log message with the function name followed by a
1042 * semicolon and space.
1043 *
1044 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1045 */
1046#ifdef LOG_USE_C99
1047# define Log12Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1048#else
1049# define Log12Func(a) do { Log12((LOG_FN_FMT ": ", LOG_FN_NAME)); Log12(a); } while (0)
1050#endif
1051
1052/** @def LogFlowFunc
1053 * Macro to log the execution flow inside C/C++ functions.
1054 *
1055 * Prepends the given log message with the function name followed by
1056 * a semicolon and space.
1057 *
1058 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1059 */
1060#ifdef LOG_USE_C99
1061# define LogFlowFunc(a) \
1062 _LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1063#else
1064# define LogFlowFunc(a) \
1065 do { LogFlow((LOG_FN_FMT ": ", LOG_FN_NAME)); LogFlow(a); } while (0)
1066#endif
1067
1068/** @def LogWarnFunc
1069 * Macro to log a warning inside C/C++ functions.
1070 *
1071 * Prepends the given log message with the function name followed by
1072 * a semicolon and space.
1073 *
1074 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1075 */
1076#ifdef LOG_USE_C99
1077# define LogWarnFunc(a) \
1078 _LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1079#else
1080# define LogWarnFunc(a) \
1081 do { LogFlow((LOG_FN_FMT ": ", LOG_FN_NAME)); LogFlow(a); } while (0)
1082#endif
1083/** @} */
1084
1085
1086/** @name Logging macros prefixing the this pointer value and method name.
1087 * @{ */
1088
1089/** @def LogThisFunc
1090 * Level 1 logging inside a C++ non-static method, with object pointer and
1091 * method name prefixed to the given message.
1092 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1093 */
1094#ifdef LOG_USE_C99
1095# define LogThisFunc(a) \
1096 _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1097#else
1098# define LogThisFunc(a) do { Log(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log(a); } while (0)
1099#endif
1100
1101/** @def Log2ThisFunc
1102 * Level 2 logging inside a C++ non-static method, with object pointer and
1103 * method name prefixed to the given message.
1104 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1105 */
1106#ifdef LOG_USE_C99
1107# define Log2ThisFunc(a) \
1108 _LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1109#else
1110# define Log2ThisFunc(a) do { Log2(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log2(a); } while (0)
1111#endif
1112
1113/** @def Log3ThisFunc
1114 * Level 3 logging inside a C++ non-static method, with object pointer and
1115 * method name prefixed to the given message.
1116 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1117 */
1118#ifdef LOG_USE_C99
1119# define Log3ThisFunc(a) \
1120 _LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1121#else
1122# define Log3ThisFunc(a) do { Log3(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log3(a); } while (0)
1123#endif
1124
1125/** @def Log4ThisFunc
1126 * Level 4 logging inside a C++ non-static method, with object pointer and
1127 * method name prefixed to the given message.
1128 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1129 */
1130#ifdef LOG_USE_C99
1131# define Log4ThisFunc(a) \
1132 _LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1133#else
1134# define Log4ThisFunc(a) do { Log4(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log4(a); } while (0)
1135#endif
1136
1137/** @def Log5ThisFunc
1138 * Level 5 logging inside a C++ non-static method, with object pointer and
1139 * method name prefixed to the given message.
1140 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1141 */
1142#ifdef LOG_USE_C99
1143# define Log5ThisFunc(a) \
1144 _LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1145#else
1146# define Log5ThisFunc(a) do { Log5(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log5(a); } while (0)
1147#endif
1148
1149/** @def Log6ThisFunc
1150 * Level 6 logging inside a C++ non-static method, with object pointer and
1151 * method name prefixed to the given message.
1152 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1153 */
1154#ifdef LOG_USE_C99
1155# define Log6ThisFunc(a) \
1156 _LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1157#else
1158# define Log6ThisFunc(a) do { Log6(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log6(a); } while (0)
1159#endif
1160
1161/** @def Log7ThisFunc
1162 * Level 7 logging inside a C++ non-static method, with object pointer and
1163 * method name prefixed to the given message.
1164 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1165 */
1166#ifdef LOG_USE_C99
1167# define Log7ThisFunc(a) \
1168 _LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1169#else
1170# define Log7ThisFunc(a) do { Log7(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log7(a); } while (0)
1171#endif
1172
1173/** @def Log8ThisFunc
1174 * Level 8 logging inside a C++ non-static method, with object pointer and
1175 * method name prefixed to the given message.
1176 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1177 */
1178#ifdef LOG_USE_C99
1179# define Log8ThisFunc(a) \
1180 _LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1181#else
1182# define Log8ThisFunc(a) do { Log8(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log8(a); } while (0)
1183#endif
1184
1185/** @def Log9ThisFunc
1186 * Level 9 logging inside a C++ non-static method, with object pointer and
1187 * method name prefixed to the given message.
1188 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1189 */
1190#ifdef LOG_USE_C99
1191# define Log9ThisFunc(a) \
1192 _LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1193#else
1194# define Log9ThisFunc(a) do { Log9(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log9(a); } while (0)
1195#endif
1196
1197/** @def Log10ThisFunc
1198 * Level 10 logging inside a C++ non-static method, with object pointer and
1199 * method name prefixed to the given message.
1200 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1201 */
1202#ifdef LOG_USE_C99
1203# define Log10ThisFunc(a) \
1204 _LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1205#else
1206# define Log10ThisFunc(a) do { Log10(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log10(a); } while (0)
1207#endif
1208
1209/** @def Log11ThisFunc
1210 * Level 11 logging inside a C++ non-static method, with object pointer and
1211 * method name prefixed to the given message.
1212 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1213 */
1214#ifdef LOG_USE_C99
1215# define Log11ThisFunc(a) \
1216 _LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1217#else
1218# define Log11ThisFunc(a) do { Log11(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log11(a); } while (0)
1219#endif
1220
1221/** @def Log12ThisFunc
1222 * Level 12 logging inside a C++ non-static method, with object pointer and
1223 * method name prefixed to the given message.
1224 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1225 */
1226#ifdef LOG_USE_C99
1227# define Log12ThisFunc(a) \
1228 _LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1229#else
1230# define Log12ThisFunc(a) do { Log12(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log12(a); } while (0)
1231#endif
1232
1233/** @def LogFlowThisFunc
1234 * Flow level logging inside a C++ non-static method, with object pointer and
1235 * method name prefixed to the given message.
1236 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1237 */
1238#ifdef LOG_USE_C99
1239# define LogFlowThisFunc(a) \
1240 _LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1241#else
1242# define LogFlowThisFunc(a) do { LogFlow(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogFlow(a); } while (0)
1243#endif
1244
1245/** @def LogWarnThisFunc
1246 * Warning level logging inside a C++ non-static method, with object pointer and
1247 * method name prefixed to the given message.
1248 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1249 */
1250#ifdef LOG_USE_C99
1251# define LogWarnThisFunc(a) \
1252 _LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1253#else
1254# define LogWarnThisFunc(a) do { LogWarn(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogWarn(a); } while (0)
1255#endif
1256/** @} */
1257
1258
1259/** @name Misc Logging Macros
1260 * @{ */
1261
1262/** @def Log1Warning
1263 * The same as Log(), but prepents a <tt>"WARNING! "</tt> string to the message.
1264 *
1265 * @param a Custom log message in format <tt>("string\n" [, args])</tt>.
1266 */
1267#if defined(LOG_USE_C99)
1268# define Log1Warning(a) _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "WARNING! %M", _LogRemoveParentheseis a )
1269#else
1270# define Log1Warning(a) do { Log(("WARNING! ")); Log(a); } while (0)
1271#endif
1272
1273/** @def Log1WarningFunc
1274 * The same as LogWarning(), but prepents the log message with the function name.
1275 *
1276 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1277 */
1278#ifdef LOG_USE_C99
1279# define Log1WarningFunc(a) \
1280 _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": WARNING! %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1281#else
1282# define Log1WarningFunc(a) \
1283 do { Log((LOG_FN_FMT ": WARNING! ", LOG_FN_NAME)); Log(a); } while (0)
1284#endif
1285
1286/** @def Log1WarningThisFunc
1287 * The same as LogWarningFunc() but for class functions (methods): the resulting
1288 * log line is additionally prepended with a hex value of |this| pointer.
1289 *
1290 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1291 */
1292#ifdef LOG_USE_C99
1293# define Log1WarningThisFunc(a) \
1294 _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": WARNING! %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1295#else
1296# define Log1WarningThisFunc(a) \
1297 do { Log(("{%p} " LOG_FN_FMT ": WARNING! ", this, LOG_FN_NAME)); Log(a); } while (0)
1298#endif
1299
1300
1301/** Shortcut to |LogFlowFunc ("ENTER\n")|, marks the beginnig of the function. */
1302#define LogFlowFuncEnter() LogFlowFunc(("ENTER\n"))
1303
1304/** Shortcut to |LogFlowFunc ("LEAVE\n")|, marks the end of the function. */
1305#define LogFlowFuncLeave() LogFlowFunc(("LEAVE\n"))
1306
1307/** Shortcut to |LogFlowFunc ("LEAVE: %Rrc\n")|, marks the end of the function. */
1308#define LogFlowFuncLeaveRC(rc) LogFlowFunc(("LEAVE: %Rrc\n", (rc)))
1309
1310/** Shortcut to |LogFlowThisFunc ("ENTER\n")|, marks the beginnig of the function. */
1311#define LogFlowThisFuncEnter() LogFlowThisFunc(("ENTER\n"))
1312
1313/** Shortcut to |LogFlowThisFunc ("LEAVE\n")|, marks the end of the function. */
1314#define LogFlowThisFuncLeave() LogFlowThisFunc(("LEAVE\n"))
1315
1316
1317/** @def LogObjRefCnt
1318 * Helper macro to print the current reference count of the given COM object
1319 * to the log file.
1320 *
1321 * @param pObj Pointer to the object in question (must be a pointer to an
1322 * IUnknown subclass or simply define COM-style AddRef() and
1323 * Release() methods)
1324 */
1325#define LogObjRefCnt(pObj) \
1326 do { \
1327 if (LogIsFlowEnabled()) \
1328 { \
1329 int cRefsForLog = (pObj)->AddRef(); \
1330 LogFlow((#pObj "{%p}.refCnt=%d\n", (pObj), cRefsForLog - 1)); \
1331 (pObj)->Release(); \
1332 } \
1333 } while (0)
1334/** @} */
1335
1336
1337/** @name Logging to specific group.
1338 * @{ */
1339/** @def LogEx
1340 * Level 1 logging to specific group.
1341 */
1342#define LogEx(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_1, a_Grp, a)
1343
1344/** @def Log2Ex
1345 * Level 2 logging to specific group.
1346 */
1347#define Log2Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_2, a_Grp, a)
1348
1349/** @def Log3Ex
1350 * Level 3 logging to specific group.
1351 */
1352#define Log3Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_3, a_Grp, a)
1353
1354/** @def Log4Ex
1355 * Level 4 logging to specific group.
1356 */
1357#define Log4Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_4, a_Grp, a)
1358
1359/** @def Log5Ex
1360 * Level 5 logging to specific group.
1361 */
1362#define Log5Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_5, a_Grp, a)
1363
1364/** @def Log6Ex
1365 * Level 6 logging to specific group.
1366 */
1367#define Log6Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_6, a_Grp, a)
1368
1369/** @def Log7Ex
1370 * Level 7 logging to specific group.
1371 */
1372#define Log7Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_7, a_Grp, a)
1373
1374/** @def Log8Ex
1375 * Level 8 logging to specific group.
1376 */
1377#define Log8Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_8, a_Grp, a)
1378
1379/** @def Log9Ex
1380 * Level 9 logging to specific group.
1381 */
1382#define Log9Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_9, a_Grp, a)
1383
1384/** @def Log10Ex
1385 * Level 10 logging to specific group.
1386 */
1387#define Log10Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_10, a_Grp, a)
1388
1389/** @def Log11Ex
1390 * Level 11 logging to specific group.
1391 */
1392#define Log11Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_11, a_Grp, a)
1393
1394/** @def Log12Ex
1395 * Level 12 logging to specific group.
1396 */
1397#define Log12Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_12, a_Grp, a)
1398
1399/** @def LogFlowEx
1400 * Logging of execution flow to specific group.
1401 */
1402#define LogFlowEx(a_Grp, a) LogIt(RTLOGGRPFLAGS_FLOW, a_Grp, a)
1403
1404/** @def LogWarnEx
1405 * Logging of warnings to specific group.
1406 */
1407#define LogWarnEx(a_Grp, a) LogIt(RTLOGGRPFLAGS_WARN, a_Grp, a)
1408/** @} */
1409
1410
1411/** @name Passing Function Call Position When Logging.
1412 *
1413 * This is a little bit ugly as we have to omit the comma before the
1414 * position parameters so that we don't inccur any overhead in non-logging
1415 * builds (!defined(LOG_ENABLED).
1416 *
1417 * @{ */
1418/** Source position for passing to a function call. */
1419#ifdef LOG_ENABLED
1420# define RTLOG_COMMA_SRC_POS , __FILE__, __LINE__, LOG_FN_NAME
1421#else
1422# define RTLOG_COMMA_SRC_POS RT_NOTHING
1423#endif
1424/** Source position declaration. */
1425#ifdef LOG_ENABLED
1426# define RTLOG_COMMA_SRC_POS_DECL , const char *pszFile, unsigned iLine, const char *pszFunction
1427#else
1428# define RTLOG_COMMA_SRC_POS_DECL RT_NOTHING
1429#endif
1430/** Source position arguments. */
1431#ifdef LOG_ENABLED
1432# define RTLOG_COMMA_SRC_POS_ARGS , pszFile, iLine, pszFunction
1433#else
1434# define RTLOG_COMMA_SRC_POS_ARGS RT_NOTHING
1435#endif
1436/** Applies NOREF() to the source position arguments. */
1437#ifdef LOG_ENABLED
1438# define RTLOG_SRC_POS_NOREF() do { NOREF(pszFile); NOREF(iLine); NOREF(pszFunction); } while (0)
1439#else
1440# define RTLOG_SRC_POS_NOREF() do { } while (0)
1441#endif
1442/** @} */
1443
1444
1445
1446/** @defgroup grp_rt_log_rel Release Logging
1447 * @{
1448 */
1449
1450#ifdef DOXYGEN_RUNNING
1451# define RTLOG_REL_DISABLED
1452# define RTLOG_REL_ENABLED
1453#endif
1454
1455/** @def RTLOG_REL_DISABLED
1456 * Use this compile time define to disable all release logging
1457 * macros.
1458 */
1459
1460/** @def RTLOG_REL_ENABLED
1461 * Use this compile time define to override RTLOG_REL_DISABLE.
1462 */
1463
1464/*
1465 * Determine whether release logging is enabled and forcefully normalize the indicators.
1466 */
1467#if !defined(RTLOG_REL_DISABLED) || defined(RTLOG_REL_ENABLED)
1468# undef RTLOG_REL_DISABLED
1469# undef RTLOG_REL_ENABLED
1470# define RTLOG_REL_ENABLED
1471#else
1472# undef RTLOG_REL_ENABLED
1473# undef RTLOG_REL_DISABLED
1474# define RTLOG_REL_DISABLED
1475#endif
1476
1477/** @name Macros for checking whether a release log level is enabled.
1478 * @{ */
1479/** @def LogRelIsItEnabled
1480 * Checks whether the specified release logging group is enabled or not.
1481 */
1482#define LogRelIsItEnabled(a_fFlags, a_iGroup) ( RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)) != NULL )
1483
1484/** @def LogRelIsEnabled
1485 * Checks whether level 1 release logging is enabled.
1486 */
1487#define LogRelIsEnabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
1488
1489/** @def LogRelIs2Enabled
1490 * Checks whether level 2 release logging is enabled.
1491 */
1492#define LogRelIs2Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
1493
1494/** @def LogRelIs3Enabled
1495 * Checks whether level 3 release logging is enabled.
1496 */
1497#define LogRelIs3Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
1498
1499/** @def LogRelIs4Enabled
1500 * Checks whether level 4 release logging is enabled.
1501 */
1502#define LogRelIs4Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
1503
1504/** @def LogRelIs5Enabled
1505 * Checks whether level 5 release logging is enabled.
1506 */
1507#define LogRelIs5Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
1508
1509/** @def LogRelIs6Enabled
1510 * Checks whether level 6 release logging is enabled.
1511 */
1512#define LogRelIs6Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
1513
1514/** @def LogRelIs7Enabled
1515 * Checks whether level 7 release logging is enabled.
1516 */
1517#define LogRelIs7Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP)
1518
1519/** @def LogRelIs8Enabled
1520 * Checks whether level 8 release logging is enabled.
1521 */
1522#define LogRelIs8Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP)
1523
1524/** @def LogRelIs2Enabled
1525 * Checks whether level 9 release logging is enabled.
1526 */
1527#define LogRelIs9Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP)
1528
1529/** @def LogRelIs10Enabled
1530 * Checks whether level 10 release logging is enabled.
1531 */
1532#define LogRelIs10Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP)
1533
1534/** @def LogRelIs11Enabled
1535 * Checks whether level 10 release logging is enabled.
1536 */
1537#define LogRelIs11Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP)
1538
1539/** @def LogRelIs12Enabled
1540 * Checks whether level 12 release logging is enabled.
1541 */
1542#define LogRelIs12Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP)
1543
1544/** @def LogRelIsFlowEnabled
1545 * Checks whether execution flow release logging is enabled.
1546 */
1547#define LogRelIsFlowEnabled() LogRelIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
1548
1549/** @def LogRelIsWarnEnabled
1550 * Checks whether warning level release logging is enabled.
1551 */
1552#define LogRelIsWarnEnabled() LogRelIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
1553/** @} */
1554
1555
1556/** @def LogRelIt
1557 * Write to specific logger if group enabled.
1558 */
1559/** @def LogRelItLikely
1560 * Write to specific logger if group enabled, assuming it likely it is enabled.
1561 */
1562/** @def LogRelMaxIt
1563 * Write to specific logger if group enabled and at less than a_cMax messages
1564 * have hit the log. Uses a static variable to count.
1565 */
1566#ifdef RTLOG_REL_ENABLED
1567# if defined(LOG_USE_C99)
1568# define _LogRelRemoveParentheseis(...) __VA_ARGS__
1569# define _LogRelIt(a_fFlags, a_iGroup, ...) \
1570 do \
1571 { \
1572 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1573 if (RT_LIKELY(!LogRelIt_pLogger)) \
1574 { /* likely */ } \
1575 else \
1576 RTLogLoggerExWeak(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
1577 _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
1578 } while (0)
1579# define LogRelIt(a_fFlags, a_iGroup, fmtargs) \
1580 _LogRelIt(a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
1581# define _LogRelItLikely(a_fFlags, a_iGroup, ...) \
1582 do \
1583 { \
1584 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1585 if (LogRelIt_pLogger) \
1586 RTLogLoggerExWeak(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
1587 _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
1588 } while (0)
1589# define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) \
1590 _LogRelItLikely(a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
1591# define _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, ...) \
1592 do \
1593 { \
1594 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1595 if (LogRelIt_pLogger) \
1596 { \
1597 static uint32_t s_LogRelMaxIt_cLogged = 0; \
1598 if (s_LogRelMaxIt_cLogged < (a_cMax)) \
1599 { \
1600 s_LogRelMaxIt_cLogged++; \
1601 RTLogLoggerExWeak(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
1602 } \
1603 } \
1604 _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
1605 } while (0)
1606# define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) \
1607 _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
1608# else
1609# define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) \
1610 do \
1611 { \
1612 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1613 if (LogRelIt_pLogger) \
1614 { \
1615 LogRelIt_pLogger->pfnLogger fmtargs; \
1616 } \
1617 LogIt(a_fFlags, a_iGroup, fmtargs); \
1618 } while (0)
1619# define LogRelIt(a_fFlags, a_iGroup, fmtargs) \
1620 do \
1621 { \
1622 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1623 if (RT_LIKELY(!LogRelIt_pLogger)) \
1624 { /* likely */ } \
1625 else \
1626 { \
1627 LogRelIt_pLogger->pfnLogger fmtargs; \
1628 } \
1629 LogIt(a_fFlags, a_iGroup, fmtargs); \
1630 } while (0)
1631# define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) \
1632 do \
1633 { \
1634 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1635 if (LogRelIt_pLogger) \
1636 { \
1637 static uint32_t s_LogRelMaxIt_cLogged = 0; \
1638 if (s_LogRelMaxIt_cLogged < (a_cMax)) \
1639 { \
1640 s_LogRelMaxIt_cLogged++; \
1641 LogRelIt_pLogger->pfnLogger fmtargs; \
1642 } \
1643 } \
1644 LogIt(a_fFlags, a_iGroup, fmtargs); \
1645 } while (0)
1646# endif
1647#else /* !RTLOG_REL_ENABLED */
1648# define LogRelIt(a_fFlags, a_iGroup, fmtargs) do { } while (0)
1649# define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) do { } while (0)
1650# define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) do { } while (0)
1651# if defined(LOG_USE_C99)
1652# define _LogRelRemoveParentheseis(...) __VA_ARGS__
1653# define _LogRelIt(a_fFlags, a_iGroup, ...) do { } while (0)
1654# define _LogRelItLikely(a_fFlags, a_iGroup, ...) do { } while (0)
1655# define _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, ...) do { } while (0)
1656# endif
1657#endif /* !RTLOG_REL_ENABLED */
1658
1659
1660/** @name Basic release logging macros
1661 * @{ */
1662/** @def LogRel
1663 * Level 1 release logging.
1664 */
1665#define LogRel(a) LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
1666
1667/** @def LogRel2
1668 * Level 2 release logging.
1669 */
1670#define LogRel2(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
1671
1672/** @def LogRel3
1673 * Level 3 release logging.
1674 */
1675#define LogRel3(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
1676
1677/** @def LogRel4
1678 * Level 4 release logging.
1679 */
1680#define LogRel4(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
1681
1682/** @def LogRel5
1683 * Level 5 release logging.
1684 */
1685#define LogRel5(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
1686
1687/** @def LogRel6
1688 * Level 6 release logging.
1689 */
1690#define LogRel6(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
1691
1692/** @def LogRel7
1693 * Level 7 release logging.
1694 */
1695#define LogRel7(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, a)
1696
1697/** @def LogRel8
1698 * Level 8 release logging.
1699 */
1700#define LogRel8(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, a)
1701
1702/** @def LogRel9
1703 * Level 9 release logging.
1704 */
1705#define LogRel9(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, a)
1706
1707/** @def LogRel10
1708 * Level 10 release logging.
1709 */
1710#define LogRel10(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
1711
1712/** @def LogRel11
1713 * Level 11 release logging.
1714 */
1715#define LogRel11(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
1716
1717/** @def LogRel12
1718 * Level 12 release logging.
1719 */
1720#define LogRel12(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
1721
1722/** @def LogRelFlow
1723 * Logging of execution flow.
1724 */
1725#define LogRelFlow(a) LogRelIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
1726
1727/** @def LogRelWarn
1728 * Warning level release logging.
1729 */
1730#define LogRelWarn(a) LogRelIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, a)
1731/** @} */
1732
1733
1734
1735/** @name Basic release logging macros with local max
1736 * @{ */
1737/** @def LogRelMax
1738 * Level 1 release logging with a max number of log entries.
1739 */
1740#define LogRelMax(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
1741
1742/** @def LogRelMax2
1743 * Level 2 release logging with a max number of log entries.
1744 */
1745#define LogRelMax2(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
1746
1747/** @def LogRelMax3
1748 * Level 3 release logging with a max number of log entries.
1749 */
1750#define LogRelMax3(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
1751
1752/** @def LogRelMax4
1753 * Level 4 release logging with a max number of log entries.
1754 */
1755#define LogRelMax4(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
1756
1757/** @def LogRelMax5
1758 * Level 5 release logging with a max number of log entries.
1759 */
1760#define LogRelMax5(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
1761
1762/** @def LogRelMax6
1763 * Level 6 release logging with a max number of log entries.
1764 */
1765#define LogRelMax6(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
1766
1767/** @def LogRelMax7
1768 * Level 7 release logging with a max number of log entries.
1769 */
1770#define LogRelMax7(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, a)
1771
1772/** @def LogRelMax8
1773 * Level 8 release logging with a max number of log entries.
1774 */
1775#define LogRelMax8(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, a)
1776
1777/** @def LogRelMax9
1778 * Level 9 release logging with a max number of log entries.
1779 */
1780#define LogRelMax9(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, a)
1781
1782/** @def LogRelMax10
1783 * Level 10 release logging with a max number of log entries.
1784 */
1785#define LogRelMax10(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
1786
1787/** @def LogRelMax11
1788 * Level 11 release logging with a max number of log entries.
1789 */
1790#define LogRelMax11(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
1791
1792/** @def LogRelMax12
1793 * Level 12 release logging with a max number of log entries.
1794 */
1795#define LogRelMax12(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
1796
1797/** @def LogRelMaxFlow
1798 * Logging of execution flow with a max number of log entries.
1799 */
1800#define LogRelMaxFlow(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
1801/** @} */
1802
1803
1804/** @name Release logging macros prefixing the current function name.
1805 * @{ */
1806
1807/** @def LogRelFunc
1808 * Release logging. Prepends the given log message with the function name
1809 * followed by a semicolon and space.
1810 */
1811#ifdef LOG_USE_C99
1812# define LogRelFunc(a) \
1813 _LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1814#else
1815# define LogRelFunc(a) do { LogRel((LOG_FN_FMT ": ", LOG_FN_NAME)); LogRel(a); } while (0)
1816#endif
1817
1818/** @def LogRelFlowFunc
1819 * Release logging. Macro to log the execution flow inside C/C++ functions.
1820 *
1821 * Prepends the given log message with the function name followed by
1822 * a semicolon and space.
1823 *
1824 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1825 */
1826#ifdef LOG_USE_C99
1827# define LogRelFlowFunc(a) _LogRelIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1828#else
1829# define LogRelFlowFunc(a) do { LogRelFlow((LOG_FN_FMT ": ", LOG_FN_NAME)); LogRelFlow(a); } while (0)
1830#endif
1831
1832/** @def LogRelMaxFunc
1833 * Release logging. Prepends the given log message with the function name
1834 * followed by a semicolon and space.
1835 */
1836#ifdef LOG_USE_C99
1837# define LogRelMaxFunc(a_cMax, a) \
1838 _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1839#else
1840# define LogRelMaxFunc(a_cMax, a) \
1841 do { LogRelMax(a_cMax, (LOG_FN_FMT ": ", LOG_FN_NAME)); LogRelMax(a_cMax, a); } while (0)
1842#endif
1843
1844/** @def LogRelMaxFlowFunc
1845 * Release logging. Macro to log the execution flow inside C/C++ functions.
1846 *
1847 * Prepends the given log message with the function name followed by
1848 * a semicolon and space.
1849 *
1850 * @param a_cMax Max number of times this should hit the log.
1851 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1852 */
1853#ifdef LOG_USE_C99
1854# define LogRelMaxFlowFunc(a_cMax, a) \
1855 _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1856#else
1857# define LogRelMaxFlowFunc(a_cMax, a) \
1858 do { LogRelMaxFlow(a_cMax, (LOG_FN_FMT ": ", LOG_FN_NAME)); LogRelFlow(a_cMax, a); } while (0)
1859#endif
1860
1861/** @} */
1862
1863
1864/** @name Release Logging macros prefixing the this pointer value and method name.
1865 * @{ */
1866
1867/** @def LogRelThisFunc
1868 * The same as LogRelFunc but for class functions (methods): the resulting log
1869 * line is additionally prepended with a hex value of |this| pointer.
1870 */
1871#ifdef LOG_USE_C99
1872# define LogRelThisFunc(a) \
1873 _LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1874#else
1875# define LogRelThisFunc(a) \
1876 do { LogRel(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogRel(a); } while (0)
1877#endif
1878
1879/** @def LogRelMaxThisFunc
1880 * The same as LogRelFunc but for class functions (methods): the resulting log
1881 * line is additionally prepended with a hex value of |this| pointer.
1882 * @param a_cMax Max number of times this should hit the log.
1883 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1884 */
1885#ifdef LOG_USE_C99
1886# define LogRelMaxThisFunc(a_cMax, a) \
1887 _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1888#else
1889# define LogRelMaxThisFunc(a_cMax, a) \
1890 do { LogRelMax(a_cMax, ("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogRelMax(a_cMax, a); } while (0)
1891#endif
1892
1893/** @def LogRelFlowThisFunc
1894 * The same as LogRelFlowFunc but for class functions (methods): the resulting
1895 * log line is additionally prepended with a hex value of |this| pointer.
1896 */
1897#ifdef LOG_USE_C99
1898# define LogRelFlowThisFunc(a) \
1899 _LogRelIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1900#else
1901# define LogRelFlowThisFunc(a) do { LogRelFlow(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogRelFlow(a); } while (0)
1902#endif
1903
1904
1905/** Shortcut to |LogRelFlowFunc ("ENTER\n")|, marks the beginnig of the function. */
1906#define LogRelFlowFuncEnter() LogRelFlowFunc(("ENTER\n"))
1907
1908/** Shortcut to |LogRelFlowFunc ("LEAVE\n")|, marks the end of the function. */
1909#define LogRelFlowFuncLeave() LogRelFlowFunc(("LEAVE\n"))
1910
1911/** Shortcut to |LogRelFlowFunc ("LEAVE: %Rrc\n")|, marks the end of the function. */
1912#define LogRelFlowFuncLeaveRC(rc) LogRelFlowFunc(("LEAVE: %Rrc\n", (rc)))
1913
1914/** Shortcut to |LogRelFlowThisFunc ("ENTER\n")|, marks the beginnig of the function. */
1915#define LogRelFlowThisFuncEnter() LogRelFlowThisFunc(("ENTER\n"))
1916
1917/** Shortcut to |LogRelFlowThisFunc ("LEAVE\n")|, marks the end of the function. */
1918#define LogRelFlowThisFuncLeave() LogRelFlowThisFunc(("LEAVE\n"))
1919
1920/** @} */
1921
1922
1923/**
1924 * Sets the default release logger instance.
1925 *
1926 * @returns The old default instance.
1927 * @param pLogger The new default release logger instance.
1928 */
1929RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger);
1930
1931/**
1932 * Gets the default release logger instance.
1933 *
1934 * @returns Pointer to default release logger instance if availble, otherwise NULL.
1935 */
1936RTDECL(PRTLOGGER) RTLogRelGetDefaultInstance(void);
1937
1938/** @copydoc RTLogRelGetDefaultInstance */
1939typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGRELGETDEFAULTINSTANCE,(void));
1940/** Pointer to RTLogRelGetDefaultInstance. */
1941typedef FNLOGRELGETDEFAULTINSTANCE *PFNLOGRELGETDEFAULTINSTANCE;
1942
1943/** "Weak symbol" emulation for RTLogRelGetDefaultInstance.
1944 * @note This is first set when RTLogRelSetDefaultInstance is called. */
1945extern RTDATADECL(PFNLOGRELGETDEFAULTINSTANCE) g_pfnRTLogRelGetDefaultInstance;
1946
1947/** "Weak symbol" wrapper for RTLogRelGetDefaultInstance. */
1948DECL_FORCE_INLINE(PRTLOGGER) RTLogRelGetDefaultInstanceWeak(void)
1949{
1950#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
1951 if (g_pfnRTLogRelGetDefaultInstance)
1952 return g_pfnRTLogRelGetDefaultInstance();
1953 return NULL;
1954#else
1955 return RTLogRelGetDefaultInstance();
1956#endif
1957}
1958
1959/**
1960 * Gets the default release logger instance.
1961 *
1962 * @returns Pointer to default release logger instance if availble, otherwise NULL.
1963 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
1964 * the high 16 bits.
1965 */
1966RTDECL(PRTLOGGER) RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup);
1967
1968/** @copydoc RTLogRelGetDefaultInstanceEx */
1969typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGRELGETDEFAULTINSTANCEEX,(uint32_t fFlagsAndGroup));
1970/** Pointer to RTLogRelGetDefaultInstanceEx. */
1971typedef FNLOGRELGETDEFAULTINSTANCEEX *PFNLOGRELGETDEFAULTINSTANCEEX;
1972
1973/** "Weak symbol" emulation for RTLogRelGetDefaultInstanceEx.
1974 * @note This is first set when RTLogRelSetDefaultInstance is called. */
1975extern RTDATADECL(PFNLOGRELGETDEFAULTINSTANCEEX) g_pfnRTLogRelGetDefaultInstanceEx;
1976
1977/** "Weak symbol" wrapper for RTLogRelGetDefaultInstanceEx. */
1978DECL_FORCE_INLINE(PRTLOGGER) RTLogRelGetDefaultInstanceExWeak(uint32_t fFlagsAndGroup)
1979{
1980#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
1981 if (g_pfnRTLogRelGetDefaultInstanceEx)
1982 return g_pfnRTLogRelGetDefaultInstanceEx(fFlagsAndGroup);
1983 return NULL;
1984#else
1985 return RTLogRelGetDefaultInstanceEx(fFlagsAndGroup);
1986#endif
1987}
1988
1989
1990/**
1991 * Write to a logger instance, defaulting to the release one.
1992 *
1993 * This function will check whether the instance, group and flags makes up a
1994 * logging kind which is currently enabled before writing anything to the log.
1995 *
1996 * @param pLogger Pointer to logger instance.
1997 * @param fFlags The logging flags.
1998 * @param iGroup The group.
1999 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2000 * only for internal usage!
2001 * @param pszFormat Format string.
2002 * @param ... Format arguments.
2003 * @remark This is a worker function for LogRelIt.
2004 */
2005RTDECL(void) RTLogRelLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2006 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
2007
2008/**
2009 * Write to a logger instance, defaulting to the release one.
2010 *
2011 * This function will check whether the instance, group and flags makes up a
2012 * logging kind which is currently enabled before writing anything to the log.
2013 *
2014 * @param pLogger Pointer to logger instance. If NULL the default release instance is attempted.
2015 * @param fFlags The logging flags.
2016 * @param iGroup The group.
2017 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2018 * only for internal usage!
2019 * @param pszFormat Format string.
2020 * @param args Format arguments.
2021 */
2022RTDECL(void) RTLogRelLoggerV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2023 const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(4, 0);
2024
2025/**
2026 * printf like function for writing to the default release log.
2027 *
2028 * @param pszFormat Printf like format string.
2029 * @param ... Optional arguments as specified in pszFormat.
2030 *
2031 * @remark The API doesn't support formatting of floating point numbers at the moment.
2032 */
2033RTDECL(void) RTLogRelPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2034
2035/**
2036 * vprintf like function for writing to the default release log.
2037 *
2038 * @param pszFormat Printf like format string.
2039 * @param args Optional arguments as specified in pszFormat.
2040 *
2041 * @remark The API doesn't support formatting of floating point numbers at the moment.
2042 */
2043RTDECL(void) RTLogRelPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
2044
2045/**
2046 * Changes the buffering setting of the default release logger.
2047 *
2048 * This can be used for optimizing longish logging sequences.
2049 *
2050 * @returns The old state.
2051 * @param fBuffered The new state.
2052 */
2053RTDECL(bool) RTLogRelSetBuffering(bool fBuffered);
2054
2055/** @} */
2056
2057
2058
2059/** @name COM port logging
2060 * @{
2061 */
2062
2063#ifdef DOXYGEN_RUNNING
2064# define LOG_TO_COM
2065# define LOG_NO_COM
2066#endif
2067
2068/** @def LOG_TO_COM
2069 * Redirects the normal logging macros to the serial versions.
2070 */
2071
2072/** @def LOG_NO_COM
2073 * Disables all LogCom* macros.
2074 */
2075
2076/** @def LogCom
2077 * Generic logging to serial port.
2078 */
2079#if defined(LOG_ENABLED) && !defined(LOG_NO_COM)
2080# define LogCom(a) RTLogComPrintf a
2081#else
2082# define LogCom(a) do { } while (0)
2083#endif
2084
2085/** @def LogComFlow
2086 * Logging to serial port of execution flow.
2087 */
2088#if defined(LOG_ENABLED) && defined(LOG_ENABLE_FLOW) && !defined(LOG_NO_COM)
2089# define LogComFlow(a) RTLogComPrintf a
2090#else
2091# define LogComFlow(a) do { } while (0)
2092#endif
2093
2094#ifdef LOG_TO_COM
2095# undef Log
2096# define Log(a) LogCom(a)
2097# undef LogFlow
2098# define LogFlow(a) LogComFlow(a)
2099#endif
2100
2101/** @} */
2102
2103
2104/** @name Backdoor Logging
2105 * @{
2106 */
2107
2108#ifdef DOXYGEN_RUNNING
2109# define LOG_TO_BACKDOOR
2110# define LOG_NO_BACKDOOR
2111#endif
2112
2113/** @def LOG_TO_BACKDOOR
2114 * Redirects the normal logging macros to the backdoor versions.
2115 */
2116
2117/** @def LOG_NO_BACKDOOR
2118 * Disables all LogBackdoor* macros.
2119 */
2120
2121/** @def LogBackdoor
2122 * Generic logging to the VBox backdoor via port I/O.
2123 */
2124#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
2125# define LogBackdoor(a) RTLogBackdoorPrintf a
2126#else
2127# define LogBackdoor(a) do { } while (0)
2128#endif
2129
2130/** @def LogBackdoorFlow
2131 * Logging of execution flow messages to the backdoor I/O port.
2132 */
2133#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
2134# define LogBackdoorFlow(a) RTLogBackdoorPrintf a
2135#else
2136# define LogBackdoorFlow(a) do { } while (0)
2137#endif
2138
2139/** @def LogRelBackdoor
2140 * Release logging to the VBox backdoor via port I/O.
2141 */
2142#if !defined(LOG_NO_BACKDOOR)
2143# define LogRelBackdoor(a) RTLogBackdoorPrintf a
2144#else
2145# define LogRelBackdoor(a) do { } while (0)
2146#endif
2147
2148#ifdef LOG_TO_BACKDOOR
2149# undef Log
2150# define Log(a) LogBackdoor(a)
2151# undef LogFlow
2152# define LogFlow(a) LogBackdoorFlow(a)
2153# undef LogRel
2154# define LogRel(a) LogRelBackdoor(a)
2155# if defined(LOG_USE_C99)
2156# undef _LogIt
2157# define _LogIt(a_fFlags, a_iGroup, ...) LogBackdoor((__VA_ARGS__))
2158# endif
2159#endif
2160
2161/** @} */
2162
2163
2164
2165/**
2166 * Gets the default logger instance, creating it if necessary.
2167 *
2168 * @returns Pointer to default logger instance if availble, otherwise NULL.
2169 */
2170RTDECL(PRTLOGGER) RTLogDefaultInstance(void);
2171
2172/**
2173 * Gets the logger instance if enabled, creating it if necessary.
2174 *
2175 * @returns Pointer to default logger instance, if group has the specified
2176 * flags enabled. Otherwise NULL is returned.
2177 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
2178 * the high 16 bits.
2179 */
2180RTDECL(PRTLOGGER) RTLogDefaultInstanceEx(uint32_t fFlagsAndGroup);
2181
2182/**
2183 * Gets the default logger instance (does not create one).
2184 *
2185 * @returns Pointer to default logger instance if availble, otherwise NULL.
2186 */
2187RTDECL(PRTLOGGER) RTLogGetDefaultInstance(void);
2188
2189/** @copydoc RTLogGetDefaultInstance */
2190typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGGETDEFAULTINSTANCE,(void));
2191/** Pointer to RTLogGetDefaultInstance. */
2192typedef FNLOGGETDEFAULTINSTANCE *PFNLOGGETDEFAULTINSTANCE;
2193
2194/** "Weak symbol" emulation for RTLogGetDefaultInstance.
2195 * @note This is first set when RTLogSetDefaultInstance is called. */
2196extern RTDATADECL(PFNLOGGETDEFAULTINSTANCE) g_pfnRTLogGetDefaultInstance;
2197
2198/** "Weak symbol" wrapper for RTLogGetDefaultInstance. */
2199DECL_FORCE_INLINE(PRTLOGGER) RTLogGetDefaultInstanceWeak(void)
2200{
2201#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2202 if (g_pfnRTLogGetDefaultInstance)
2203 return g_pfnRTLogGetDefaultInstance();
2204 return NULL;
2205#else
2206 return RTLogGetDefaultInstance();
2207#endif
2208}
2209
2210/**
2211 * Gets the default logger instance if enabled (does not create one).
2212 *
2213 * @returns Pointer to default logger instance, if group has the specified
2214 * flags enabled. Otherwise NULL is returned.
2215 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
2216 * the high 16 bits.
2217 */
2218RTDECL(PRTLOGGER) RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup);
2219
2220/** @copydoc RTLogGetDefaultInstanceEx */
2221typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGGETDEFAULTINSTANCEEX,(uint32_t fFlagsAndGroup));
2222/** Pointer to RTLogGetDefaultInstanceEx. */
2223typedef FNLOGGETDEFAULTINSTANCEEX *PFNLOGGETDEFAULTINSTANCEEX;
2224
2225/** "Weak symbol" emulation for RTLogGetDefaultInstanceEx.
2226 * @note This is first set when RTLogSetDefaultInstance is called. */
2227extern RTDATADECL(PFNLOGGETDEFAULTINSTANCEEX) g_pfnRTLogGetDefaultInstanceEx;
2228
2229/** "Weak symbol" wrapper for RTLogGetDefaultInstanceEx. */
2230DECL_FORCE_INLINE(PRTLOGGER) RTLogGetDefaultInstanceExWeak(uint32_t fFlagsAndGroup)
2231{
2232#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2233 if (g_pfnRTLogGetDefaultInstanceEx)
2234 return g_pfnRTLogGetDefaultInstanceEx(fFlagsAndGroup);
2235 return NULL;
2236#else
2237 return RTLogGetDefaultInstanceEx(fFlagsAndGroup);
2238#endif
2239}
2240
2241/**
2242 * Sets the default logger instance.
2243 *
2244 * @returns The old default instance.
2245 * @param pLogger The new default logger instance.
2246 */
2247RTDECL(PRTLOGGER) RTLogSetDefaultInstance(PRTLOGGER pLogger);
2248
2249#ifdef IN_RING0
2250/**
2251 * Changes the default logger instance for the current thread.
2252 *
2253 * @returns IPRT status code.
2254 * @param pLogger The logger instance. Pass NULL for deregistration.
2255 * @param uKey Associated key for cleanup purposes. If pLogger is NULL,
2256 * all instances with this key will be deregistered. So in
2257 * order to only deregister the instance associated with the
2258 * current thread use 0.
2259 */
2260RTR0DECL(int) RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey);
2261#endif /* IN_RING0 */
2262
2263/**
2264 * Creates the default logger instance for IPRT users.
2265 *
2266 * Any user of the logging features will need to implement
2267 * this or use the generic dummy.
2268 *
2269 * @returns Pointer to the logger instance.
2270 */
2271RTDECL(PRTLOGGER) RTLogDefaultInit(void);
2272
2273/**
2274 * This is the 2nd half of what RTLogGetDefaultInstanceEx() and
2275 * RTLogRelGetDefaultInstanceEx() does.
2276 *
2277 * @returns If the group has the specified flags enabled @a pLogger will be
2278 * returned returned. Otherwise NULL is returned.
2279 * @param pLogger The logger. NULL is NULL.
2280 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
2281 * the high 16 bits.
2282 */
2283RTDECL(PRTLOGGER) RTLogCheckGroupFlags(PRTLOGGER pLogger, uint32_t fFlagsAndGroup);
2284
2285/**
2286 * Create a logger instance.
2287 *
2288 * @returns iprt status code.
2289 *
2290 * @param ppLogger Where to store the logger instance.
2291 * @param fFlags Logger instance flags, a combination of the
2292 * RTLOGFLAGS_* values.
2293 * @param pszGroupSettings The initial group settings.
2294 * @param pszEnvVarBase Base name for the environment variables for
2295 * this instance.
2296 * @param cGroups Number of groups in the array.
2297 * @param papszGroups Pointer to array of groups. This must stick
2298 * around for the life of the logger instance.
2299 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
2300 * if pszFilenameFmt specified.
2301 * @param pszFilenameFmt Log filename format string. Standard
2302 * RTStrFormat().
2303 * @param ... Format arguments.
2304 */
2305RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint64_t fFlags, const char *pszGroupSettings,
2306 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
2307 uint32_t fDestFlags, const char *pszFilenameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(8, 9);
2308
2309/**
2310 * Create a logger instance.
2311 *
2312 * @returns iprt status code.
2313 *
2314 * @param ppLogger Where to store the logger instance.
2315 * @param pszEnvVarBase Base name for the environment variables for
2316 * this instance (ring-3 only).
2317 * @param fFlags Logger instance flags, a combination of the
2318 * RTLOGFLAGS_* values.
2319 * @param pszGroupSettings The initial group settings.
2320 * @param cGroups Number of groups in the array.
2321 * @param papszGroups Pointer to array of groups. This must stick
2322 * around for the life of the logger instance.
2323 * @param cMaxEntriesPerGroup The max number of entries per group. UINT32_MAX
2324 * or zero for unlimited.
2325 * @param cBufDescs Number of buffer descriptors that @a paBufDescs
2326 * points to. Zero for defaults.
2327 * @param paBufDescs Buffer descriptors, optional.
2328 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
2329 * if pszFilenameFmt specified.
2330 * @param pfnPhase Callback function for starting logging and for
2331 * ending or starting a new file for log history
2332 * rotation. NULL is OK.
2333 * @param cHistory Number of old log files to keep when performing
2334 * log history rotation. 0 means no history.
2335 * @param cbHistoryFileMax Maximum size of log file when performing
2336 * history rotation. 0 means no size limit.
2337 * @param cSecsHistoryTimeSlot Maximum time interval per log file when
2338 * performing history rotation, in seconds.
2339 * 0 means time limit.
2340 * @param pOutputIf The optional file output interface, can be NULL which will
2341 * make use of the default one.
2342 * @param pvOutputIfUser The opaque user data to pass to the callbacks in the output interface.
2343 * @param pErrInfo Where to return extended error information.
2344 * Optional.
2345 * @param pszFilenameFmt Log filename format string. Standard RTStrFormat().
2346 * @param ... Format arguments.
2347 */
2348RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings,
2349 unsigned cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
2350 uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags,
2351 PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
2352 PCRTLOGOUTPUTIF pOutputIf, void *pvOutputIfUser,
2353 PRTERRINFO pErrInfo, const char *pszFilenameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(18, 19);
2354
2355/**
2356 * Create a logger instance.
2357 *
2358 * @returns iprt status code.
2359 *
2360 * @param ppLogger Where to store the logger instance.
2361 * @param pszEnvVarBase Base name for the environment variables for
2362 * this instance (ring-3 only).
2363 * @param fFlags Logger instance flags, a combination of the
2364 * RTLOGFLAGS_* values.
2365 * @param pszGroupSettings The initial group settings.
2366 * @param cGroups Number of groups in the array.
2367 * @param papszGroups Pointer to array of groups. This must stick
2368 * around for the life of the logger instance.
2369 * @param cMaxEntriesPerGroup The max number of entries per group. UINT32_MAX
2370 * or zero for unlimited.
2371 * @param cBufDescs Number of buffer descriptors that @a paBufDescs
2372 * points to. Zero for defaults.
2373 * @param paBufDescs Buffer descriptors, optional.
2374 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
2375 * if pszFilenameFmt specified.
2376 * @param pfnPhase Callback function for starting logging and for
2377 * ending or starting a new file for log history
2378 * rotation.
2379 * @param cHistory Number of old log files to keep when performing
2380 * log history rotation. 0 means no history.
2381 * @param cbHistoryFileMax Maximum size of log file when performing
2382 * history rotation. 0 means no size limit.
2383 * @param cSecsHistoryTimeSlot Maximum time interval per log file when
2384 * performing history rotation, in seconds.
2385 * 0 means no time limit.
2386 * @param pOutputIf The optional file output interface, can be NULL which will
2387 * make use of the default one.
2388 * @param pvOutputIfUser The opaque user data to pass to the callbacks in the output interface.
2389 * @param pErrInfo Where to return extended error information.
2390 * Optional.
2391 * @param pszFilenameFmt Log filename format string. Standard
2392 * RTStrFormat().
2393 * @param va Format arguments.
2394 */
2395RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings,
2396 uint32_t cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
2397 uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags,
2398 PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
2399 PCRTLOGOUTPUTIF pOutputIf, void *pvOutputIfUser,
2400 PRTERRINFO pErrInfo, const char *pszFilenameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(18, 0);
2401
2402/**
2403 * Destroys a logger instance.
2404 *
2405 * The instance is flushed and all output destinations closed (where applicable).
2406 *
2407 * @returns iprt status code.
2408 * @param pLogger The logger instance which close destroyed. NULL is fine.
2409 */
2410RTDECL(int) RTLogDestroy(PRTLOGGER pLogger);
2411
2412/**
2413 * Sets the custom prefix callback.
2414 *
2415 * @returns IPRT status code.
2416 * @param pLogger The logger instance.
2417 * @param pfnCallback The callback.
2418 * @param pvUser The user argument for the callback.
2419 * */
2420RTDECL(int) RTLogSetCustomPrefixCallback(PRTLOGGER pLogger, PFNRTLOGPREFIX pfnCallback, void *pvUser);
2421
2422/**
2423 * Sets the custom flush callback.
2424 *
2425 * This can be handy for special loggers like the per-EMT ones in ring-0,
2426 * but also for implementing a log viewer in the debugger GUI.
2427 *
2428 * @returns IPRT status code.
2429 * @retval VWRN_ALREADY_EXISTS if it was set to a different flusher.
2430 * @param pLogger The logger instance.
2431 * @param pfnFlush The flush callback.
2432 */
2433RTDECL(int) RTLogSetFlushCallback(PRTLOGGER pLogger, PFNRTLOGFLUSH pfnFlush);
2434
2435/**
2436 * Sets the thread name for a thread specific ring-0 logger.
2437 *
2438 * @returns IPRT status code.
2439 * @param pLogger The logger. NULL is not allowed.
2440 * @param pszNameFmt The format string for the thread name.
2441 * @param ... Format arguments.
2442 */
2443RTR0DECL(int) RTLogSetR0ThreadNameF(PRTLOGGER pLogger, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(2, 3);
2444
2445/**
2446 * Sets the thread name for a thread specific ring-0 logger.
2447 *
2448 * @returns IPRT status code.
2449 * @param pLogger The logger. NULL is not allowed.
2450 * @param pszNameFmt The format string for the thread name.
2451 * @param va Format arguments.
2452 */
2453RTR0DECL(int) RTLogSetR0ThreadNameV(PRTLOGGER pLogger, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
2454
2455/**
2456 * Sets the program start time for a thread specific ring-0 logger.
2457 *
2458 * @returns IPRT status code.
2459 * @param pLogger The logger. NULL is not allowed.
2460 * @param nsStart The RTTimeNanoTS() value at program start.
2461 */
2462RTR0DECL(int) RTLogSetR0ProgramStart(PRTLOGGER pLogger, uint64_t nsStart);
2463
2464/**
2465 * Get the current log group settings as a string.
2466 *
2467 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2468 * @param pLogger Logger instance (NULL for default logger).
2469 * @param pszBuf The output buffer.
2470 * @param cchBuf The size of the output buffer. Must be greater than
2471 * zero.
2472 */
2473RTDECL(int) RTLogQueryGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
2474
2475/**
2476 * Updates the group settings for the logger instance using the specified
2477 * specification string.
2478 *
2479 * @returns iprt status code.
2480 * Failures can safely be ignored.
2481 * @param pLogger Logger instance (NULL for default logger).
2482 * @param pszValue Value to parse.
2483 */
2484RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue);
2485
2486/**
2487 * Sets the max number of entries per group.
2488 *
2489 * @returns Old restriction.
2490 *
2491 * @param pLogger The logger instance (NULL is an alias for the
2492 * default logger).
2493 * @param cMaxEntriesPerGroup The max number of entries per group.
2494 *
2495 * @remarks Lowering the limit of an active logger may quietly mute groups.
2496 * Raising it may reactive already muted groups.
2497 */
2498RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup);
2499
2500/**
2501 * Gets the current flag settings for the given logger.
2502 *
2503 * @returns Logger flags, UINT64_MAX if no logger.
2504 * @param pLogger Logger instance (NULL for default logger).
2505 */
2506RTDECL(uint64_t) RTLogGetFlags(PRTLOGGER pLogger);
2507
2508/**
2509 * Modifies the flag settings for the given logger.
2510 *
2511 * @returns IPRT status code. Returns VINF_LOG_NO_LOGGER if no default logger
2512 * and @a pLogger is NULL.
2513 * @param pLogger Logger instance (NULL for default logger).
2514 * @param fSet Mask of flags to set (OR).
2515 * @param fClear Mask of flags to clear (NAND). This is allowed to
2516 * include invalid flags - e.g. UINT64_MAX is okay.
2517 */
2518RTDECL(int) RTLogChangeFlags(PRTLOGGER pLogger, uint64_t fSet, uint64_t fClear);
2519
2520/**
2521 * Updates the flags for the logger instance using the specified
2522 * specification string.
2523 *
2524 * @returns iprt status code.
2525 * Failures can safely be ignored.
2526 * @param pLogger Logger instance (NULL for default logger).
2527 * @param pszValue Value to parse.
2528 */
2529RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue);
2530
2531/**
2532 * Changes the buffering setting of the specified logger.
2533 *
2534 * This can be used for optimizing longish logging sequences.
2535 *
2536 * @returns The old state.
2537 * @param pLogger The logger instance (NULL is an alias for the default
2538 * logger).
2539 * @param fBuffered The new state.
2540 */
2541RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered);
2542
2543/**
2544 * Get the current log flags as a string.
2545 *
2546 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2547 * @param pLogger Logger instance (NULL for default logger).
2548 * @param pszBuf The output buffer.
2549 * @param cchBuf The size of the output buffer. Must be greater than
2550 * zero.
2551 */
2552RTDECL(int) RTLogQueryFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
2553
2554/**
2555 * Gets the current destinations flags for the given logger.
2556 *
2557 * @returns Logger destination flags, UINT32_MAX if no logger.
2558 * @param pLogger Logger instance (NULL for default logger).
2559 */
2560RTDECL(uint32_t) RTLogGetDestinations(PRTLOGGER pLogger);
2561
2562/**
2563 * Modifies the log destinations settings for the given logger.
2564 *
2565 * This is only suitable for simple destination settings that doesn't take
2566 * additional arguments, like RTLOGDEST_FILE.
2567 *
2568 * @returns IPRT status code. Returns VINF_LOG_NO_LOGGER if no default logger
2569 * and @a pLogger is NULL.
2570 * @param pLogger Logger instance (NULL for default logger).
2571 * @param fSet Mask of destinations to set (OR).
2572 * @param fClear Mask of destinations to clear (NAND).
2573 */
2574RTDECL(int) RTLogChangeDestinations(PRTLOGGER pLogger, uint32_t fSet, uint32_t fClear);
2575
2576/**
2577 * Updates the logger destination using the specified string.
2578 *
2579 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2580 * @param pLogger Logger instance (NULL for default logger).
2581 * @param pszValue The value to parse.
2582 */
2583RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszValue);
2584
2585/**
2586 * Clear the file delay flag if set, opening the destination and flushing.
2587 *
2588 * @returns IPRT status code.
2589 * @param pLogger Logger instance (NULL for default logger).
2590 * @param pErrInfo Where to return extended error info. Optional.
2591 */
2592RTDECL(int) RTLogClearFileDelayFlag(PRTLOGGER pLogger, PRTERRINFO pErrInfo);
2593
2594/**
2595 * Get the current log destinations as a string.
2596 *
2597 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2598 * @param pLogger Logger instance (NULL for default logger).
2599 * @param pszBuf The output buffer.
2600 * @param cchBuf The size of the output buffer. Must be greater than 0.
2601 */
2602RTDECL(int) RTLogQueryDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
2603
2604/**
2605 * Performs a bulk update of logger flags and group flags.
2606 *
2607 * This is for instanced used for copying settings from ring-3 to ring-0
2608 * loggers.
2609 *
2610 * @returns IPRT status code.
2611 * @param pLogger The logger instance (NULL for default logger).
2612 * @param fFlags The new logger flags.
2613 * @param uGroupCrc32 The CRC32 of the group name strings.
2614 * @param cGroups Number of groups.
2615 * @param pafGroups Array of group flags.
2616 * @sa RTLogQueryBulk
2617 */
2618RTDECL(int) RTLogBulkUpdate(PRTLOGGER pLogger, uint64_t fFlags, uint32_t uGroupCrc32, uint32_t cGroups, uint32_t const *pafGroups);
2619
2620/**
2621 * Queries data for a bulk update of logger flags and group flags.
2622 *
2623 * This is for instanced used for copying settings from ring-3 to ring-0
2624 * loggers.
2625 *
2626 * @returns IPRT status code.
2627 * @retval VERR_BUFFER_OVERFLOW if pafGroups is too small, @a pcGroups will be
2628 * set to the actual number of groups.
2629 * @param pLogger The logger instance (NULL for default logger).
2630 * @param pfFlags Where to return the logger flags.
2631 * @param puGroupCrc32 Where to return the CRC32 of the group names.
2632 * @param pcGroups Input: Size of the @a pafGroups allocation.
2633 * Output: Actual number of groups returned.
2634 * @param pafGroups Where to return the flags for each group.
2635 * @sa RTLogBulkUpdate
2636 */
2637RTDECL(int) RTLogQueryBulk(PRTLOGGER pLogger, uint64_t *pfFlags, uint32_t *puGroupCrc32, uint32_t *pcGroups, uint32_t *pafGroups);
2638
2639/**
2640 * Write/copy bulk log data from another logger.
2641 *
2642 * This is used for transferring stuff from the ring-0 loggers and into the
2643 * ring-3 one. The text goes in as-is w/o any processing (i.e. prefixing or
2644 * newline fun).
2645 *
2646 * @returns IRPT status code.
2647 * @param pLogger The logger instance (NULL for default logger).
2648 * @param pszBefore Text to log before the bulk text. Optional.
2649 * @param pch Pointer to the block of bulk log text to write.
2650 * @param cch Size of the block of bulk log text to write.
2651 * @param pszAfter Text to log after the bulk text. Optional.
2652 */
2653RTDECL(int) RTLogBulkWrite(PRTLOGGER pLogger, const char *pszBefore, const char *pch, size_t cch, const char *pszAfter);
2654
2655/**
2656 * Write/copy bulk log data from a nested VM logger.
2657 *
2658 * This is used for
2659 *
2660 * @returns IRPT status code.
2661 * @param pLogger The logger instance (NULL for default logger).
2662 * @param pch Pointer to the block of bulk log text to write.
2663 * @param cch Size of the block of bulk log text to write.
2664 * @param pszInfix String to put after the line prefixes and the
2665 * line content.
2666 */
2667RTDECL(int) RTLogBulkNestedWrite(PRTLOGGER pLogger, const char *pch, size_t cch, const char *pszInfix);
2668
2669/**
2670 * Flushes the specified logger.
2671 *
2672 * @returns IRPT status code.
2673 * @param pLogger The logger instance to flush.
2674 * If NULL the default instance is used. The default instance
2675 * will not be initialized by this call.
2676 */
2677RTDECL(int) RTLogFlush(PRTLOGGER pLogger);
2678
2679/**
2680 * Write to a logger instance.
2681 *
2682 * @param pLogger Pointer to logger instance.
2683 * @param pvCallerRet Ignored.
2684 * @param pszFormat Format string.
2685 * @param ... Format arguments.
2686 */
2687RTDECL(void) RTLogLogger(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
2688
2689/**
2690 * Write to a logger instance, weak version.
2691 *
2692 * @param pLogger Pointer to logger instance.
2693 * @param pvCallerRet Ignored.
2694 * @param pszFormat Format string.
2695 * @param ... Format arguments.
2696 */
2697#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2698RTDECL(void) RTLogLoggerWeak(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
2699#else /* Cannot use a DECL_FORCE_INLINE because older GCC versions doesn't support inlining va_start. */
2700# undef RTLogLoggerWeak /* in case of mangling */
2701# define RTLogLoggerWeak RTLogLogger
2702#endif
2703
2704/**
2705 * Write to a logger instance.
2706 *
2707 * @param pLogger Pointer to logger instance.
2708 * @param pszFormat Format string.
2709 * @param args Format arguments.
2710 */
2711RTDECL(void) RTLogLoggerV(PRTLOGGER pLogger, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(2, 0);
2712
2713/**
2714 * Write to a logger instance.
2715 *
2716 * This function will check whether the instance, group and flags makes up a
2717 * logging kind which is currently enabled before writing anything to the log.
2718 *
2719 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
2720 * @param fFlags The logging flags.
2721 * @param iGroup The group.
2722 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2723 * only for internal usage!
2724 * @param pszFormat Format string.
2725 * @param ... Format arguments.
2726 * @remark This is a worker function of LogIt.
2727 */
2728RTDECL(void) RTLogLoggerEx(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2729 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
2730
2731/**
2732 * Write to a logger instance, weak version.
2733 *
2734 * This function will check whether the instance, group and flags makes up a
2735 * logging kind which is currently enabled before writing anything to the log.
2736 *
2737 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
2738 * @param fFlags The logging flags.
2739 * @param iGroup The group.
2740 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2741 * only for internal usage!
2742 * @param pszFormat Format string.
2743 * @param ... Format arguments.
2744 * @remark This is a worker function of LogIt.
2745 */
2746#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2747RTDECL(void) RTLogLoggerExWeak(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2748 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
2749#else /* Cannot use a DECL_FORCE_INLINE because older GCC versions doesn't support inlining va_start. */
2750# undef RTLogLoggerExWeak /* in case of mangling */
2751# define RTLogLoggerExWeak RTLogLoggerEx
2752#endif
2753
2754/**
2755 * Write to a logger instance.
2756 *
2757 * This function will check whether the instance, group and flags makes up a
2758 * logging kind which is currently enabled before writing anything to the log.
2759 *
2760 * @returns VINF_SUCCESS, VINF_LOG_NO_LOGGER, VINF_LOG_DISABLED, or IPRT error
2761 * status.
2762 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
2763 * @param fFlags The logging flags.
2764 * @param iGroup The group.
2765 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2766 * only for internal usage!
2767 * @param pszFormat Format string.
2768 * @param args Format arguments.
2769 */
2770RTDECL(int) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2771 const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(4, 0);
2772
2773/** @copydoc RTLogLoggerExV */
2774typedef DECLCALLBACKTYPE(int, FNRTLOGLOGGEREXV,(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2775 const char *pszFormat, va_list args)) RT_IPRT_FORMAT_ATTR(4, 0);
2776/** Pointer to RTLogLoggerExV. */
2777typedef FNRTLOGLOGGEREXV *PFNRTLOGLOGGEREXV;
2778/** "Weak symbol" emulation for RTLogLoggerExV.
2779 * @note This is first set when RTLogCreateEx or RTLogCreate is called. */
2780extern RTDATADECL(PFNRTLOGLOGGEREXV) g_pfnRTLogLoggerExV;
2781
2782/** "Weak symbol" wrapper for RTLogLoggerExV. */
2783DECL_FORCE_INLINE(int) RTLogLoggerExVWeak(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2784 const char *pszFormat, va_list args) /* RT_IPRT_FORMAT_ATTR(4, 0) */
2785{
2786#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2787 if (g_pfnRTLogLoggerExV)
2788 return g_pfnRTLogLoggerExV(pLogger, fFlags, iGroup, pszFormat, args);
2789 return 22301; /* VINF_LOG_DISABLED, don't want err.h dependency here. */
2790#else
2791 return RTLogLoggerExV(pLogger, fFlags, iGroup, pszFormat, args);
2792#endif
2793}
2794
2795/**
2796 * printf like function for writing to the default log.
2797 *
2798 * @param pszFormat Printf like format string.
2799 * @param ... Optional arguments as specified in pszFormat.
2800 *
2801 * @remark The API doesn't support formatting of floating point numbers at the moment.
2802 */
2803RTDECL(void) RTLogPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2804
2805/**
2806 * vprintf like function for writing to the default log.
2807 *
2808 * @param pszFormat Printf like format string.
2809 * @param va Optional arguments as specified in pszFormat.
2810 *
2811 * @remark The API doesn't support formatting of floating point numbers at the moment.
2812 */
2813RTDECL(void) RTLogPrintfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
2814
2815/**
2816 * Dumper vprintf-like function outputting to a logger.
2817 *
2818 * @param pvUser Pointer to the logger instance to use, NULL for default
2819 * instance.
2820 * @param pszFormat Format string.
2821 * @param va Format arguments.
2822 */
2823RTDECL(void) RTLogDumpPrintfV(void *pvUser, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
2824
2825/**
2826 * Used for logging assertions, debug and release log as appropriate.
2827 *
2828 * Implies flushing.
2829 *
2830 * @param pszFormat Format string.
2831 * @param ... Format arguments.
2832 */
2833typedef DECLCALLBACKTYPE(void, FNRTLOGASSERTION,(const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(1, 2);
2834/** Pointer to an assertion logger, ellipsis variant. */
2835typedef FNRTLOGASSERTION *PFNRTLOGASSERTION;
2836
2837/**
2838 * Used for logging assertions, debug and release log as appropriate.
2839 *
2840 * Implies flushing.
2841 *
2842 * @param pszFormat Format string.
2843 * @param va Format arguments.
2844 */
2845typedef DECLCALLBACKTYPE(void, FNRTLOGASSERTIONV,(const char *pszFormat, va_list va)) RT_IPRT_FORMAT_ATTR(1, 0);
2846/** Pointer to an assertion logger, va_list variant. */
2847typedef FNRTLOGASSERTIONV *PFNRTLOGASSERTIONV;
2848
2849/** @copydoc FNRTLOGASSERTION */
2850RTDECL(void) RTLogAssert(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2851/** @copydoc FNRTLOGASSERTIONV */
2852RTDECL(void) RTLogAssertV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
2853
2854/** "Weak symbol" emulation for RTLogAssert. */
2855extern RTDATADECL(PFNRTLOGASSERTION) g_pfnRTLogAssert;
2856/** "Weak symbol" emulation for RTLogAssertV. */
2857extern RTDATADECL(PFNRTLOGASSERTIONV) g_pfnRTLogAssertV;
2858
2859
2860#ifndef DECLARED_FNRTSTROUTPUT /* duplicated in iprt/string.h & iprt/errcore.h */
2861#define DECLARED_FNRTSTROUTPUT
2862/**
2863 * Output callback.
2864 *
2865 * @returns number of bytes written.
2866 * @param pvArg User argument.
2867 * @param pachChars Pointer to an array of utf-8 characters.
2868 * @param cbChars Number of bytes in the character array pointed to by pachChars.
2869 */
2870typedef DECLCALLBACKTYPE(size_t, FNRTSTROUTPUT,(void *pvArg, const char *pachChars, size_t cbChars));
2871/** Pointer to callback function. */
2872typedef FNRTSTROUTPUT *PFNRTSTROUTPUT;
2873#endif
2874
2875/**
2876 * Partial vsprintf worker implementation.
2877 *
2878 * @returns number of bytes formatted.
2879 * @param pfnOutput Output worker.
2880 * Called in two ways. Normally with a string an it's length.
2881 * For termination, it's called with NULL for string, 0 for length.
2882 * @param pvArg Argument to output worker.
2883 * @param pszFormat Format string.
2884 * @param args Argument list.
2885 */
2886RTDECL(size_t) RTLogFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArg, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(3, 0);
2887
2888/**
2889 * Write log buffer to COM port.
2890 *
2891 * @param pach Pointer to the buffer to write.
2892 * @param cb Number of bytes to write.
2893 */
2894RTDECL(void) RTLogWriteCom(const char *pach, size_t cb);
2895
2896/**
2897 * Prints a formatted string to the serial port used for logging.
2898 *
2899 * @returns Number of bytes written.
2900 * @param pszFormat Format string.
2901 * @param ... Optional arguments specified in the format string.
2902 */
2903RTDECL(size_t) RTLogComPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2904
2905/**
2906 * Prints a formatted string to the serial port used for logging.
2907 *
2908 * @returns Number of bytes written.
2909 * @param pszFormat Format string.
2910 * @param args Optional arguments specified in the format string.
2911 */
2912RTDECL(size_t) RTLogComPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
2913
2914/**
2915 * Write log buffer to a debugger (RTLOGDEST_DEBUGGER).
2916 *
2917 * @param pach What to write.
2918 * @param cb How much to write.
2919 * @remark When linking statically, this function can be replaced by defining your own.
2920 */
2921RTDECL(void) RTLogWriteDebugger(const char *pach, size_t cb);
2922
2923/**
2924 * Write log buffer to a user defined output stream (RTLOGDEST_USER).
2925 *
2926 * @param pach What to write.
2927 * @param cb How much to write.
2928 * @remark When linking statically, this function can be replaced by defining your own.
2929 */
2930RTDECL(void) RTLogWriteUser(const char *pach, size_t cb);
2931
2932/**
2933 * Write log buffer to a parent VMM (hypervisor).
2934 *
2935 * @param pach What to write.
2936 * @param cb How much to write.
2937 * @param fRelease Set if targeting the release log, clear if debug log.
2938 *
2939 * @note Currently only available on AMD64 and x86.
2940 */
2941RTDECL(void) RTLogWriteVmm(const char *pach, size_t cb, bool fRelease);
2942
2943/**
2944 * Write log buffer to stdout (RTLOGDEST_STDOUT).
2945 *
2946 * @param pach What to write.
2947 * @param cb How much to write.
2948 * @remark When linking statically, this function can be replaced by defining your own.
2949 */
2950RTDECL(void) RTLogWriteStdOut(const char *pach, size_t cb);
2951
2952/**
2953 * Write log buffer to stdout (RTLOGDEST_STDERR).
2954 *
2955 * @param pach What to write.
2956 * @param cb How much to write.
2957 * @remark When linking statically, this function can be replaced by defining your own.
2958 */
2959RTDECL(void) RTLogWriteStdErr(const char *pach, size_t cb);
2960
2961#ifdef VBOX
2962
2963/**
2964 * Prints a formatted string to the backdoor port.
2965 *
2966 * @returns Number of bytes written.
2967 * @param pszFormat Format string.
2968 * @param ... Optional arguments specified in the format string.
2969 */
2970RTDECL(size_t) RTLogBackdoorPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2971
2972/**
2973 * Prints a formatted string to the backdoor port.
2974 *
2975 * @returns Number of bytes written.
2976 * @param pszFormat Format string.
2977 * @param args Optional arguments specified in the format string.
2978 */
2979RTDECL(size_t) RTLogBackdoorPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
2980
2981#endif /* VBOX */
2982
2983RT_C_DECLS_END
2984
2985/** @} */
2986
2987#endif /* !IPRT_INCLUDED_log_h */
2988
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use