VirtualBox

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

Last change on this file since 97778 was 96811, checked in by vboxsync, 2 years ago

VMM,IPRT,VBoxGuest,SUPDrv: Added a more efficient interface for guest logging using the CPUID instruction. This is mainly intended for development use and not enabled by default. Require updating host drivers.

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