VirtualBox

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

Last change on this file was 106337, checked in by vboxsync, 5 weeks ago

Runtime: Add ACPI table builder API to dynamically generate a DSDT/SSDT, bugref:10733

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

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