VirtualBox

Changeset 90829 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 24, 2021 10:26:07 AM (3 years ago)
Author:
vboxsync
Message:

IPRT,VMM,SUPDrv,++: Reworked the IPRT logger structure and how the VMM ring-0 uses it. bugref:10086

Location:
trunk/src/VBox
Files:
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp

    r90711 r90829  
    567567    /* Create release (or debug) logger (stdout + file). */
    568568    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
     569#ifdef DEBUG /* See below, debug logger not release. */
     570    static const char s_szEnvVarPfx[] = "VBOXTRAY_LOG";
     571    static const char s_szGroupSettings[] = "all.e.l.f";
     572#else
     573    static const char s_szEnvVarPfx[] = "VBOXTRAY_RELEASE_LOG";
     574    static const char s_szGroupSettings[] = "all";
     575#endif
    569576    RTERRINFOSTATIC ErrInfo;
    570     int rc = RTLogCreateEx(&g_pLoggerRelease, RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_USECRLF,
    571 #ifdef DEBUG /* See below, debug logger not release. */
    572                            "all.e.l.f",
    573                            "VBOXTRAY_LOG",
    574 #else
    575                            "all",
    576                            "VBOXTRAY_RELEASE_LOG",
    577 #endif
    578                            RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX, RTLOGDEST_STDOUT,
     577    int rc = RTLogCreateEx(&g_pLoggerRelease, s_szEnvVarPfx,
     578                           RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_USECRLF,
     579                           s_szGroupSettings, RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
     580                           NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT,
    579581                           vboxTrayLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
    580582                           RTErrInfoInitStatic(&ErrInfo), NULL /*pszFilenameFmt*/);
  • trunk/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile

    r83886 r90829  
    101101        strformattype.c \
    102102        strprintf.c \
     103        strprintf2.c \
    103104        strtonum.c \
    104105        memchr.c \
  • trunk/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest

    r83886 r90829  
    137137    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
    138138    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
     139    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf2.cpp=>common/string/strprintf2.c \
    139140    ${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
    140141    ${PATH_ROOT}/src/VBox/Runtime/common/string/memchr.cpp=>common/string/memchr.c \
  • trunk/src/VBox/Additions/common/VBoxGuest/linux/Makefile

    r89957 r90829  
    7373        r0drv/generic/semspinmutex-r0drv-generic.o \
    7474        common/alloc/alloc.o \
     75        common/checksum/crc32.o \
    7576        common/err/RTErrConvertFromErrno.o \
    7677        common/err/RTErrConvertToErrno.o \
     
    107108        common/string/strformattype.o \
    108109        common/string/strprintf.o \
     110        common/string/strprintf2.o \
    109111        common/string/strtonum.o \
    110112        common/string/utf-8.o \
  • trunk/src/VBox/Additions/common/VBoxGuest/linux/combined-agnostic.c

    r83918 r90829  
    5353#undef LOG_GROUP
    5454#include "common/alloc/alloc.c"
     55#undef LOG_GROUP
     56#include "common/checksum/crc32.c"
    5557#undef LOG_GROUP
    5658#include "common/err/errinfo.c"
     
    116118#include "common/string/strprintf.c"
    117119#undef LOG_GROUP
     120#include "common/string/strprintf2.c"
     121#undef LOG_GROUP
    118122#include "common/string/strtonum.c"
    119123#undef LOG_GROUP
  • trunk/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest

    r89957 r90829  
    3838    ${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \
    3939    ${PATH_ROOT}/include/iprt/cpuset.h=>include/iprt/cpuset.h \
     40    ${PATH_ROOT}/include/iprt/crc.h=>include/iprt/crc.h \
    4041    ${PATH_ROOT}/include/iprt/ctype.h=>include/iprt/ctype.h \
    4142    ${PATH_ROOT}/include/iprt/err.h=>include/iprt/err.h \
     
    113114    ${PATH_ROOT}/src/VBox/Runtime/common/alloc/alloc.cpp=>common/alloc/alloc.c \
    114115    ${PATH_ROOT}/src/VBox/Runtime/common/alloc/heapsimple.cpp=>common/alloc/heapsimple.c \
     116    ${PATH_ROOT}/src/VBox/Runtime/common/checksum/crc32.cpp=>common/checksum/crc32.c \
    115117    ${PATH_ROOT}/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp=>common/err/RTErrConvertFromErrno.c \
    116118    ${PATH_ROOT}/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp=>common/err/RTErrConvertToErrno.c \
     
    155157    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
    156158    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
     159    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf2.cpp=>common/string/strprintf2.c \
    157160    ${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
    158161    ${PATH_ROOT}/src/VBox/Runtime/common/string/utf-8.cpp=>common/string/utf-8.c \
  • trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp

    r90707 r90829  
    314314    fFlags |= RTLOGFLAGS_USECRLF;
    315315#endif
    316     int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags, "all", "VBOXSERVICE_RELEASE_LOG",
     316    int rc = RTLogCreateEx(&g_pLoggerRelease, "VBOXSERVICE_RELEASE_LOG", fFlags, "all",
    317317                           RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/,
    318                            RTLOGDEST_STDOUT | RTLOGDEST_USER,
     318                           NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT | RTLOGDEST_USER,
    319319                           vgsvcLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
    320320                           NULL /*pErrInfo*/, "%s", pszLogFile ? pszLogFile : "");
  • trunk/src/VBox/Additions/darwin/VBoxClient/VBoxClient.cpp

    r83716 r90829  
    5959{
    6060    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    61     int rc = RTLogCreateEx(&g_pLogger, RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG, "all", "VBOXCLIENT_RELEASE_LOG",
     61    int rc = RTLogCreateEx(&g_pLogger, "VBOXCLIENT_RELEASE_LOG", RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG, "all",
    6262                           RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/,
    63                            RTLOGDEST_STDOUT,
     63                           NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT,
    6464                           NULL /*pfnPhase*/,
    6565                           pszLogFileName ? 10 : 0 /*cHistory*/,
     
    6767                           pszLogFileName ? RT_SEC_1DAY : 0 /*cSecsHistoryTimeSlot*/,
    6868                           NULL /*pErrInfo*/, "%s", pszLogFileName ? pszLogFileName : "");
    69 
    7069    AssertRCReturn(rc, rc);
    7170
  • trunk/src/VBox/Additions/linux/lightdm-greeter/vbox-greeter.cpp

    r82968 r90829  
    935935    fFlags |= RTLOGFLAGS_USECRLF;
    936936#endif
    937     int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags, "all", "VBOXGREETER_RELEASE_LOG",
    938                            RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/, RTLOGDEST_STDOUT,
     937    int rc = RTLogCreateEx(&g_pLoggerRelease, "VBOXGREETER_RELEASE_LOG", fFlags, "all",
     938                           RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/,
     939                           NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT,
    939940                           vboxGreeterLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
    940941                           NULL /*pErrInfo*/, pszLogFile);
  • trunk/src/VBox/Additions/x11/VBoxClient/logging.cpp

    r90708 r90829  
    263263    fFlags |= RTLOGFLAGS_USECRLF;
    264264#endif
    265     int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags, "all", "VBOXCLIENT_RELEASE_LOG",
     265    int rc = RTLogCreateEx(&g_pLoggerRelease, "VBOXCLIENT_RELEASE_LOG", fFlags, "all",
    266266                           RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/,
    267                            RTLOGDEST_STDOUT | RTLOGDEST_USER,
     267                           NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT | RTLOGDEST_USER,
    268268                           vbClLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
    269269                           NULL /*pErrInfo*/, "%s", pszLogFile ? pszLogFile : "");
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp

    r90780 r90829  
    284284    { "RTHandleTableFreeWithCtx",               (void *)(uintptr_t)RTHandleTableFreeWithCtx },
    285285    { "RTHandleTableLookupWithCtx",             (void *)(uintptr_t)RTHandleTableLookupWithCtx },
     286    { "RTLogBulkUpdate",                        (void *)(uintptr_t)RTLogBulkUpdate},
     287    { "RTLogCheckGroupFlags",                   (void *)(uintptr_t)RTLogCheckGroupFlags },
     288    { "RTLogCreateEx",                          (void *)(uintptr_t)RTLogCreateEx },
     289    { "RTLogDestroy",                           (void *)(uintptr_t)RTLogDestroy },
    286290    { "RTLogDefaultInstance",                   (void *)(uintptr_t)RTLogDefaultInstance },
    287291    { "RTLogDefaultInstanceEx",                 (void *)(uintptr_t)RTLogDefaultInstanceEx },
     
    295299    { "SUPR0GetDefaultLogRelInstanceEx",        (void *)(uintptr_t)SUPR0GetDefaultLogRelInstanceEx },
    296300    { "RTLogSetDefaultInstanceThread",          (void *)(uintptr_t)RTLogSetDefaultInstanceThread },
     301    { "RTLogSetR0ThreadNameF",                  (void *)(uintptr_t)RTLogSetR0ThreadNameF },
    297302    { "RTMemAllocExTag",                        (void *)(uintptr_t)RTMemAllocExTag },
    298303    { "RTMemAllocTag",                          (void *)(uintptr_t)RTMemAllocTag },
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r90489 r90829  
    223223 *          - Remove pvVMMR0 from SUPLDRLOAD.
    224224 */
    225 #define SUPDRV_IOC_VERSION                              0x00300003
     225#define SUPDRV_IOC_VERSION                              0x00300004
    226226
    227227/** SUP_IOCTL_COOKIE. */
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r90780 r90829  
    279279        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    280280        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00300000
    281                                    ? 0x00300003
     281                                   ? 0x00300004
    282282                                   : SUPDRV_IOC_VERSION & 0xffff0000;
    283283        CookieReq.u.In.u32MinVersion = uMinVersion;
  • trunk/src/VBox/HostDrivers/Support/freebsd/Makefile

    r83886 r90829  
    101101        strformattype.c \
    102102        strprintf.c \
     103        strprintf2.c \
    103104        strtonum.c \
    104105        memchr.c \
  • trunk/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv

    r83886 r90829  
    135135    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
    136136    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
     137    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf2.cpp=>common/string/strprintf2.c \
    137138    ${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
    138139    ${PATH_ROOT}/src/VBox/Runtime/common/string/memchr.cpp=>common/string/memchr.c \
  • trunk/src/VBox/HostDrivers/Support/linux/Makefile

    r89961 r90829  
    108108        common/string/strformattype.o \
    109109        common/string/strprintf.o \
     110        common/string/strprintf2.o \
    110111        common/string/strtonum.o \
    111112        common/table/avlpv.o \
  • trunk/src/VBox/HostDrivers/Support/linux/combined-agnostic2.c

    r85523 r90829  
    5454#include "common/string/strprintf.c"
    5555#undef LOG_GROUP
     56#include "common/string/strprintf2.c"
     57#undef LOG_GROUP
    5658#include "common/string/strtonum.c"
    5759#undef LOG_GROUP
  • trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv

    r89961 r90829  
    147147    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
    148148    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
     149    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf2.cpp=>common/string/strprintf2.c \
    149150    ${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
    150151    ${PATH_ROOT}/src/VBox/Runtime/common/table/avlpv.cpp=>common/table/avlpv.c \
  • trunk/src/VBox/Main/glue/VBoxLogRelCreate.cpp

    r82968 r90829  
    169169#endif
    170170    g_pszLogEntity = pcszEntity;
    171     int vrc = RTLogCreateEx(&pReleaseLogger, fFlags, pcszGroupSettings, pcszEnvVarBase,
    172                             RT_ELEMENTS(s_apszGroups), s_apszGroups, cMaxEntriesPerGroup, fDestFlags,
     171    int vrc = RTLogCreateEx(&pReleaseLogger, pcszEnvVarBase, fFlags, pcszGroupSettings, RT_ELEMENTS(s_apszGroups), s_apszGroups,
     172                            cMaxEntriesPerGroup,  NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, fDestFlags,
    173173                            vboxHeaderFooter, cHistory, uHistoryFileSize, uHistoryFileTime,
    174174                            pErrInfo, pcszLogFile ? "%s" : NULL, pcszLogFile);
  • trunk/src/VBox/Main/src-helper-apps/OpenGLTest/OpenGLTestApp.cpp

    r86859 r90829  
    296296    }
    297297
    298     int vrc = RTLogCreateEx(&loggerRelease, fFlags, "all",
    299                             "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX, enmLogDest,
    300                             NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */,
    301                             NULL /* pErrInfo */, pszFilenameFmt, pszFilename, RTTimeMilliTS());
     298
     299    int vrc = RTLogCreateEx(&loggerRelease, "VBOX_RELEASE_LOG", fFlags, "all", RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
     300                            NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, enmLogDest,
     301                            NULL /*pfnBeginEnd*/, 0 /*cHistory*/, 0 /*cbHistoryFileMax*/, 0 /*uHistoryTimeMax*/,
     302                            NULL /*pErrInfo*/, pszFilenameFmt, pszFilename, RTTimeMilliTS());
    302303    if (RT_SUCCESS(vrc))
    303304    {
  • trunk/src/VBox/Runtime/VBox/VBoxRTImp.def

    r90692 r90829  
    12571257    RTLockValidatorWriteLockGetCount
    12581258    RTLockValidatorWriteLockInc
    1259     RTLogCloneRC
    12601259    RTLogComPrintf
    12611260    RTLogComPrintfV
    1262     RTLogCopyGroupsAndFlagsForR0
     1261    ;RTLogCopyGroupsAndFlagsForR0
    12631262    RTLogCreate
    12641263    RTLogCreateEx
    12651264    RTLogCreateExV
    1266     RTLogCreateForR0
    12671265    RTLogDefaultInit
    12681266    RTLogDefaultInstance
     
    12721270    RTLogFlags
    12731271    RTLogFlush
    1274     RTLogFlushRC
    1275     RTLogFlushToLogger
     1272    ;RTLogFlushToLogger
    12761273    RTLogFormatV
    12771274    RTLogGetDefaultInstance
  • trunk/src/VBox/Runtime/VBox/log-vbox.cpp

    r83663 r90829  
    668668        /*RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");*/
    669669        RTLogFlags(pLogger, "enabled unbuffered pid tid");
    670 #  ifndef IN_GUEST
    671         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
    672 #  else
     670        RTLogDestinations(pLogger, "debugger stdout");
     671#  ifdef IN_GUEST
    673672        /*RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");*/
    674673        RTLogGroupSettings(pLogger, "all=~0");
     
    678677        RTLogGroupSettings(pLogger, "+all");
    679678        RTLogFlags(pLogger, "enabled unbuffered");
    680         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
     679        RTLogDestinations(pLogger, "debugger");
    681680# endif
    682681# if defined(DEBUG_ramshankar)  /* Guest ring-0 as well */
    683682        RTLogGroupSettings(pLogger, "+all.e.l.f");
    684683        RTLogFlags(pLogger, "enabled unbuffered");
    685         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
     684        RTLogDestinations(pLogger, "debugger");
    686685# endif
    687686# if defined(DEBUG_aleksey)  /* Guest ring-0 as well */
    688687        RTLogGroupSettings(pLogger, "net_flt_drv.e.l.f.l3.l4.l5.l6 +net_adp_drv.e.l.f.l3.l4.l5.l6");
    689688        RTLogFlags(pLogger, "enabled unbuffered");
    690         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
     689        RTLogDestinations(pLogger, "debugger stdout");
    691690# endif
    692691# if defined(DEBUG_andy)  /* Guest ring-0 as well */
    693692        RTLogGroupSettings(pLogger, "+all.e.l.f");
    694693        RTLogFlags(pLogger, "enabled unbuffered pid tid");
    695         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
     694        RTLogDestinations(pLogger, "debugger stdout");
    696695# endif
    697696# if defined(DEBUG_misha) /* Guest ring-0 as well */
    698697        RTLogFlags(pLogger, "enabled unbuffered");
    699         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
     698        RTLogDestinations(pLogger, "debugger");
    700699# endif
    701700# if defined(DEBUG_michael) && defined(IN_GUEST)
    702701        RTLogGroupSettings(pLogger, "+vga.e.l.f");
    703702        RTLogFlags(pLogger, "enabled unbuffered");
    704         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
     703        RTLogDestinations(pLogger, "debugger stdout");
    705704# endif
    706705# if 0 /* vboxdrv logging - ATTENTION: this is what we're referring to guys! Change to '# if 1'. */
    707706        RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");
    708707        RTLogFlags(pLogger, "enabled unbuffered tid");
    709         pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
     708        RTLogDestinations(pLogger, "debugger stdout");
    710709# endif
    711710    }
  • trunk/src/VBox/Runtime/common/log/log.cpp

    r90803 r90829  
    3434#ifndef IN_RC
    3535# include <iprt/alloc.h>
     36# include <iprt/crc.h>
    3637# include <iprt/process.h>
    3738# include <iprt/semaphore.h>
     
    8990AssertCompile(sizeof(RTLOG_RINGBUF_EYE_CATCHER_END) == 16);
    9091
     92/** The default buffer size. */
     93#define RTLOG_BUFFER_DEFAULT_SIZE       _64K
     94/** Buffer alignment used RTLogCreateExV.   */
     95#define RTLOG_BUFFER_ALIGN              64
     96
    9197
    9298/*********************************************************************************************************************************
     
    94100*********************************************************************************************************************************/
    95101/**
    96  * Arguments passed to the output function.
    97  */
    98 typedef struct RTLOGOUTPUTPREFIXEDARGS
    99 {
    100     /** The logger instance. */
    101     PRTLOGGER               pLogger;
    102     /** The flags. (used for prefixing.) */
    103     unsigned                fFlags;
    104     /** The group. (used for prefixing.) */
    105     unsigned                iGroup;
    106 } RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS;
    107 
    108 #ifndef IN_RC
    109 
    110 /**
    111102 * Internal logger data.
    112103 *
     
    115106typedef struct RTLOGGERINTERNAL
    116107{
     108    /** The public logger core. */
     109    RTLOGGER                Core;
     110
    117111    /** The structure revision (RTLOGGERINTERNAL_REV). */
    118112    uint32_t                uRevision;
    119113    /** The size of the internal logger structure. */
    120114    uint32_t                cbSelf;
     115
     116    /** Logger instance flags - RTLOGFLAGS. */
     117    uint64_t                fFlags;
     118    /** Destination flags - RTLOGDEST. */
     119    uint32_t                fDestFlags;
     120
     121    /** Number of buffer descriptors. */
     122    uint8_t                 cBufDescs;
     123    /** Index of the current buffer descriptor. */
     124    uint8_t                 idxBufDesc;
     125    /** Pointer to buffer the descriptors. */
     126    PRTLOGBUFFERDESC        paBufDescs;
     127    /** Pointer to the current buffer the descriptor. */
     128    PRTLOGBUFFERDESC        pBufDesc;
    121129
    122130    /** Spinning mutex semaphore.  Can be NIL. */
     
    181189    char                    szR0ThreadName[16];
    182190
    183 # ifdef IN_RING3 /* Note! Must be at the end! */
     191#ifdef IN_RING3 /* Note! Must be at the end! */ /** @todo r=bird: figure out why it must be at the end... */
    184192    /** @name File logging bits for the logger.
    185193     * @{ */
     
    205213    char                    szFilename[RTPATH_MAX];
    206214    /** @} */
    207 # endif /* IN_RING3 */
     215#endif /* IN_RING3 */
     216
     217    /** Number of groups in the afGroups and papszGroups members. */
     218    uint32_t                cGroups;
     219    /** Group flags array - RTLOGGRPFLAGS.
     220     * This member have variable length and may extend way beyond
     221     * the declared size of 1 entry. */
     222    RT_FLEXIBLE_ARRAY_EXTENSION
     223    uint32_t                afGroups[RT_FLEXIBLE_ARRAY];
    208224} RTLOGGERINTERNAL;
    209225
    210226/** The revision of the internal logger structure. */
    211 # define RTLOGGERINTERNAL_REV    UINT32_C(11)
    212 
    213 # ifdef IN_RING3
     227# define RTLOGGERINTERNAL_REV    UINT32_C(12)
     228
     229AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbRingBufUnflushed, sizeof(uint64_t));
     230#ifdef IN_RING3
    214231/** The size of the RTLOGGERINTERNAL structure in ring-0.  */
    215 #  define RTLOGGERINTERNAL_R0_SIZE       RT_UOFFSETOF(RTLOGGERINTERNAL, pfnPhase)
     232# define RTLOGGERINTERNAL_R0_SIZE       RT_UOFFSETOF(RTLOGGERINTERNAL, pfnPhase)
    216233AssertCompileMemberAlignment(RTLOGGERINTERNAL, hFile, sizeof(void *));
    217234AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbHistoryFileMax, sizeof(uint64_t));
    218 # endif
    219 AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbRingBufUnflushed, sizeof(uint64_t));
    220 
    221 #endif /* !IN_RC */
     235#endif
     236
     237
     238/** Pointer to internal logger bits. */
     239typedef struct RTLOGGERINTERNAL *PRTLOGGERINTERNAL;
     240/**
     241 * Arguments passed to the output function.
     242 */
     243typedef struct RTLOGOUTPUTPREFIXEDARGS
     244{
     245    /** The logger instance. */
     246    PRTLOGGERINTERNAL       pLoggerInt;
     247    /** The flags. (used for prefixing.) */
     248    unsigned                fFlags;
     249    /** The group. (used for prefixing.) */
     250    unsigned                iGroup;
     251} RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS;
    222252
    223253
     
    233263#endif
    234264#ifdef IN_RING3
    235 static int  rtR3LogOpenFileDestination(PRTLOGGER pLogger, PRTERRINFO pErrInfo);
     265static int  rtR3LogOpenFileDestination(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo);
    236266#endif
    237267#ifndef IN_RC
    238 static void rtLogRingBufFlush(PRTLOGGER pLogger);
     268static void rtLogRingBufFlush(PRTLOGGERINTERNAL pLoggerInt);
    239269#endif
    240 static void rtlogFlush(PRTLOGGER pLogger, bool fNeedSpace);
     270static void rtlogFlush(PRTLOGGERINTERNAL pLoggerInt, bool fNeedSpace);
    241271static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars);
    242 static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars);
    243 static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
     272static void rtlogLoggerExVLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup,
     273                                const char *pszFormat, va_list args);
    244274#ifndef IN_RC
    245 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
     275static void rtlogLoggerExFLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
    246276#endif
    247277
     
    250280*   Global Variables                                                                                                             *
    251281*********************************************************************************************************************************/
    252 #ifdef IN_RC
     282#ifndef IN_RC
     283/** Default logger instance. */
     284static PRTLOGGER                    g_pLogger;
     285/** Default release logger instance. */
     286static PRTLOGGER                    g_pRelLogger;
     287#else
    253288/** Default logger instance. Make it weak because our RC module loader does not
    254289 *  necessarily resolve this symbol and the compiler _must_ check if this is
     
    256291 *  .weak_reference (must specify "-dynamic" to be used'') */
    257292# ifdef RT_OS_DARWIN
    258 extern "C" DECLIMPORT(RTLOGGERRC) g_Logger;
     293extern "C" DECLIMPORT(RTLOGGERRC)   g_Logger;
     294/** Default release logger instance. */
     295extern "C" DECLIMPORT(RTLOGGERRC)   g_RelLogger;
    259296# else
    260297extern "C" DECLWEAK(DECLIMPORT(RTLOGGERRC)) g_Logger;
     298/** Default release logger instance. */
     299extern "C" DECLWEAK(DECLIMPORT(RTLOGGERRC)) g_RelLogger;
    261300# endif
    262 #else /* !IN_RC */
    263 /** Default logger instance. */
    264 static PRTLOGGER                    g_pLogger;
    265 #endif /* !IN_RC */
     301#endif /* IN_RC */
    266302#ifdef IN_RING3
    267303/** The RTThreadGetWriteLockCount() change caused by the logger mutex semaphore. */
     
    303339    const char *pszInstr;               /**< The name  */
    304340    size_t      cchInstr;               /**< The size of the name. */
    305     uint32_t    fFlag;                  /**< The flag value. */
     341    uint64_t    fFlag;                  /**< The flag value. */
    306342    bool        fInverted;              /**< Inverse meaning? */
    307343    uint32_t    fFixedDest;             /**< RTLOGDEST_FIXED_XXX flags blocking this. */
     
    381417 *
    382418 * @returns See RTSemSpinMutexRequest().
    383  * @param   pLogger     The logger instance.
    384  */
    385 DECLINLINE(int) rtlogLock(PRTLOGGER pLogger)
     419 * @param   pLoggerInt  The logger instance.
     420 */
     421DECLINLINE(int) rtlogLock(PRTLOGGERINTERNAL pLoggerInt)
    386422{
    387423#ifndef IN_RC
    388     PRTLOGGERINTERNAL pInt = pLogger->pInt;
    389     AssertMsgReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pInt->uRevision, RTLOGGERINTERNAL_REV),
     424    AssertMsgReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, ("%#x != %#x\n", pLoggerInt->Core.u32Magic, RTLOGGER_MAGIC),
     425                    VERR_INVALID_MAGIC);
     426    AssertMsgReturn(pLoggerInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pLoggerInt->uRevision, RTLOGGERINTERNAL_REV),
    390427                    VERR_LOG_REVISION_MISMATCH);
    391     AssertMsgReturn(pInt->cbSelf == sizeof(*pInt), ("%#x != %#x\n", pInt->cbSelf, sizeof(*pInt)),
     428    AssertMsgReturn(pLoggerInt->cbSelf == sizeof(*pLoggerInt), ("%#x != %#x\n", pLoggerInt->cbSelf, sizeof(*pLoggerInt)),
    392429                    VERR_LOG_REVISION_MISMATCH);
    393     if (pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
    394     {
    395         int rc = RTSemSpinMutexRequest(pInt->hSpinMtx);
     430    if (pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
     431    {
     432        int rc = RTSemSpinMutexRequest(pLoggerInt->hSpinMtx);
    396433        if (RT_FAILURE(rc))
    397434            return rc;
    398435    }
    399436#else
    400     NOREF(pLogger);
     437    NOREF(pLoggerInt);
    401438#endif
    402439    return VINF_SUCCESS;
     
    406443/**
    407444 * Unlocks the logger instance.
    408  * @param   pLogger     The logger instance.
    409  */
    410 DECLINLINE(void) rtlogUnlock(PRTLOGGER pLogger)
     445 * @param   pLoggerInt  The logger instance.
     446 */
     447DECLINLINE(void) rtlogUnlock(PRTLOGGERINTERNAL pLoggerInt)
    411448{
    412449#ifndef IN_RC
    413     if (pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
    414         RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
     450    if (pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
     451        RTSemSpinMutexRelease(pLoggerInt->hSpinMtx);
    415452#else
    416     NOREF(pLogger);
     453    NOREF(pLoggerInt);
    417454#endif
    418455    return;
     
    432469static DECLCALLBACK(size_t) rtlogPhaseWrite(void *pvArg, const char *pachChars, size_t cbChars)
    433470{
    434     PRTLOGGER pLogger = (PRTLOGGER)pvArg;
    435     RTFileWrite(pLogger->pInt->hFile, pachChars, cbChars, NULL);
     471    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pvArg;
     472    RTFileWrite(pLoggerInt->hFile, pachChars, cbChars, NULL);
    436473    return cbChars;
    437474}
     
    477514static DECLCALLBACK(void) rtlogPhaseMsgLocked(PRTLOGGER pLogger, const char *pszFormat, ...)
    478515{
     516    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     517    AssertPtrReturnVoid(pLoggerInt);
     518    Assert(pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
     519
    479520    va_list args;
    480     AssertPtrReturnVoid(pLogger);
    481     AssertPtrReturnVoid(pLogger->pInt);
    482     Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
    483 
    484521    va_start(args, pszFormat);
    485     rtlogLoggerExVLocked(pLogger, 0, ~0U, pszFormat, args);
     522    rtlogLoggerExVLocked(pLoggerInt, 0, ~0U, pszFormat, args);
    486523    va_end(args);
    487524}
     
    497534static DECLCALLBACK(void) rtlogPhaseMsgNormal(PRTLOGGER pLogger, const char *pszFormat, ...)
    498535{
     536    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     537    AssertPtrReturnVoid(pLoggerInt);
     538    Assert(pLoggerInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
     539
    499540    va_list args;
    500     AssertPtrReturnVoid(pLogger);
    501     AssertPtrReturnVoid(pLogger->pInt);
    502     Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
    503 
    504541    va_start(args, pszFormat);
    505     RTLogLoggerExV(pLogger, 0, ~0U, pszFormat, args);
     542    RTLogLoggerExV(&pLoggerInt->Core, 0, ~0U, pszFormat, args);
    506543    va_end(args);
    507544}
     
    513550 *
    514551 * @returns IPRT status code.
    515  * @param   pLogger     The logger instance.
     552 * @param   pLoggerInt  The logger instance.
    516553 * @param   cbNewSize   The new ring buffer size (0 == default).
    517554 * @param   fForce      Whether to do this even if the logger instance hasn't
    518555 *                      really been fully created yet (i.e. during RTLogCreate).
    519556 */
    520 static int rtLogRingBufAdjust(PRTLOGGER pLogger, uint32_t cbNewSize, bool fForce)
     557static int rtLogRingBufAdjust(PRTLOGGERINTERNAL pLoggerInt, uint32_t cbNewSize, bool fForce)
    521558{
    522559    /*
    523560     * If this is early logger init, don't do anything.
    524561     */
    525     if (!pLogger->pInt->fCreated && !fForce)
     562    if (!pLoggerInt->fCreated && !fForce)
    526563        return VINF_SUCCESS;
    527564
     
    529566     * Lock the logger and make the necessary changes.
    530567     */
    531     int rc = rtlogLock(pLogger);
     568    int rc = rtlogLock(pLoggerInt);
    532569    if (RT_SUCCESS(rc))
    533570    {
    534571        if (cbNewSize == 0)
    535572            cbNewSize = RTLOG_RINGBUF_DEFAULT_SIZE;
    536         if (   pLogger->pInt->cbRingBuf != cbNewSize
    537             || !pLogger->pInt->pchRingBufCur)
    538         {
    539             uintptr_t offOld = pLogger->pInt->pchRingBufCur - pLogger->pInt->pszRingBuf;
     573        if (   pLoggerInt->cbRingBuf != cbNewSize
     574            || !pLoggerInt->pchRingBufCur)
     575        {
     576            uintptr_t offOld = pLoggerInt->pchRingBufCur - pLoggerInt->pszRingBuf;
    540577            if (offOld < sizeof(RTLOG_RINGBUF_EYE_CATCHER))
    541578                offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER);
    542579            else if (offOld >= cbNewSize)
    543580            {
    544                 memmove(pLogger->pInt->pszRingBuf, &pLogger->pInt->pszRingBuf[offOld - cbNewSize], cbNewSize);
     581                memmove(pLoggerInt->pszRingBuf, &pLoggerInt->pszRingBuf[offOld - cbNewSize], cbNewSize);
    545582                offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER);
    546583            }
    547584
    548             void *pvNew = RTMemRealloc(pLogger->pInt->pchRingBufCur, cbNewSize);
     585            void *pvNew = RTMemRealloc(pLoggerInt->pchRingBufCur, cbNewSize);
    549586            if (pvNew)
    550587            {
    551                 pLogger->pInt->pszRingBuf    = (char *)pvNew;
    552                 pLogger->pInt->pchRingBufCur = (char *)pvNew + offOld;
    553                 pLogger->pInt->cbRingBuf     = cbNewSize;
     588                pLoggerInt->pszRingBuf    = (char *)pvNew;
     589                pLoggerInt->pchRingBufCur = (char *)pvNew + offOld;
     590                pLoggerInt->cbRingBuf     = cbNewSize;
    554591                memcpy(pvNew, RTLOG_RINGBUF_EYE_CATCHER, sizeof(RTLOG_RINGBUF_EYE_CATCHER));
    555592                memcpy((char *)pvNew + cbNewSize - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END),
     
    560597                rc = VERR_NO_MEMORY;
    561598        }
    562         rtlogUnlock(pLogger);
     599        rtlogUnlock(pLoggerInt);
    563600    }
    564601
     
    642679 * Flushes the ring buffer to all the other log destinations.
    643680 *
    644  * @param   pLogger     The logger instance which ring buffer should be flushed.
    645  */
    646 static void rtLogRingBufFlush(PRTLOGGER pLogger)
     681 * @param   pLoggerInt  The logger instance which ring buffer should be flushed.
     682 */
     683static void rtLogRingBufFlush(PRTLOGGERINTERNAL pLoggerInt)
    647684{
    648685    const char  *pszPreamble;
     
    657694     * part of the buffer.
    658695     */
    659     uint64_t     cchUnflushed = pLogger->pInt->cbRingBufUnflushed;
    660     char * const pszBuf   = &pLogger->pInt->pszRingBuf[sizeof(RTLOG_RINGBUF_EYE_CATCHER)];
    661     size_t const cchBuf   = pLogger->pInt->cbRingBuf - sizeof(RTLOG_RINGBUF_EYE_CATCHER) - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END);
    662     size_t       offCur   = pLogger->pInt->pchRingBufCur - pszBuf;
     696    uint64_t     cchUnflushed = pLoggerInt->cbRingBufUnflushed;
     697    char * const pszBuf   = &pLoggerInt->pszRingBuf[sizeof(RTLOG_RINGBUF_EYE_CATCHER)];
     698    size_t const cchBuf   = pLoggerInt->cbRingBuf - sizeof(RTLOG_RINGBUF_EYE_CATCHER) - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END);
     699    size_t       offCur   = pLoggerInt->pchRingBufCur - pszBuf;
    663700    size_t       cchAfter;
    664701    if (RT_LIKELY(offCur < cchBuf))
     
    670707    }
    671708
    672     pLogger->pInt->cbRingBufUnflushed = 0;
     709    pLoggerInt->cbRingBufUnflushed = 0;
    673710
    674711    /*
     
    711748     * Write the ring buffer to all other destiations.
    712749     */
    713     if (pLogger->fDestFlags & RTLOGDEST_USER)
     750    if (pLoggerInt->fDestFlags & RTLOGDEST_USER)
    714751    {
    715752        if (cchPreamble)
     
    721758    }
    722759
    723     if (pLogger->fDestFlags & RTLOGDEST_DEBUGGER)
     760    if (pLoggerInt->fDestFlags & RTLOGDEST_DEBUGGER)
    724761    {
    725762        if (cchPreamble)
     
    732769
    733770# ifdef IN_RING3
    734     if (pLogger->fDestFlags & RTLOGDEST_FILE)
    735     {
    736         if (pLogger->pInt->hFile != NIL_RTFILE)
     771    if (pLoggerInt->fDestFlags & RTLOGDEST_FILE)
     772    {
     773        if (pLoggerInt->hFile != NIL_RTFILE)
    737774        {
    738775            if (cchPreamble)
    739                 RTFileWrite(pLogger->pInt->hFile, pszPreamble, cchPreamble, NULL);
     776                RTFileWrite(pLoggerInt->hFile, pszPreamble, cchPreamble, NULL);
    740777            if (cchFirst)
    741                 RTFileWrite(pLogger->pInt->hFile, pszFirst, cchFirst, NULL);
     778                RTFileWrite(pLoggerInt->hFile, pszFirst, cchFirst, NULL);
    742779            if (cchSecond)
    743                 RTFileWrite(pLogger->pInt->hFile, pszSecond, cchSecond, NULL);
    744             if (pLogger->fFlags & RTLOGFLAGS_FLUSH)
    745                 RTFileFlush(pLogger->pInt->hFile);
    746         }
    747         if (pLogger->pInt->cHistory)
    748             pLogger->pInt->cbHistoryFileWritten += cchFirst + cchSecond;
     780                RTFileWrite(pLoggerInt->hFile, pszSecond, cchSecond, NULL);
     781            if (pLoggerInt->fFlags & RTLOGFLAGS_FLUSH)
     782                RTFileFlush(pLoggerInt->hFile);
     783        }
     784        if (pLoggerInt->cHistory)
     785            pLoggerInt->cbHistoryFileWritten += cchFirst + cchSecond;
    749786    }
    750787# endif
    751788
    752     if (pLogger->fDestFlags & RTLOGDEST_STDOUT)
     789    if (pLoggerInt->fDestFlags & RTLOGDEST_STDOUT)
    753790    {
    754791        if (cchPreamble)
     
    760797    }
    761798
    762     if (pLogger->fDestFlags & RTLOGDEST_STDERR)
     799    if (pLoggerInt->fDestFlags & RTLOGDEST_STDERR)
    763800    {
    764801        if (cchPreamble)
     
    771808
    772809# if defined(IN_RING0) && !defined(LOG_NO_COM)
    773     if (pLogger->fDestFlags & RTLOGDEST_COM)
     810    if (pLoggerInt->fDestFlags & RTLOGDEST_COM)
    774811    {
    775812        if (cchPreamble)
     
    784821
    785822
    786 RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, const char *pszEnvVarBase,
    787                            unsigned cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
    788                            uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
    789                            uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
     823RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings,
     824                           uint32_t cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
     825                           PFNRTLOGFLUSH pfnFlush, uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags,
     826                           PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
    790827                           PRTERRINFO pErrInfo, const char *pszFilenameFmt, va_list args)
    791828{
    792     int         rc;
    793     size_t      offInternal;
    794     size_t      cbLogger;
    795     PRTLOGGER   pLogger;
     829    int                 rc;
     830    size_t              cbLogger;
     831    size_t              offBuffers;
     832    PRTLOGGERINTERNAL   pLoggerInt;
     833    uint32_t            i;
    796834
    797835    /*
    798836     * Validate input.
    799837     */
    800     if (   (cGroups && !papszGroups)
    801         || !RT_VALID_PTR(ppLogger) )
    802     {
    803         AssertMsgFailed(("Invalid parameters!\n"));
    804         return VERR_INVALID_PARAMETER;
    805     }
     838    AssertPtrReturn(ppLogger, VERR_INVALID_POINTER);
    806839    *ppLogger = NULL;
    807 
     840    if (cGroups)
     841    {
     842        AssertPtrReturn(papszGroups, VERR_INVALID_POINTER);
     843        AssertReturn(cGroups < _8K, VERR_OUT_OF_RANGE);
     844    }
    808845    AssertMsgReturn(cHistory < _1M, ("%#x", cHistory), VERR_OUT_OF_RANGE);
    809 
    810     /*
    811      * Allocate a logger instance.
    812      */
    813     offInternal = RT_UOFFSETOF_DYN(RTLOGGER, afGroups[cGroups]);
    814     offInternal = RT_ALIGN_Z(offInternal, sizeof(uint64_t));
    815     cbLogger = offInternal + sizeof(RTLOGGERINTERNAL);
     846    AssertReturn(cBufDescs <= 128, VERR_OUT_OF_RANGE);
     847
     848    /*
     849     * Calculate the logger size.
     850     */
     851    AssertCompileSize(RTLOGGER, 32);
     852    cbLogger = RT_UOFFSETOF_DYN(RTLOGGERINTERNAL, afGroups[cGroups]);
    816853    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
    817854        cbLogger += cGroups * sizeof(uint32_t);
    818     pLogger = (PRTLOGGER)RTMemAllocZVarTag(cbLogger, "may-leak:log-instance");
    819     if (pLogger)
     855    if (cBufDescs == 0)
     856    {
     857        /* Allocate one buffer descriptor and a default sized buffer. */
     858        cbLogger   = RT_ALIGN_Z(cbLogger, RTLOG_BUFFER_ALIGN);
     859        offBuffers = cbLogger;
     860        cbLogger  += RT_ALIGN_Z(sizeof(paBufDescs[0]), RTLOG_BUFFER_ALIGN) + RTLOG_BUFFER_DEFAULT_SIZE;
     861    }
     862    else
     863    {
     864        /* Caller-supplied buffer descriptors.  If pchBuf is NULL, we have to allocate the buffers. */
     865        AssertPtrReturn(paBufDescs, VERR_INVALID_POINTER);
     866        if (paBufDescs[0].pchBuf != NULL)
     867            offBuffers = 0;
     868        else
     869        {
     870            cbLogger = RT_ALIGN_Z(cbLogger, RTLOG_BUFFER_ALIGN);
     871            offBuffers = cbLogger;
     872        }
     873
     874        for (i = 0; i < cBufDescs; i++)
     875        {
     876            AssertReturn(paBufDescs[i].u32Magic == RTLOGBUFFERDESC_MAGIC, VERR_INVALID_MAGIC);
     877            AssertReturn(paBufDescs[i].uReserved == 0, VERR_INVALID_PARAMETER);
     878            AssertMsgReturn(paBufDescs[i].cbBuf >= _1K && paBufDescs[i].cbBuf <= _64M,
     879                            ("paBufDesc[%u].cbBuf=%#x\n", i, paBufDescs[i].cbBuf), VERR_OUT_OF_RANGE);
     880            AssertReturn(paBufDescs[i].offBuf == 0, VERR_INVALID_PARAMETER);
     881            if (offBuffers != 0)
     882            {
     883                cbLogger += RT_ALIGN_Z(paBufDescs[i].cbBuf, RTLOG_BUFFER_ALIGN);
     884                AssertReturn(paBufDescs[i].pchBuf == NULL, VERR_INVALID_PARAMETER);
     885                AssertReturn(paBufDescs[i].pAux == NULL, VERR_INVALID_PARAMETER);
     886            }
     887            else
     888            {
     889                AssertPtrReturn(paBufDescs[i].pchBuf, VERR_INVALID_POINTER);
     890                AssertPtrNullReturn(paBufDescs[i].pAux, VERR_INVALID_POINTER);
     891            }
     892        }
     893    }
     894
     895    /*
     896     * Allocate a logger instance.
     897     */
     898    pLoggerInt = (PRTLOGGERINTERNAL)RTMemAllocZVarTag(cbLogger, "may-leak:log-instance");
     899    if (pLoggerInt)
    820900    {
    821901# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
    822902        uint8_t *pu8Code;
    823903# endif
    824         pLogger->u32Magic       = RTLOGGER_MAGIC;
    825         pLogger->cGroups        = cGroups;
    826         pLogger->fFlags         = fFlags;
    827         pLogger->fDestFlags     = fDestFlags;
    828         pLogger->pInt           = (PRTLOGGERINTERNAL)((uintptr_t)pLogger + offInternal);
    829         pLogger->pInt->uRevision                = RTLOGGERINTERNAL_REV;
    830         pLogger->pInt->cbSelf                   = sizeof(RTLOGGERINTERNAL);
    831         pLogger->pInt->hSpinMtx                 = NIL_RTSEMSPINMUTEX;
    832         pLogger->pInt->pfnFlush                 = NULL;
    833         pLogger->pInt->pfnPrefix                = NULL;
    834         pLogger->pInt->pvPrefixUserArg          = NULL;
    835         pLogger->pInt->fPendingPrefix           = true;
    836         pLogger->pInt->fCreated                 = false;
    837         pLogger->pInt->nsR0ProgramStart         = 0;
    838         RT_ZERO(pLogger->pInt->szR0ThreadName);
    839         pLogger->pInt->cMaxGroups               = cGroups;
    840         pLogger->pInt->papszGroups              = papszGroups;
     904        pLoggerInt->Core.u32Magic               = RTLOGGER_MAGIC;
     905        pLoggerInt->cGroups                     = cGroups;
     906        pLoggerInt->fFlags                      = fFlags;
     907        pLoggerInt->fDestFlags                  = fDestFlags;
     908        pLoggerInt->uRevision                   = RTLOGGERINTERNAL_REV;
     909        pLoggerInt->cbSelf                      = sizeof(RTLOGGERINTERNAL);
     910        pLoggerInt->hSpinMtx                    = NIL_RTSEMSPINMUTEX;
     911        pLoggerInt->pfnFlush                    = pfnFlush;
     912        pLoggerInt->pfnPrefix                   = NULL;
     913        pLoggerInt->pvPrefixUserArg             = NULL;
     914        pLoggerInt->fPendingPrefix              = true;
     915        pLoggerInt->fCreated                    = false;
     916        pLoggerInt->nsR0ProgramStart            = 0;
     917        RT_ZERO(pLoggerInt->szR0ThreadName);
     918        pLoggerInt->cMaxGroups                  = cGroups;
     919        pLoggerInt->papszGroups                 = papszGroups;
    841920        if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
    842             pLogger->pInt->pacEntriesPerGroup   = (uint32_t *)(pLogger->pInt + 1);
     921            pLoggerInt->pacEntriesPerGroup      = (uint32_t *)(pLoggerInt + 1);
    843922        else
    844             pLogger->pInt->pacEntriesPerGroup   = NULL;
    845         pLogger->pInt->cMaxEntriesPerGroup      = cMaxEntriesPerGroup ? cMaxEntriesPerGroup : UINT32_MAX;
     923            pLoggerInt->pacEntriesPerGroup      = NULL;
     924        pLoggerInt->cMaxEntriesPerGroup         = cMaxEntriesPerGroup ? cMaxEntriesPerGroup : UINT32_MAX;
    846925# ifdef IN_RING3
    847         pLogger->pInt->pfnPhase                 = pfnPhase;
    848         pLogger->pInt->hFile                    = NIL_RTFILE;
    849         pLogger->pInt->cHistory                 = cHistory;
     926        pLoggerInt->pfnPhase                    = pfnPhase;
     927        pLoggerInt->hFile                       = NIL_RTFILE;
     928        pLoggerInt->cHistory                    = cHistory;
    850929        if (cbHistoryFileMax == 0)
    851             pLogger->pInt->cbHistoryFileMax     = UINT64_MAX;
     930            pLoggerInt->cbHistoryFileMax        = UINT64_MAX;
    852931        else
    853             pLogger->pInt->cbHistoryFileMax     = cbHistoryFileMax;
     932            pLoggerInt->cbHistoryFileMax        = cbHistoryFileMax;
    854933        if (cSecsHistoryTimeSlot == 0)
    855             pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
     934            pLoggerInt->cSecsHistoryTimeSlot    = UINT32_MAX;
    856935        else
    857             pLogger->pInt->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot;
     936            pLoggerInt->cSecsHistoryTimeSlot    = cSecsHistoryTimeSlot;
    858937# else   /* !IN_RING3 */
    859938        RT_NOREF_PV(pfnPhase); RT_NOREF_PV(cHistory); RT_NOREF_PV(cbHistoryFileMax); RT_NOREF_PV(cSecsHistoryTimeSlot);
    860939# endif  /* !IN_RING3 */
    861940        if (pszGroupSettings)
    862             RTLogGroupSettings(pLogger, pszGroupSettings);
     941            RTLogGroupSettings(&pLoggerInt->Core, pszGroupSettings);
     942
     943        /*
     944         * Buffer descriptors.
     945         */
     946        if (!offBuffers)
     947        {
     948            /* Caller-supplied descriptors: */
     949            pLoggerInt->cBufDescs  = cBufDescs;
     950            pLoggerInt->paBufDescs = paBufDescs;
     951        }
     952        else if (cBufDescs)
     953        {
     954            /* Caller-supplied descriptors, but we allocate the actual buffers: */
     955            pLoggerInt->cBufDescs  = cBufDescs;
     956            pLoggerInt->paBufDescs = paBufDescs;
     957            for (i = 0; i < cBufDescs; i++)
     958            {
     959                paBufDescs[i].pchBuf = (char *)pLoggerInt + offBuffers;
     960                offBuffers = RT_ALIGN_Z(offBuffers + paBufDescs[i].cbBuf, RTLOG_BUFFER_ALIGN);
     961            }
     962            Assert(offBuffers == cbLogger);
     963        }
     964        else
     965        {
     966            /* One descriptor with a default sized buffer. */
     967            pLoggerInt->cBufDescs  = cBufDescs  = 1;
     968            pLoggerInt->paBufDescs = paBufDescs = (PRTLOGBUFFERDESC)((char *)(char *)pLoggerInt + offBuffers);
     969            offBuffers = RT_ALIGN_Z(offBuffers + sizeof(paBufDescs[0]) * cBufDescs, RTLOG_BUFFER_ALIGN);
     970            for (i = 0; i < cBufDescs; i++)
     971            {
     972                paBufDescs[i].u32Magic  = RTLOGBUFFERDESC_MAGIC;
     973                paBufDescs[i].uReserved = 0;
     974                paBufDescs[i].cbBuf     = RTLOG_BUFFER_DEFAULT_SIZE;
     975                paBufDescs[i].offBuf    = 0;
     976                paBufDescs[i].pAux      = NULL;
     977                paBufDescs[i].pchBuf    = (char *)pLoggerInt + offBuffers;
     978                offBuffers = RT_ALIGN_Z(offBuffers + RTLOG_BUFFER_DEFAULT_SIZE, RTLOG_BUFFER_ALIGN);
     979            }
     980            Assert(offBuffers == cbLogger);
     981        }
     982        pLoggerInt->pBufDesc   = paBufDescs;
     983        pLoggerInt->idxBufDesc = 0;
    863984
    864985# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
     
    869990        if (pu8Code)
    870991        {
    871             pLogger->pfnLogger = *(PFNRTLOGGER*)&pu8Code;
     992            pLoggerInt->Core.pfnLogger = *(PFNRTLOGGER *)&pu8Code;
    872993            *pu8Code++ = 0x68;          /* push imm32 */
    873             *(void **)pu8Code = pLogger;
     994            *(void **)pu8Code = &pLoggerInt->Core;
    874995            pu8Code += sizeof(void *);
    875996            *pu8Code++ = 0xe8;          /* call rel32 */
     
    8811002            *pu8Code++ = 0x04;
    8821003            *pu8Code++ = 0xc3;          /* ret near */
    883             AssertMsg((uintptr_t)pu8Code - (uintptr_t)pLogger->pfnLogger <= 64,
    884                       ("Wrapper assembly is too big! %d bytes\n", (uintptr_t)pu8Code - (uintptr_t)pLogger->pfnLogger));
     1004            AssertMsg((uintptr_t)pu8Code - (uintptr_t)pLoggerInt->Core.pfnLogger <= 64,
     1005                      ("Wrapper assembly is too big! %d bytes\n", (uintptr_t)pu8Code - (uintptr_t)pLoggerInt->Core.pfnLogger));
    8851006            rc = VINF_SUCCESS;
    8861007        }
     
    8891010            rc = VERR_NO_MEMORY;
    8901011#  ifdef RT_OS_LINUX
    891                 /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */
     1012            /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */
    8921013            RTErrInfoSet(pErrInfo, rc, N_("mmap(PROT_WRITE | PROT_EXEC) failed -- SELinux?"));
    8931014#  endif
     
    9031024            {
    9041025                /** @todo validate the length, fail on overflow. */
    905                 RTStrPrintfV(pLogger->pInt->szFilename, sizeof(pLogger->pInt->szFilename), pszFilenameFmt, args);
    906                 if (pLogger->pInt->szFilename[0])
    907                     pLogger->fDestFlags |= RTLOGDEST_FILE;
     1026                RTStrPrintfV(pLoggerInt->szFilename, sizeof(pLoggerInt->szFilename), pszFilenameFmt, args);
     1027                if (pLoggerInt->szFilename[0])
     1028                    pLoggerInt->fDestFlags |= RTLOGDEST_FILE;
    9081029            }
    9091030
     
    9241045                const char *pszValue = RTEnvGet(pszEnvVar);
    9251046                if (pszValue)
    926                     RTLogDestinations(pLogger, pszValue);
     1047                    RTLogDestinations(&pLoggerInt->Core, pszValue);
    9271048
    9281049                /*
     
    9321053                pszValue = RTEnvGet(pszEnvVar);
    9331054                if (pszValue)
    934                     RTLogFlags(pLogger, pszValue);
     1055                    RTLogFlags(&pLoggerInt->Core, pszValue);
    9351056
    9361057                /*
     
    9401061                pszValue = RTEnvGet(pszEnvVar);
    9411062                if (pszValue)
    942                     RTLogGroupSettings(pLogger, pszValue);
     1063                    RTLogGroupSettings(&pLoggerInt->Core, pszValue);
    9431064
    9441065                /*
     
    9521073                    rc = RTStrToUInt32Full(pszValue, 0, &cMax);
    9531074                    if (RT_SUCCESS(rc))
    954                         pLogger->pInt->cMaxEntriesPerGroup = cMax ? cMax : UINT32_MAX;
     1075                        pLoggerInt->cMaxEntriesPerGroup = cMax ? cMax : UINT32_MAX;
    9551076                    else
    9561077                        AssertMsgFailed(("Invalid group limit! %s=%s\n", pszEnvVar, pszValue));
     
    9661087             */
    9671088            rc = VINF_SUCCESS;
    968             if ((pLogger->fDestFlags & (RTLOGDEST_F_DELAY_FILE | RTLOGDEST_FILE)) == RTLOGDEST_F_DELAY_FILE)
    969                 pLogger->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE;
     1089            if ((pLoggerInt->fDestFlags & (RTLOGDEST_F_DELAY_FILE | RTLOGDEST_FILE)) == RTLOGDEST_F_DELAY_FILE)
     1090                pLoggerInt->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE;
    9701091# ifdef IN_RING3
    971             if ((pLogger->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_F_DELAY_FILE)) == RTLOGDEST_FILE)
    972                 rc = rtR3LogOpenFileDestination(pLogger, pErrInfo);
     1092            if ((pLoggerInt->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_F_DELAY_FILE)) == RTLOGDEST_FILE)
     1093                rc = rtR3LogOpenFileDestination(pLoggerInt, pErrInfo);
    9731094# endif
    9741095
    975             if ((pLogger->fDestFlags & RTLOGDEST_RINGBUF) && RT_SUCCESS(rc))
    976                 rc = rtLogRingBufAdjust(pLogger, pLogger->pInt->cbRingBuf, true /*fForce*/);
     1096            if ((pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF) && RT_SUCCESS(rc))
     1097                rc = rtLogRingBufAdjust(pLoggerInt, pLoggerInt->cbRingBuf, true /*fForce*/);
    9771098
    9781099            /*
     
    9821103            if (RT_SUCCESS(rc))
    9831104            {
    984                 rc = RTSemSpinMutexCreate(&pLogger->pInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
     1105                if (!(fFlags & RTLOG_F_NO_LOCKING))
     1106                    rc = RTSemSpinMutexCreate(&pLoggerInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
    9851107                if (RT_SUCCESS(rc))
    9861108                {
     
    9901112                    {
    9911113                        int32_t c = RTLockValidatorWriteLockGetCount(Thread);
    992                         RTSemSpinMutexRequest(pLogger->pInt->hSpinMtx);
     1114                        RTSemSpinMutexRequest(pLoggerInt->hSpinMtx);
    9931115                        c = RTLockValidatorWriteLockGetCount(Thread) - c;
    994                         RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
     1116                        RTSemSpinMutexRelease(pLoggerInt->hSpinMtx);
    9951117                        ASMAtomicWriteU32(&g_cLoggerLockCount, c);
    9961118                    }
    9971119
    9981120                    /* Use the callback to generate some initial log contents. */
    999                     Assert(RT_VALID_PTR(pLogger->pInt->pfnPhase) || pLogger->pInt->pfnPhase == NULL);
    1000                     if (pLogger->pInt->pfnPhase)
    1001                         pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);
     1121                    AssertPtrNull(pLoggerInt->pfnPhase);
     1122                    if (pLoggerInt->pfnPhase)
     1123                        pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);
    10021124# endif
    1003                     pLogger->pInt->fCreated = true;
    1004                     *ppLogger = pLogger;
     1125                    pLoggerInt->fCreated = true;
     1126                    *ppLogger = &pLoggerInt->Core;
    10051127                    return VINF_SUCCESS;
    10061128                }
     
    10091131            }
    10101132# ifdef IN_RING3
    1011             RTFileClose(pLogger->pInt->hFile);
     1133            RTFileClose(pLoggerInt->hFile);
    10121134# endif
    10131135# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
    1014             RTMemFree(*(void **)&pLogger->pfnLogger);
     1136            RTMemFree(*(void **)&pLoggerInt->Core.pfnLogger);
    10151137# else
    1016             RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
     1138            RTMemExecFree(*(void **)&pLoggerInt->Core.pfnLogger, 64);
    10171139# endif
    10181140        }
    1019         RTMemFree(pLogger);
     1141        RTMemFree(pLoggerInt);
    10201142    }
    10211143    else
     
    10271149
    10281150
    1029 RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
     1151RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint64_t fFlags, const char *pszGroupSettings,
    10301152                        const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
    10311153                        uint32_t fDestFlags, const char *pszFilenameFmt, ...)
    10321154{
    1033     va_list args;
    1034     int rc;
    1035 
    1036     va_start(args, pszFilenameFmt);
    1037     rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase,
    1038                         cGroups, papszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/, fDestFlags,
     1155    va_list va;
     1156    int     rc;
     1157
     1158    va_start(va, pszFilenameFmt);
     1159    rc = RTLogCreateExV(ppLogger, pszEnvVarBase, fFlags, pszGroupSettings, cGroups, papszGroups,
     1160                        UINT32_MAX /*cMaxEntriesPerGroup*/,
     1161                        NULL /*pfnFlush*/, 0 /*cBufDescs*/, NULL /*paBufDescs*/, fDestFlags,
    10391162                        NULL /*pfnPhase*/, 0 /*cHistory*/, 0 /*cbHistoryFileMax*/, 0 /*cSecsHistoryTimeSlot*/,
    1040                         NULL /*pErrInfo*/, pszFilenameFmt, args);
    1041     va_end(args);
     1163                        NULL /*pErrInfo*/, pszFilenameFmt, va);
     1164    va_end(va);
    10421165    return rc;
    10431166}
     
    10451168
    10461169
    1047 RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, const char *pszEnvVarBase,
     1170RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings,
    10481171                          unsigned cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
    1049                           uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
    1050                           uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
     1172                          PFNRTLOGFLUSH pfnFlush, uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags,
     1173                          PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
    10511174                          PRTERRINFO pErrInfo, const char *pszFilenameFmt, ...)
    10521175{
    1053     va_list args;
    1054     int rc;
    1055 
    1056     va_start(args, pszFilenameFmt);
    1057     rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, cMaxEntriesPerGroup,
    1058                         fDestFlags, pfnPhase, cHistory, cbHistoryFileMax, cSecsHistoryTimeSlot,
    1059                         pErrInfo, pszFilenameFmt, args);
    1060     va_end(args);
     1176    va_list va;
     1177    int     rc;
     1178
     1179    va_start(va, pszFilenameFmt);
     1180    rc = RTLogCreateExV(ppLogger, pszEnvVarBase, fFlags, pszGroupSettings, cGroups, papszGroups, cMaxEntriesPerGroup,
     1181                        pfnFlush, cBufDescs, paBufDescs, fDestFlags,
     1182                        pfnPhase, cHistory, cbHistoryFileMax, cSecsHistoryTimeSlot,
     1183                        pErrInfo, pszFilenameFmt, va);
     1184    va_end(va);
    10611185    return rc;
    10621186}
     
    10741198RTDECL(int) RTLogDestroy(PRTLOGGER pLogger)
    10751199{
    1076     int             rc;
    1077     uint32_t        iGroup;
    1078     RTSEMSPINMUTEX  hSpinMtx;
     1200    int                 rc;
     1201    uint32_t            iGroup;
     1202    RTSEMSPINMUTEX      hSpinMtx;
     1203    PRTLOGGERINTERNAL   pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
    10791204
    10801205    /*
    10811206     * Validate input.
    10821207     */
    1083     if (!pLogger)
     1208    if (!pLoggerInt)
    10841209        return VINF_SUCCESS;
    1085     AssertPtrReturn(pLogger, VERR_INVALID_POINTER);
    1086     AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
    1087     AssertPtrReturn(pLogger->pInt, VERR_INVALID_POINTER);
     1210    AssertPtrReturn(pLoggerInt, VERR_INVALID_POINTER);
     1211    AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
    10881212
    10891213    /*
    10901214     * Acquire logger instance sem and disable all logging. (paranoia)
    10911215     */
    1092     rc = rtlogLock(pLogger);
     1216    rc = rtlogLock(pLoggerInt);
    10931217    AssertMsgRCReturn(rc, ("%Rrc\n", rc), rc);
    10941218
    1095     pLogger->fFlags |= RTLOGFLAGS_DISABLED;
    1096     iGroup = pLogger->cGroups;
     1219    pLoggerInt->fFlags |= RTLOGFLAGS_DISABLED;
     1220    iGroup = pLoggerInt->cGroups;
    10971221    while (iGroup-- > 0)
    1098         pLogger->afGroups[iGroup] = 0;
     1222        pLoggerInt->afGroups[iGroup] = 0;
    10991223
    11001224    /*
    11011225     * Flush it.
    11021226     */
    1103     rtlogFlush(pLogger, false /*fNeedSpace*/);
     1227    rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
    11041228
    11051229# ifdef IN_RING3
     
    11071231     * Add end of logging message.
    11081232     */
    1109     if (   (pLogger->fDestFlags & RTLOGDEST_FILE)
    1110         && pLogger->pInt->hFile != NIL_RTFILE)
    1111         pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);
     1233    if (   (pLoggerInt->fDestFlags & RTLOGDEST_FILE)
     1234        && pLoggerInt->hFile != NIL_RTFILE)
     1235        pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_END, rtlogPhaseMsgLocked);
    11121236
    11131237    /*
    11141238     * Close output stuffs.
    11151239     */
    1116     if (pLogger->pInt->hFile != NIL_RTFILE)
    1117     {
    1118         int rc2 = RTFileClose(pLogger->pInt->hFile);
     1240    if (pLoggerInt->hFile != NIL_RTFILE)
     1241    {
     1242        int rc2 = RTFileClose(pLoggerInt->hFile);
    11191243        AssertRC(rc2);
    11201244        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
    11211245            rc = rc2;
    1122         pLogger->pInt->hFile = NIL_RTFILE;
     1246        pLoggerInt->hFile = NIL_RTFILE;
    11231247    }
    11241248# endif
     
    11271251     * Free the mutex, the wrapper and the instance memory.
    11281252     */
    1129     hSpinMtx = pLogger->pInt->hSpinMtx;
    1130     pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
     1253    hSpinMtx = pLoggerInt->hSpinMtx;
     1254    pLoggerInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
    11311255    if (hSpinMtx != NIL_RTSEMSPINMUTEX)
    11321256    {
     
    11391263    }
    11401264
    1141     if (pLogger->pfnLogger)
     1265    if (pLoggerInt->Core.pfnLogger)
    11421266    {
    11431267# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
    1144         RTMemFree(*(void **)&pLogger->pfnLogger);
     1268        RTMemFree(*(void **)&pLoggerInt->Core.pfnLogger);
    11451269# else
    1146         RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
     1270        RTMemExecFree(*(void **)&pLoggerInt->Core.pfnLogger, 64);
    11471271# endif
    1148         pLogger->pfnLogger = NULL;
    1149     }
    1150     RTMemFree(pLogger);
     1272        pLoggerInt->Core.pfnLogger = NULL;
     1273    }
     1274    RTMemFree(pLoggerInt);
    11511275
    11521276    return rc;
     
    11551279
    11561280
     1281# if 0 /* obsolete */
    11571282/**
    11581283 * Create a logger instance clone for RC usage.
     
    12371362}
    12381363RT_EXPORT_SYMBOL(RTLogCloneRC);
    1239 
    1240 
     1364# endif
     1365
     1366
     1367# if 0 /* obsolete */
    12411368/**
    12421369 * Flushes a RC logger instance to a R3 logger.
     
    12941421}
    12951422RT_EXPORT_SYMBOL(RTLogFlushRC);
     1423# endif
    12961424
    12971425# ifdef IN_RING3
    1298 
     1426#  if 0 /* obsolete */
    12991427RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger,
    13001428                             RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr,
     
    14721600RT_EXPORT_SYMBOL(RTLogFlushR0);
    14731601
     1602#  endif /* obsolete */
    14741603# endif /* IN_RING3 */
    14751604
    14761605
     1606#if 0
    14771607/**
    14781608 * Flushes the buffer in one logger instance onto another logger.
     
    14861616RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger)
    14871617{
     1618    PRTLOGGERINTERNAL pSrcLoggerInt = (PRTLOGGERINTERNAL)pSrcLogger;
     1619    PRTLOGGERINTERNAL pDstLoggerInt = (PRTLOGGERINTERNAL)pDstLogger;
     1620
    14881621    /*
    14891622     * Resolve defaults.
    14901623     */
    1491     if (!pDstLogger)
    1492     {
    1493         pDstLogger = RTLogDefaultInstance();
    1494         if (!pDstLogger)
     1624    if (!pDstLoggerInt)
     1625    {
     1626        pDstLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     1627        if (!pDstLoggerInt)
    14951628        {
    14961629            /* flushing to "/dev/null". */
    1497             if (pSrcLogger->offScratch)
     1630            if (pSrcLoggerInt->offScratch)
    14981631            {
    1499                 int rc = rtlogLock(pSrcLogger);
     1632                int rc = rtlogLock(pSrcLoggerInt);
    15001633                if (RT_SUCCESS(rc))
    15011634                {
    1502                     pSrcLogger->offScratch = 0;
    1503                     rtlogUnlock(pSrcLogger);
     1635                    pSrcLoggerInt->offScratch = 0;
     1636                    rtlogUnlock(pSrcLoggerInt);
    15041637                }
    15051638            }
     
    15111644     * Any thing to flush?
    15121645     */
    1513     if (    pSrcLogger->offScratch
    1514         ||  pDstLogger->offScratch)
     1646    if (    pSrcLoggerInt->offScratch
     1647        ||  pDstLoggerInt->offScratch)
    15151648    {
    15161649        /*
    15171650         * Acquire logger semaphores.
    15181651         */
    1519         int rc = rtlogLock(pDstLogger);
     1652        int rc = rtlogLock(pDstLoggerInt);
    15201653        if (RT_FAILURE(rc))
    15211654            return;
    1522         rc = rtlogLock(pSrcLogger);
     1655        rc = rtlogLock(pSrcLoggerInt);
    15231656        if (RT_SUCCESS(rc))
    15241657        {
     
    15271660             * flush the HC instance.
    15281661             */
    1529             if (pSrcLogger->offScratch)
     1662            if (pSrcLoggerInt->offScratch)
    15301663            {
    1531                 rtLogOutput(pDstLogger, pSrcLogger->achScratch, pSrcLogger->offScratch);
    1532                 rtLogOutput(pDstLogger, NULL, 0);
    1533                 pSrcLogger->offScratch = 0;
     1664                rtLogOutput(pDstLoggerInt, pSrcLoggerInt->achScratch, pSrcLoggerInt->offScratch);
     1665                rtLogOutput(pDstLoggerInt, NULL, 0);
     1666                pSrcLoggerInt->offScratch = 0;
    15341667            }
    15351668
     
    15371670             * Release the semaphores.
    15381671             */
    1539             rtlogUnlock(pSrcLogger);
    1540         }
    1541         rtlogUnlock(pDstLogger);
     1672            rtlogUnlock(pSrcLoggerInt);
     1673        }
     1674        rtlogUnlock(pDstLoggerInt);
    15421675    }
    15431676}
    15441677RT_EXPORT_SYMBOL(RTLogFlushToLogger);
     1678#endif
    15451679
    15461680
     
    15581692     * Resolve defaults.
    15591693     */
    1560     if (!pLogger)
    1561     {
    1562         pLogger = RTLogDefaultInstance();
    1563         if (!pLogger)
     1694    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     1695    if (!pLoggerInt)
     1696    {
     1697        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     1698        if (!pLoggerInt)
    15641699            return VINF_SUCCESS;
    15651700    }
    1566     AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
     1701    AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
    15671702
    15681703    /*
    15691704     * Do the work.
    15701705     */
    1571     rtlogLock(pLogger);
    1572     pLogger->pInt->pvPrefixUserArg = pvUser;
    1573     pLogger->pInt->pfnPrefix       = pfnCallback;
    1574     rtlogUnlock(pLogger);
     1706    rtlogLock(pLoggerInt);
     1707    pLoggerInt->pvPrefixUserArg = pvUser;
     1708    pLoggerInt->pfnPrefix       = pfnCallback;
     1709    rtlogUnlock(pLoggerInt);
    15751710
    15761711    return VINF_SUCCESS;
     
    16661801RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue)
    16671802{
     1803
    16681804    /*
    16691805     * Resolve defaults.
    16701806     */
    1671     if (!pLogger)
    1672     {
    1673         pLogger = RTLogDefaultInstance();
    1674         if (!pLogger)
     1807    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     1808    if (!pLoggerInt)
     1809    {
     1810        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     1811        if (!pLoggerInt)
    16751812            return VINF_SUCCESS;
    16761813    }
     1814    Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC);
    16771815
    16781816    /*
     
    17231861                            ? RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1
    17241862                            : rtlogGroupFlags(&pszStart[3]);
    1725             for (i = 0; i < pLogger->cGroups; i++)
     1863            for (i = 0; i < pLoggerInt->cGroups; i++)
    17261864            {
    17271865                if (fEnabled)
    1728                     pLogger->afGroups[i] |= fFlags;
     1866                    pLoggerInt->afGroups[i] |= fFlags;
    17291867                else
    1730                     pLogger->afGroups[i] &= ~fFlags;
     1868                    pLoggerInt->afGroups[i] &= ~fFlags;
    17311869            }
    17321870        }
     
    17361874             * Specific group(s).
    17371875             */
    1738             for (i = 0; i < pLogger->cGroups; i++)
     1876            for (i = 0; i < pLoggerInt->cGroups; i++)
    17391877            {
    17401878                const char *psz2 = (const char*)pszStart;
    1741                 if (rtlogIsGroupMatching(pLogger->pInt->papszGroups[i], &psz2, cch))
     1879                if (rtlogIsGroupMatching(pLoggerInt->papszGroups[i], &psz2, cch))
    17421880                {
    17431881                    unsigned fFlags = RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1;
     
    17451883                        fFlags = rtlogGroupFlags(psz2);
    17461884                    if (fEnabled)
    1747                         pLogger->afGroups[i] |= fFlags;
     1885                        pLoggerInt->afGroups[i] |= fFlags;
    17481886                    else
    1749                         pLogger->afGroups[i] &= ~fFlags;
     1887                        pLoggerInt->afGroups[i] &= ~fFlags;
    17501888                }
    17511889            } /* for each group */
     
    19202058RTDECL(int) RTLogQueryGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
    19212059{
    1922     bool        fNotFirst = false;
    1923     int         rc        = VINF_SUCCESS;
    1924     uint32_t    cGroups;
    1925     uint32_t    fGroup;
    1926     uint32_t    i;
     2060    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2061    bool              fNotFirst  = false;
     2062    int               rc         = VINF_SUCCESS;
     2063    uint32_t          cGroups;
     2064    uint32_t          fGroup;
     2065    uint32_t          i;
    19272066
    19282067    Assert(cchBuf);
     
    19312070     * Resolve defaults.
    19322071     */
    1933     if (!pLogger)
    1934     {
    1935         pLogger = RTLogDefaultInstance();
    1936         if (!pLogger)
     2072    if (!pLoggerInt)
     2073    {
     2074        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2075        if (!pLoggerInt)
    19372076        {
    19382077            *pszBuf = '\0';
     
    19402079        }
    19412080    }
    1942 
    1943     cGroups = pLogger->cGroups;
     2081    Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC);
     2082
     2083    cGroups = pLoggerInt->cGroups;
    19442084
    19452085    /*
    19462086     * Check if all are the same.
    19472087     */
    1948     fGroup = pLogger->afGroups[0];
     2088    fGroup = pLoggerInt->afGroups[0];
    19492089    for (i = 1; i < cGroups; i++)
    1950         if (pLogger->afGroups[i] != fGroup)
     2090        if (pLoggerInt->afGroups[i] != fGroup)
    19512091            break;
    19522092    if (i >= cGroups)
     
    19602100        for (i = 0; i < cGroups; i++)
    19612101        {
    1962             fGroup = pLogger->afGroups[i];
     2102            fGroup = pLoggerInt->afGroups[i];
    19632103            if (fGroup)
    19642104            {
    1965                 const char *pszName = pLogger->pInt->papszGroups[i];
     2105                const char *pszName = pLoggerInt->papszGroups[i];
    19662106                if (pszName)
    19672107                {
     
    19922132RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue)
    19932133{
    1994     int rc = VINF_SUCCESS;
     2134    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2135    int               rc         = VINF_SUCCESS;
    19952136
    19962137    /*
    19972138     * Resolve defaults.
    19982139     */
    1999     if (!pLogger)
    2000     {
    2001         pLogger = RTLogDefaultInstance();
    2002         if (!pLogger)
     2140    if (!pLoggerInt)
     2141    {
     2142        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2143        if (!pLoggerInt)
    20032144            return VINF_SUCCESS;
    20042145    }
     
    20462187            if (!strncmp(pszValue, g_aLogFlags[i].pszInstr, g_aLogFlags[i].cchInstr))
    20472188            {
    2048                 if (!(g_aLogFlags[i].fFixedDest & pLogger->fDestFlags))
     2189                if (!(g_aLogFlags[i].fFixedDest & pLoggerInt->fDestFlags))
    20492190                {
    20502191                    if (fNo == g_aLogFlags[i].fInverted)
    2051                         pLogger->fFlags |= g_aLogFlags[i].fFlag;
     2192                        pLoggerInt->fFlags |= g_aLogFlags[i].fFlag;
    20522193                    else
    2053                         pLogger->fFlags &= ~g_aLogFlags[i].fFlag;
     2194                        pLoggerInt->fFlags &= ~g_aLogFlags[i].fFlag;
    20542195                }
    20552196                pszValue += g_aLogFlags[i].cchInstr;
     
    20872228RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered)
    20882229{
    2089     bool fOld;
     2230    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2231    bool              fOld;
    20902232
    20912233    /*
    20922234     * Resolve the logger instance.
    20932235     */
    2094     if (!pLogger)
    2095     {
    2096         pLogger = RTLogDefaultInstance();
    2097         if (!pLogger)
     2236    if (!pLoggerInt)
     2237    {
     2238        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2239        if (!pLoggerInt)
    20982240            return false;
    20992241    }
    21002242
    2101     rtlogLock(pLogger);
    2102     fOld  = !!(pLogger->fFlags & RTLOGFLAGS_BUFFERED);
     2243    rtlogLock(pLoggerInt);
     2244    fOld  = !!(pLoggerInt->fFlags & RTLOGFLAGS_BUFFERED);
    21032245    if (fBuffered)
    2104         pLogger->fFlags |= RTLOGFLAGS_BUFFERED;
     2246        pLoggerInt->fFlags |= RTLOGFLAGS_BUFFERED;
    21052247    else
    2106         pLogger->fFlags &= ~RTLOGFLAGS_BUFFERED;
    2107     rtlogUnlock(pLogger);
     2248        pLoggerInt->fFlags &= ~RTLOGFLAGS_BUFFERED;
     2249    rtlogUnlock(pLoggerInt);
    21082250
    21092251    return fOld;
     
    21152257RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup)
    21162258{
     2259    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2260
    21172261    /*
    21182262     * Resolve the logger instance.
    21192263     */
    2120     if (!pLogger)
    2121     {
    2122         pLogger = RTLogDefaultInstance();
    2123         if (!pLogger)
     2264    if (!pLoggerInt)
     2265    {
     2266        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2267        if (!pLoggerInt)
    21242268            return UINT32_MAX;
    21252269    }
    21262270
    2127     rtlogLock(pLogger);
    2128     uint32_t cOld = pLogger->pInt->cMaxEntriesPerGroup;
    2129     pLogger->pInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup;
    2130     rtlogUnlock(pLogger);
     2271    rtlogLock(pLoggerInt);
     2272    uint32_t cOld = pLoggerInt->cMaxEntriesPerGroup;
     2273    pLoggerInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup;
     2274    rtlogUnlock(pLoggerInt);
    21312275
    21322276    return cOld;
    21332277}
     2278#endif
     2279
     2280
     2281#ifdef IN_RING0
     2282RTR0DECL(int) RTLogSetR0ThreadNameF(PRTLOGGER pLogger, const char *pszNameFmt, ...)
     2283{
     2284    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2285    int               rc;
     2286    if (pLoggerInt)
     2287    {
     2288        va_list va;
     2289        va_start(va, pszNameFmt);
     2290
     2291        rc = rtlogLock(pLoggerInt);
     2292        if (RT_SUCCESS(rc))
     2293        {
     2294            ssize_t cch = RTStrPrintf2V(pLoggerInt->szR0ThreadName, sizeof(pLoggerInt->szR0ThreadName), pszNameFmt, va);
     2295            rtlogUnlock(pLoggerInt);
     2296            rc = cch > 0 ? VINF_SUCCESS : VERR_BUFFER_OVERFLOW;
     2297        }
     2298
     2299        va_end(va);
     2300    }
     2301    else
     2302        rc = VERR_INVALID_PARAMETER;
     2303    return rc;
     2304}
     2305RT_EXPORT_SYMBOL(RTLogSetR0ThreadNameF);
    21342306#endif
    21352307
     
    21442316RTDECL(uint64_t) RTLogGetFlags(PRTLOGGER pLogger)
    21452317{
    2146     if (!pLogger)
    2147     {
    2148         pLogger = RTLogDefaultInstance();
    2149         if (!pLogger)
     2318    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2319    if (!pLoggerInt)
     2320    {
     2321        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2322        if (!pLoggerInt)
    21502323            return UINT64_MAX;
    21512324    }
    2152     return pLogger->fFlags;
     2325    return pLoggerInt->fFlags;
    21532326}
    21542327RT_EXPORT_SYMBOL(RTLogGetFlags);
     2328
     2329
     2330/**
     2331 * Modifies the flag settings for the given logger.
     2332 *
     2333 * @returns IPRT status code.  Returns VINF_SUCCESS if no default logger and @a
     2334 *          pLogger is NULL.
     2335 * @param   pLogger         Logger instance (NULL for default logger).
     2336 * @param   fSet            Mask of flags to set (OR).
     2337 * @param   fClear          Mask of flags to clear (NAND).  This is allowed to
     2338 *                          include invalid flags - e.g. UINT64_MAX is okay.
     2339 */
     2340RTDECL(int) RTLogChangeFlags(PRTLOGGER pLogger, uint64_t fSet, uint64_t fClear)
     2341{
     2342    AssertReturn(!(fSet & ~RTLOG_F_VALID_MASK), VERR_INVALID_FLAGS);
     2343
     2344    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2345    if (!pLoggerInt)
     2346    {
     2347        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2348        if (!pLoggerInt)
     2349            return VINF_SUCCESS;
     2350    }
     2351    AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
     2352    AssertReturn(pLoggerInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH);
     2353
     2354    /*
     2355     * Make the changes.
     2356     */
     2357    pLoggerInt->fFlags &= ~fClear;
     2358    pLoggerInt->fFlags |= fSet;
     2359
     2360    return VINF_SUCCESS;
     2361}
     2362RT_EXPORT_SYMBOL(RTLogChangeFlags);
    21552363
    21562364
     
    21662374RTDECL(int) RTLogQueryFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
    21672375{
    2168     bool        fNotFirst = false;
    2169     int         rc        = VINF_SUCCESS;
    2170     uint32_t    fFlags;
    2171     unsigned    i;
     2376    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2377    bool              fNotFirst  = false;
     2378    int               rc         = VINF_SUCCESS;
     2379    uint32_t          fFlags;
     2380    unsigned          i;
    21722381
    21732382    Assert(cchBuf);
     
    21762385     * Resolve defaults.
    21772386     */
    2178     if (!pLogger)
    2179     {
    2180         pLogger = RTLogDefaultInstance();
    2181         if (!pLogger)
     2387    if (!pLoggerInt)
     2388    {
     2389        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2390        if (!pLoggerInt)
    21822391        {
    21832392            *pszBuf = '\0';
     
    21892398     * Add the flags in the list.
    21902399     */
    2191     fFlags = pLogger->fFlags;
     2400    fFlags = pLoggerInt->fFlags;
    21922401    for (i = 0; i < RT_ELEMENTS(g_aLogFlags); i++)
    21932402        if (    !g_aLogFlags[i].fInverted
     
    22722481     * Resolve defaults.
    22732482     */
    2274     if (!pLogger)
    2275     {
    2276         pLogger = RTLogDefaultInstance();
    2277         if (!pLogger)
     2483    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2484    if (!pLoggerInt)
     2485    {
     2486        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2487        if (!pLoggerInt)
    22782488            return VINF_SUCCESS;
    22792489    }
     
    23132523            {
    23142524                if (!fNo)
    2315                     pLogger->fDestFlags |= g_aLogDst[i].fFlag;
     2525                    pLoggerInt->fDestFlags |= g_aLogDst[i].fFlag;
    23162526                else
    2317                     pLogger->fDestFlags &= ~g_aLogDst[i].fFlag;
     2527                    pLoggerInt->fDestFlags &= ~g_aLogDst[i].fFlag;
    23182528                pszValue += cchInstr;
    23192529
     
    23282538
    23292539# ifdef IN_RING3
    2330                     char szTmp[sizeof(pLogger->pInt->szFilename)];
     2540                    char szTmp[sizeof(pLoggerInt->szFilename)];
    23312541# else
    23322542                    char szTmp[32];
     
    23342544                    if (0)
    23352545                    { /* nothing */ }
    2336 #ifdef IN_RING3
     2546# ifdef IN_RING3
    23372547
    23382548                    /* log file name */
    23392549                    else if (i == 0 /* file */ && !fNo)
    23402550                    {
    2341                         if (!(pLogger->fDestFlags & RTLOGDEST_FIXED_FILE))
     2551                        if (!(pLoggerInt->fDestFlags & RTLOGDEST_FIXED_FILE))
    23422552                        {
    2343                             AssertReturn(cch < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
    2344                             memcpy(pLogger->pInt->szFilename, pszValue, cch);
    2345                             pLogger->pInt->szFilename[cch] = '\0';
    2346                             /** @todo reopen log file if pLogger->pInt->fCreated is true ... */
     2553                            AssertReturn(cch < sizeof(pLoggerInt->szFilename), VERR_OUT_OF_RANGE);
     2554                            memcpy(pLoggerInt->szFilename, pszValue, cch);
     2555                            pLoggerInt->szFilename[cch] = '\0';
     2556                            /** @todo reopen log file if pLoggerInt->fCreated is true ... */
    23472557                        }
    23482558                    }
     
    23502560                    else if (i == 1 /* dir */ && !fNo)
    23512561                    {
    2352                         if (!(pLogger->fDestFlags & RTLOGDEST_FIXED_DIR))
     2562                        if (!(pLoggerInt->fDestFlags & RTLOGDEST_FIXED_DIR))
    23532563                        {
    2354                             const char *pszFile = RTPathFilename(pLogger->pInt->szFilename);
     2564                            const char *pszFile = RTPathFilename(pLoggerInt->szFilename);
    23552565                            size_t      cchFile = pszFile ? strlen(pszFile) : 0;
    2356                             AssertReturn(cchFile + cch + 1 < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
     2566                            AssertReturn(cchFile + cch + 1 < sizeof(pLoggerInt->szFilename), VERR_OUT_OF_RANGE);
    23572567                            memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1);
    23582568
    2359                             memcpy(pLogger->pInt->szFilename, pszValue, cch);
    2360                             pLogger->pInt->szFilename[cch] = '\0';
    2361                             RTPathStripTrailingSlash(pLogger->pInt->szFilename);
    2362 
    2363                             cch = strlen(pLogger->pInt->szFilename);
    2364                             pLogger->pInt->szFilename[cch++] = '/';
    2365                             memcpy(&pLogger->pInt->szFilename[cch], szTmp, cchFile);
    2366                             pLogger->pInt->szFilename[cch + cchFile] = '\0';
    2367                             /** @todo reopen log file if pLogger->pInt->fCreated is true ... */
     2569                            memcpy(pLoggerInt->szFilename, pszValue, cch);
     2570                            pLoggerInt->szFilename[cch] = '\0';
     2571                            RTPathStripTrailingSlash(pLoggerInt->szFilename);
     2572
     2573                            cch = strlen(pLoggerInt->szFilename);
     2574                            pLoggerInt->szFilename[cch++] = '/';
     2575                            memcpy(&pLoggerInt->szFilename[cch], szTmp, cchFile);
     2576                            pLoggerInt->szFilename[cch + cchFile] = '\0';
     2577                            /** @todo reopen log file if pLoggerInt->fCreated is true ... */
    23682578                        }
    23692579                    }
     
    23772587                                rc = RTStrToUInt32Full(szTmp, 0, &cHistory);
    23782588                            AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc);
    2379                             pLogger->pInt->cHistory = cHistory;
     2589                            pLoggerInt->cHistory = cHistory;
    23802590                        }
    23812591                        else
    2382                             pLogger->pInt->cHistory = 0;
     2592                            pLoggerInt->cHistory = 0;
    23832593                    }
    23842594                    else if (i == 3 /* histsize */)
     
    23882598                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
    23892599                            if (RT_SUCCESS(rc))
    2390                                 rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pInt->cbHistoryFileMax);
     2600                                rc = RTStrToUInt64Full(szTmp, 0, &pLoggerInt->cbHistoryFileMax);
    23912601                            AssertMsgRCReturn(rc, ("Invalid history file size value %s (%Rrc)!\n", szTmp, rc), rc);
    2392                             if (pLogger->pInt->cbHistoryFileMax == 0)
    2393                                 pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
     2602                            if (pLoggerInt->cbHistoryFileMax == 0)
     2603                                pLoggerInt->cbHistoryFileMax = UINT64_MAX;
    23942604                        }
    23952605                        else
    2396                             pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
     2606                            pLoggerInt->cbHistoryFileMax = UINT64_MAX;
    23972607                    }
    23982608                    else if (i == 4 /* histtime */)
     
    24022612                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
    24032613                            if (RT_SUCCESS(rc))
    2404                                 rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pInt->cSecsHistoryTimeSlot);
     2614                                rc = RTStrToUInt32Full(szTmp, 0, &pLoggerInt->cSecsHistoryTimeSlot);
    24052615                            AssertMsgRCReturn(rc, ("Invalid history time slot value %s (%Rrc)!\n", szTmp, rc), rc);
    2406                             if (pLogger->pInt->cSecsHistoryTimeSlot == 0)
    2407                                 pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
     2616                            if (pLoggerInt->cSecsHistoryTimeSlot == 0)
     2617                                pLoggerInt->cSecsHistoryTimeSlot = UINT32_MAX;
    24082618                        }
    24092619                        else
    2410                             pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
     2620                            pLoggerInt->cSecsHistoryTimeSlot = UINT32_MAX;
    24112621                    }
    24122622# endif /* IN_RING3 */
     
    24272637                        else
    24282638                            cbRingBuf = RT_ALIGN_32(cbRingBuf, 64);
    2429                         rc = rtLogRingBufAdjust(pLogger, cbRingBuf, false /*fForce*/);
     2639                        rc = rtLogRingBufAdjust(pLoggerInt, cbRingBuf, false /*fForce*/);
    24302640                        if (RT_FAILURE(rc))
    24312641                            return rc;
     
    24382648                    pszValue = pszEnd + (*pszEnd != '\0');
    24392649                }
    2440                 else if (i == 5 /* ringbuf */ && !fNo && !pLogger->pInt->pszRingBuf)
     2650                else if (i == 5 /* ringbuf */ && !fNo && !pLoggerInt->pszRingBuf)
    24412651                {
    2442                     int rc = rtLogRingBufAdjust(pLogger, pLogger->pInt->cbRingBuf, false /*fForce*/);
     2652                    int rc = rtLogRingBufAdjust(pLoggerInt, pLoggerInt->cbRingBuf, false /*fForce*/);
    24432653                    if (RT_FAILURE(rc))
    24442654                        return rc;
     
    24762686     * Resolve defaults.
    24772687     */
    2478     if (!pLogger)
    2479     {
    2480         pLogger = RTLogDefaultInstance();
    2481         if (!pLogger)
     2688    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2689    if (!pLoggerInt)
     2690    {
     2691        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2692        if (!pLoggerInt)
    24822693            return VINF_SUCCESS;
    24832694    }
     
    24862697     * Do the work.
    24872698     */
    2488     int rc = rtlogLock(pLogger);
     2699    int rc = rtlogLock(pLoggerInt);
    24892700    if (RT_SUCCESS(rc))
    24902701    {
    2491         if (pLogger->fDestFlags & RTLOGDEST_F_DELAY_FILE)
    2492         {
    2493             pLogger->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE;
     2702        if (pLoggerInt->fDestFlags & RTLOGDEST_F_DELAY_FILE)
     2703        {
     2704            pLoggerInt->fDestFlags &= ~RTLOGDEST_F_DELAY_FILE;
    24942705# ifdef IN_RING3
    2495             if (   pLogger->fDestFlags & RTLOGDEST_FILE
    2496                 && pLogger->pInt->hFile == NIL_RTFILE)
     2706            if (   pLoggerInt->fDestFlags & RTLOGDEST_FILE
     2707                && pLoggerInt->hFile == NIL_RTFILE)
    24972708            {
    2498                 rc = rtR3LogOpenFileDestination(pLogger, pErrInfo);
     2709                rc = rtR3LogOpenFileDestination(pLoggerInt, pErrInfo);
    24992710                if (RT_SUCCESS(rc))
    2500                     rtlogFlush(pLogger, false /*fNeedSpace*/);
     2711                    rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
    25012712            }
    25022713# endif
    25032714            RT_NOREF(pErrInfo); /** @todo fix create API to use RTErrInfo */
    25042715        }
    2505         rtlogUnlock(pLogger);
     2716        rtlogUnlock(pLoggerInt);
    25062717    }
    25072718    return VINF_SUCCESS;
    25082719}
    25092720RT_EXPORT_SYMBOL(RTLogClearFileDelayFlag);
     2721
     2722
     2723/**
     2724 * Modifies the log destinations settings for the given logger.
     2725 *
     2726 * This is only suitable for simple destination settings that doesn't take
     2727 * additional arguments, like RTLOGDEST_FILE.
     2728 *
     2729 * @returns IPRT status code.  Returns VINF_SUCCESS if no default logger and @a
     2730 *          pLogger is NULL.
     2731 * @param   pLogger            Logger instance (NULL for default logger).
     2732 * @param   fSet               Mask of destinations to set (OR).
     2733 * @param   fClear             Mask of destinations to clear (NAND).
     2734 */
     2735RTDECL(int) RTLogChangeDestinations(PRTLOGGER pLogger, uint32_t fSet, uint32_t fClear)
     2736{
     2737    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2738    AssertCompile((RTLOG_DST_VALID_MASK & RTLOG_DST_CHANGE_MASK) == RTLOG_DST_CHANGE_MASK);
     2739    AssertReturn(!(fSet & ~RTLOG_DST_CHANGE_MASK), VERR_INVALID_FLAGS);
     2740    AssertReturn(!(fClear & ~RTLOG_DST_CHANGE_MASK), VERR_INVALID_FLAGS);
     2741
     2742    /*
     2743     * Resolve defaults.
     2744     */
     2745    if (!pLoggerInt)
     2746    {
     2747        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2748        if (!pLoggerInt)
     2749            return VINF_SUCCESS;
     2750    }
     2751    AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
     2752    AssertReturn(pLoggerInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH);
     2753
     2754    /*
     2755     * Make the changes.
     2756     */
     2757    pLoggerInt->fDestFlags &= ~fClear;
     2758    pLoggerInt->fDestFlags |= fSet;
     2759
     2760    return VINF_SUCCESS;
     2761}
     2762RT_EXPORT_SYMBOL(RTLogChangeDestinations);
     2763
     2764
     2765/**
     2766 * Gets the current destinations flags for the given logger.
     2767 *
     2768 * @returns Logger destination flags, UINT32_MAX if no logger.
     2769 * @param   pLogger             Logger instance (NULL for default logger).
     2770 */
     2771RTDECL(uint32_t) RTLogGetDestinations(PRTLOGGER pLogger)
     2772{
     2773    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2774    if (!pLoggerInt)
     2775    {
     2776        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2777        if (!pLoggerInt)
     2778            return UINT32_MAX;
     2779    }
     2780    return pLoggerInt->fFlags;
     2781}
     2782RT_EXPORT_SYMBOL(RTLogGetDestinations);
    25102783
    25112784
     
    25212794RTDECL(int) RTLogQueryDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
    25222795{
    2523     bool        fNotFirst = false;
    2524     int         rc        = VINF_SUCCESS;
    2525     uint32_t    fDestFlags;
    2526     unsigned    i;
     2796    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2797    bool              fNotFirst  = false;
     2798    int               rc         = VINF_SUCCESS;
     2799    uint32_t          fDestFlags;
     2800    unsigned          i;
    25272801
    25282802    AssertReturn(cchBuf, VERR_INVALID_PARAMETER);
     
    25322806     * Resolve defaults.
    25332807     */
    2534     if (!pLogger)
    2535     {
    2536         pLogger = RTLogDefaultInstance();
    2537         if (!pLogger)
     2808    if (!pLoggerInt)
     2809    {
     2810        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     2811        if (!pLoggerInt)
    25382812            return VINF_SUCCESS;
    25392813    }
     
    25422816     * Add the flags in the list.
    25432817     */
    2544     fDestFlags = pLogger->fDestFlags;
     2818    fDestFlags = pLoggerInt->fDestFlags;
    25452819    for (i = 6; i < RT_ELEMENTS(g_aLogDst); i++)
    25462820        if (g_aLogDst[i].fFlag & fDestFlags)
     
    25692843        if (RT_FAILURE(rc))
    25702844            return rc;
    2571         rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pInt->szFilename);
     2845        rc = RTStrCopyP(&pszBuf, &cchBuf, pLoggerInt->szFilename);
    25722846        if (RT_FAILURE(rc))
    25732847            return rc;
    25742848        fNotFirst = true;
    25752849
    2576         if (pLogger->pInt->cHistory)
    2577         {
    2578             RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " history=%u" : "history=%u", pLogger->pInt->cHistory);
     2850        if (pLoggerInt->cHistory)
     2851        {
     2852            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " history=%u" : "history=%u", pLoggerInt->cHistory);
    25792853            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    25802854            if (RT_FAILURE(rc))
     
    25822856            fNotFirst = true;
    25832857        }
    2584         if (pLogger->pInt->cbHistoryFileMax != UINT64_MAX)
    2585         {
    2586             RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histsize=%llu" : "histsize=%llu", pLogger->pInt->cbHistoryFileMax);
     2858        if (pLoggerInt->cbHistoryFileMax != UINT64_MAX)
     2859        {
     2860            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histsize=%llu" : "histsize=%llu", pLoggerInt->cbHistoryFileMax);
    25872861            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    25882862            if (RT_FAILURE(rc))
     
    25902864            fNotFirst = true;
    25912865        }
    2592         if (pLogger->pInt->cSecsHistoryTimeSlot != UINT32_MAX)
    2593         {
    2594             RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histtime=%llu" : "histtime=%llu", pLogger->pInt->cSecsHistoryTimeSlot);
     2866        if (pLoggerInt->cSecsHistoryTimeSlot != UINT32_MAX)
     2867        {
     2868            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histtime=%llu" : "histtime=%llu", pLoggerInt->cSecsHistoryTimeSlot);
    25952869            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    25962870            if (RT_FAILURE(rc))
     
    26062880    if (fDestFlags & RTLOGDEST_RINGBUF)
    26072881    {
    2608         if (pLogger->pInt->cbRingBuf == RTLOG_RINGBUF_DEFAULT_SIZE)
     2882        if (pLoggerInt->cbRingBuf == RTLOG_RINGBUF_DEFAULT_SIZE)
    26092883            rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " ringbuf" : "ringbuf");
    26102884        else
    26112885        {
    2612             RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " ringbuf=%#x" : "ringbuf=%#x", pLogger->pInt->cbRingBuf);
     2886            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " ringbuf=%#x" : "ringbuf=%#x", pLoggerInt->cbRingBuf);
    26132887            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    26142888        }
     
    26222896RT_EXPORT_SYMBOL(RTLogQueryDestinations);
    26232897
     2898
     2899/**
     2900 * Helper for calculating the CRC32 of all the group names.
     2901 */
     2902static uint32_t rtLogCalcGroupNameCrc32(PRTLOGGERINTERNAL pLoggerInt)
     2903{
     2904    const char * const * const  papszGroups = pLoggerInt->papszGroups;
     2905    uint32_t                    iGroup      = pLoggerInt->cGroups;
     2906    uint32_t                    uCrc32      = RTCrc32Start();
     2907    while (iGroup-- > 0)
     2908    {
     2909        const char *pszGroup = papszGroups[iGroup];
     2910        uCrc32 = RTCrc32Process(uCrc32, pszGroup, strlen(pszGroup) + 1);
     2911    }
     2912    return RTCrc32Finish(uCrc32);
     2913}
     2914
     2915
     2916/**
     2917 * Performs a bulk update of logger flags and group flags.
     2918 *
     2919 * This is for instanced used for copying settings from ring-3 to ring-0
     2920 * loggers.
     2921 *
     2922 * @returns IPRT status code.
     2923 * @param   pLogger             The logger instance (NULL for default logger).
     2924 * @param   fFlags              The new logger flags.
     2925 * @param   uGroupCrc32         The CRC32 of the group name strings.
     2926 * @param   cGroups             Number of groups.
     2927 * @param   pafGroups           Array of group flags.
     2928 * @sa      RTLogQueryBulk
     2929 */
     2930RTDECL(int) RTLogBulkUpdate(PRTLOGGER pLogger, uint64_t fFlags, uint32_t uGroupCrc32, uint32_t cGroups, uint32_t const *pafGroups)
     2931{
     2932    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     2933    int               rc;
     2934
     2935    /*
     2936     * Resolve defaults.
     2937     */
     2938    if (!pLoggerInt)
     2939    {
     2940        pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger;
     2941        if (!pLoggerInt)
     2942            return VINF_SUCCESS;
     2943    }
     2944
     2945    /*
     2946     * Do the updating.
     2947     */
     2948    rc = rtlogLock(pLoggerInt);
     2949    if (RT_SUCCESS(rc))
     2950    {
     2951        pLoggerInt->fFlags = fFlags;
     2952        if (   uGroupCrc32 == rtLogCalcGroupNameCrc32(pLoggerInt)
     2953            && pLoggerInt->cGroups == cGroups)
     2954        {
     2955            memcpy(pLoggerInt->afGroups, pafGroups, sizeof(pLoggerInt->afGroups[0]) * cGroups);
     2956            rc = VINF_SUCCESS;
     2957        }
     2958        else
     2959            rc = VERR_MISMATCH;
     2960
     2961        rtlogUnlock(pLoggerInt);
     2962    }
     2963    return rc;
     2964}
     2965RT_EXPORT_SYMBOL(RTLogBulkUpdate);
     2966
     2967
     2968/**
     2969 * Queries data for a bulk update of logger flags and group flags.
     2970 *
     2971 * This is for instanced used for copying settings from ring-3 to ring-0
     2972 * loggers.
     2973 *
     2974 * @returns IPRT status code.
     2975 * @retval  VERR_BUFFER_OVERFLOW if pafGroups is too small, @a pcGroups will be
     2976 *          set to the actual number of groups.
     2977 * @param   pLogger             The logger instance (NULL for default logger).
     2978 * @param   pfFlags             Where to return the logger flags.
     2979 * @param   puGroupCrc32        Where to return the CRC32 of the group names.
     2980 * @param   pcGroups            Input: Size of the @a pafGroups allocation.
     2981 *                              Output: Actual number of groups returned.
     2982 * @param   pafGroups           Where to return the flags for each group.
     2983 * @sa      RTLogBulkUpdate
     2984 */
     2985RTDECL(int) RTLogQueryBulk(PRTLOGGER pLogger, uint64_t *pfFlags, uint32_t *puGroupCrc32, uint32_t *pcGroups, uint32_t *pafGroups)
     2986{
     2987    PRTLOGGERINTERNAL pLoggerInt   = (PRTLOGGERINTERNAL)pLogger;
     2988    uint32_t const    cGroupsAlloc = *pcGroups;
     2989
     2990    /*
     2991     * Resolve defaults.
     2992     */
     2993    if (!pLoggerInt)
     2994    {
     2995        pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger;
     2996        if (!pLoggerInt)
     2997        {
     2998            *pfFlags      = 0;
     2999            *puGroupCrc32 = 0;
     3000            *pcGroups     = 0;
     3001            return VINF_SUCCESS;
     3002        }
     3003    }
     3004    AssertReturn(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
     3005
     3006    /*
     3007     * Get the data.
     3008     */
     3009    *pfFlags  = pLoggerInt->fFlags;
     3010    *pcGroups = pLoggerInt->cGroups;
     3011    if (cGroupsAlloc >= pLoggerInt->cGroups)
     3012    {
     3013        memcpy(pafGroups, pLoggerInt->afGroups, sizeof(pLoggerInt->afGroups[0]) * pLoggerInt->cGroups);
     3014        *puGroupCrc32 = rtLogCalcGroupNameCrc32(pLoggerInt);
     3015        return VINF_SUCCESS;
     3016    }
     3017    *puGroupCrc32 = 0;
     3018    return VERR_BUFFER_OVERFLOW;
     3019}
     3020RT_EXPORT_SYMBOL(RTLogQueryBulk);
     3021
     3022
     3023/**
     3024 * Write/copy bulk log data from another logger.
     3025 *
     3026 * This is used for transferring stuff from the ring-0 loggers and into the
     3027 * ring-3 one.  The text goes in as-is w/o any processing (i.e. prefixing or
     3028 * newline fun).
     3029 *
     3030 * @returns IRPT status code.
     3031 * @param   pLogger             The logger instance (NULL for default logger).
     3032 * @param   pch                 Pointer to the block of bulk log text to write.
     3033 * @param   cch                 Size of the block of bulk log text to write.
     3034 */
     3035RTDECL(int) RTLogBulkWrite(PRTLOGGER pLogger, const char *pch, size_t cch)
     3036{
     3037    /*
     3038     * Resolve defaults.
     3039     */
     3040    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     3041    if (!pLoggerInt)
     3042    {
     3043        pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger;
     3044        if (!pLoggerInt)
     3045            return VINF_SUCCESS;
     3046    }
     3047
     3048    /*
     3049     * Lock and validate it.
     3050     */
     3051    int rc = rtlogLock(pLoggerInt);
     3052    if (RT_SUCCESS(rc))
     3053    {
     3054        /*
     3055         * Do the copying.
     3056         */
     3057        while (cch > 0)
     3058        {
     3059            PRTLOGBUFFERDESC const  pBufDesc = pLoggerInt->pBufDesc;
     3060            char * const            pchBuf   = pBufDesc->pchBuf;
     3061            uint32_t const          cbBuf    = pBufDesc->cbBuf;
     3062            uint32_t                offBuf   = pBufDesc->offBuf;
     3063            if (cch + 1 < cbBuf - offBuf)
     3064            {
     3065                memcpy(&pchBuf[offBuf], pch, cch);
     3066                offBuf += (uint32_t)cch;
     3067                pchBuf[offBuf] = '\0';
     3068                pBufDesc->offBuf = offBuf;
     3069                if (pBufDesc->pAux)
     3070                    pBufDesc->pAux->offBuf = offBuf;
     3071                if (!(pLoggerInt->fDestFlags & RTLOGFLAGS_BUFFERED))
     3072                    rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
     3073                break;
     3074            }
     3075
     3076            /* Not enough space. */
     3077            if (offBuf + 1 < cbBuf)
     3078            {
     3079                uint32_t cbToCopy = cbBuf - offBuf - 1;
     3080                memcpy(&pchBuf[offBuf], pch, cbToCopy);
     3081                offBuf += cbToCopy;
     3082                pchBuf[offBuf] = '\0';
     3083                pBufDesc->offBuf = offBuf;
     3084                if (pBufDesc->pAux)
     3085                    pBufDesc->pAux->offBuf = offBuf;
     3086                pch += cbToCopy;
     3087                cch -= cbToCopy;
     3088            }
     3089
     3090            rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
     3091        }
     3092
     3093        rtlogUnlock(pLoggerInt);
     3094    }
     3095    return rc;
     3096}
     3097RT_EXPORT_SYMBOL(RTLogBulkWrite);
     3098
    26243099#endif /* !IN_RC */
    26253100
     
    26363111     * Resolve defaults.
    26373112     */
    2638     if (!pLogger)
    2639     {
    2640 #ifdef IN_RC
    2641         pLogger = &g_Logger;
    2642 #else
    2643         pLogger = g_pLogger;
    2644 #endif
    2645         if (!pLogger)
     3113    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     3114    if (!pLoggerInt)
     3115    {
     3116        pLoggerInt = (PRTLOGGERINTERNAL)g_pLogger;
     3117        if (!pLoggerInt)
    26463118            return;
    26473119    }
     3120    Assert(pLoggerInt->Core.u32Magic == RTLOGGER_MAGIC);
     3121    AssertPtr(pLoggerInt->pBufDesc);
     3122    Assert(pLoggerInt->pBufDesc->u32Magic == RTLOGBUFFERDESC_MAGIC);
    26483123
    26493124    /*
    26503125     * Any thing to flush?
    26513126     */
    2652     if (   pLogger->offScratch
    2653 #ifndef IN_RC
    2654         || (pLogger->fDestFlags & RTLOGDEST_RINGBUF)
    2655 #endif
    2656        )
    2657     {
    2658 #ifndef IN_RC
     3127    if (   pLoggerInt->pBufDesc->offBuf > 0
     3128        || (pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF))
     3129    {
    26593130        /*
    26603131         * Acquire logger instance sem.
    26613132         */
    2662         int rc = rtlogLock(pLogger);
    2663         if (RT_FAILURE(rc))
    2664             return;
    2665 #endif
    2666         /*
    2667          * Call worker.
    2668          */
    2669         rtlogFlush(pLogger, false /*fNeedSpace*/);
    2670 
    2671 #ifndef IN_RC
    2672         /*
    2673          * Since this is an explicit flush call, the ring buffer content should
    2674          * be flushed to the other destinations if active.
    2675          */
    2676         if (   (pLogger->fDestFlags & RTLOGDEST_RINGBUF)
    2677             && pLogger->pInt->pszRingBuf /* paranoia */)
    2678             rtLogRingBufFlush(pLogger);
    2679 
    2680         /*
    2681          * Release the semaphore.
    2682          */
    2683         rtlogUnlock(pLogger);
    2684 #endif
     3133        int rc = rtlogLock(pLoggerInt);
     3134        if (RT_SUCCESS(rc))
     3135        {
     3136            /*
     3137             * Call worker.
     3138             */
     3139            rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
     3140
     3141            /*
     3142             * Since this is an explicit flush call, the ring buffer content should
     3143             * be flushed to the other destinations if active.
     3144             */
     3145            if (   (pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF)
     3146                && pLoggerInt->pszRingBuf /* paranoia */)
     3147                rtLogRingBufFlush(pLoggerInt);
     3148
     3149            /*
     3150             * Release the semaphore.
     3151             */
     3152            rtlogUnlock(pLoggerInt);
     3153        }
    26853154    }
    26863155}
     
    27283197
    27293198
     3199/**
     3200 * Worker for RTLogDefaultInstanceEx, RTLogGetDefaultInstanceEx,
     3201 * RTLogRelGetDefaultInstanceEx and RTLogCheckGroupFlags.
     3202 */
     3203DECL_FORCE_INLINE(PRTLOGGERINTERNAL) rtLogCheckGroupFlagsWorker(PRTLOGGERINTERNAL pLoggerInt, uint32_t fFlagsAndGroup)
     3204{
     3205    if (pLoggerInt->fFlags & RTLOGFLAGS_DISABLED)
     3206        pLoggerInt = NULL;
     3207    else
     3208    {
     3209        uint32_t const fFlags = RT_LO_U16(fFlagsAndGroup);
     3210        uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
     3211        if (   iGroup != UINT16_MAX
     3212             && (   (pLoggerInt->afGroups[iGroup < pLoggerInt->cGroups ? iGroup : 0] & (fFlags | RTLOGGRPFLAGS_ENABLED))
     3213                 != (fFlags | RTLOGGRPFLAGS_ENABLED)))
     3214            pLoggerInt = NULL;
     3215    }
     3216    return pLoggerInt;
     3217}
     3218
     3219
    27303220RTDECL(PRTLOGGER)   RTLogDefaultInstanceEx(uint32_t fFlagsAndGroup)
    27313221{
    2732     PRTLOGGER pLogger = rtLogDefaultInstanceCommon();
    2733     if (pLogger)
    2734     {
    2735         if (pLogger->fFlags & RTLOGFLAGS_DISABLED)
    2736             pLogger = NULL;
    2737         else
    2738         {
    2739             uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup);
    2740             uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
    2741             if (   iGroup != UINT16_MAX
    2742                  && (   (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED))
    2743                      != (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED)))
    2744                 pLogger = NULL;
    2745         }
    2746     }
    2747     return pLogger;
     3222    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)rtLogDefaultInstanceCommon();
     3223    if (pLoggerInt)
     3224        pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup);
     3225    AssertCompileMemberOffset(RTLOGGERINTERNAL, Core, 0);
     3226    return (PRTLOGGER)pLoggerInt;
    27483227}
    27493228RT_EXPORT_SYMBOL(RTLogDefaultInstanceEx);
     
    27863265RTDECL(PRTLOGGER) RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup)
    27873266{
    2788     PRTLOGGER pLogger = rtLogGetDefaultInstanceCommon();
    2789     if (pLogger)
    2790     {
    2791         if (pLogger->fFlags & RTLOGFLAGS_DISABLED)
    2792             pLogger = NULL;
    2793         else
    2794         {
    2795             uint32_t const fFlags = RT_LO_U16(fFlagsAndGroup);
    2796             uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
    2797             if (   iGroup != UINT16_MAX
    2798                  && (   (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | RTLOGGRPFLAGS_ENABLED))
    2799                      != (fFlags | RTLOGGRPFLAGS_ENABLED)))
    2800                 pLogger = NULL;
    2801         }
    2802     }
    2803     return pLogger;
     3267    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)rtLogGetDefaultInstanceCommon();
     3268    if (pLoggerInt)
     3269        pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup);
     3270    AssertCompileMemberOffset(RTLOGGERINTERNAL, Core, 0);
     3271    return (PRTLOGGER)pLoggerInt;
    28043272}
    28053273RT_EXPORT_SYMBOL(RTLogGetDefaultInstanceEx);
     
    29083376
    29093377
     3378RTDECL(PRTLOGGER)   RTLogRelGetDefaultInstance(void)
     3379{
     3380#ifdef IN_RC
     3381    return &g_RelLogger;
     3382#else /* !IN_RC */
     3383    return g_pRelLogger;
     3384#endif /* !IN_RC */
     3385}
     3386RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstance);
     3387
     3388
     3389RTDECL(PRTLOGGER)   RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup)
     3390{
     3391#ifdef IN_RC
     3392    PRTLOGGERINTERNAL pLoggerInt = &g_RelLogger;
     3393#else
     3394    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)g_pRelLogger;
     3395#endif
     3396    if (pLoggerInt)
     3397        pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup);
     3398    return (PRTLOGGER)pLoggerInt;
     3399}
     3400RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstanceEx);
     3401
     3402
     3403#ifndef IN_RC
     3404/**
     3405 * Sets the default logger instance.
     3406 *
     3407 * @returns iprt status code.
     3408 * @param   pLogger     The new default release logger instance.
     3409 */
     3410RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger)
     3411{
     3412    return ASMAtomicXchgPtrT(&g_pRelLogger, pLogger, PRTLOGGER);
     3413}
     3414RT_EXPORT_SYMBOL(RTLogRelSetDefaultInstance);
     3415#endif /* !IN_RC */
     3416
     3417
     3418/**
     3419 *
     3420 * This is the 2nd half of what RTLogGetDefaultInstanceEx() and
     3421 * RTLogRelGetDefaultInstanceEx() does.
     3422 *
     3423 * @returns If the group has the specified flags enabled @a pLogger will be
     3424 *          returned returned.  Otherwise NULL is returned.
     3425 * @param   pLogger         The logger.  NULL is NULL.
     3426 * @param   fFlagsAndGroup  The flags in the lower 16 bits, the group number in
     3427 *                          the high 16 bits.
     3428 */
     3429RTDECL(PRTLOGGER)   RTLogCheckGroupFlags(PRTLOGGER pLogger, uint32_t fFlagsAndGroup)
     3430{
     3431    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     3432    if (pLoggerInt)
     3433        pLoggerInt = rtLogCheckGroupFlagsWorker(pLoggerInt, fFlagsAndGroup);
     3434    return (PRTLOGGER)pLoggerInt;
     3435}
     3436RT_EXPORT_SYMBOL(RTLogCheckGroupFlags);
     3437
     3438
    29103439/**
    29113440 * Write to a logger instance.
     
    29383467RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
    29393468{
    2940     int rc;
     3469    PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pLogger;
     3470    int               rc;
    29413471
    29423472    /*
    29433473     * A NULL logger means default instance.
    29443474     */
    2945     if (!pLogger)
    2946     {
    2947         pLogger = RTLogDefaultInstance();
    2948         if (!pLogger)
     3475    if (!pLoggerInt)
     3476    {
     3477        pLoggerInt = (PRTLOGGERINTERNAL)RTLogDefaultInstance();
     3478        if (!pLoggerInt)
    29493479            return;
    29503480    }
     
    29533483     * Validate and correct iGroup.
    29543484     */
    2955     if (iGroup != ~0U && iGroup >= pLogger->cGroups)
     3485    if (iGroup != ~0U && iGroup >= pLoggerInt->cGroups)
    29563486        iGroup = 0;
    29573487
     
    29593489     * If no output, then just skip it.
    29603490     */
    2961     if (    (pLogger->fFlags & RTLOGFLAGS_DISABLED)
     3491    if (    (pLoggerInt->fFlags & RTLOGFLAGS_DISABLED)
    29623492#ifndef IN_RC
    2963         || !pLogger->fDestFlags
     3493        || !pLoggerInt->fDestFlags
    29643494#endif
    29653495        || !pszFormat || !*pszFormat)
    29663496        return;
    29673497    if (    iGroup != ~0U
    2968         &&  (pLogger->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))
     3498        &&  (pLoggerInt->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))
    29693499        return;
    29703500
     
    29723502     * Acquire logger instance sem.
    29733503     */
    2974     rc = rtlogLock(pLogger);
     3504    rc = rtlogLock(pLoggerInt);
    29753505    if (RT_FAILURE(rc))
    29763506    {
    29773507#ifdef IN_RING0
    2978         if (pLogger->fDestFlags & ~RTLOGDEST_FILE)
    2979             rtR0LogLoggerExFallback(pLogger->fDestFlags, pLogger->fFlags, pLogger->pInt, pszFormat, args);
     3508        if (pLoggerInt->fDestFlags & ~RTLOGDEST_FILE)
     3509            rtR0LogLoggerExFallback(pLoggerInt->fDestFlags, pLoggerInt->fFlags, pLoggerInt, pszFormat, args);
    29803510#endif
    29813511        return;
     
    29863516     */
    29873517#ifndef IN_RC
    2988     if (RT_UNLIKELY(   (pLogger->fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
    2989                     && iGroup < pLogger->cGroups
    2990                     && (pLogger->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT)
    2991                     && ++pLogger->pInt->pacEntriesPerGroup[iGroup] >= pLogger->pInt->cMaxEntriesPerGroup ))
    2992     {
    2993         uint32_t cEntries = pLogger->pInt->pacEntriesPerGroup[iGroup];
    2994         if (cEntries > pLogger->pInt->cMaxEntriesPerGroup)
    2995             pLogger->pInt->pacEntriesPerGroup[iGroup] = cEntries - 1;
     3518    if (RT_UNLIKELY(   (pLoggerInt->fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
     3519                    && iGroup < pLoggerInt->cGroups
     3520                    && (pLoggerInt->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT)
     3521                    && ++pLoggerInt->pacEntriesPerGroup[iGroup] >= pLoggerInt->cMaxEntriesPerGroup ))
     3522    {
     3523        uint32_t cEntries = pLoggerInt->pacEntriesPerGroup[iGroup];
     3524        if (cEntries > pLoggerInt->cMaxEntriesPerGroup)
     3525            pLoggerInt->pacEntriesPerGroup[iGroup] = cEntries - 1;
    29963526        else
    29973527        {
    2998             rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
    2999             if (   pLogger->pInt->papszGroups
    3000                 && pLogger->pInt->papszGroups[iGroup])
    3001                 rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n",
    3002                                      cEntries, pLogger->pInt->papszGroups[iGroup], iGroup);
     3528            rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, args);
     3529            if (   pLoggerInt->papszGroups
     3530                && pLoggerInt->papszGroups[iGroup])
     3531                rtlogLoggerExFLocked(pLoggerInt, fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n",
     3532                                     cEntries, pLoggerInt->papszGroups[iGroup], iGroup);
    30033533            else
    3004                 rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group #%u, muting it.\n",
    3005                                      cEntries, iGroup);
     3534                rtlogLoggerExFLocked(pLoggerInt, fFlags, iGroup, "%u messages from group #%u, muting it.\n", cEntries, iGroup);
    30063535        }
    30073536    }
    30083537    else
    30093538#endif
    3010         rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
     3539        rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, args);
    30113540
    30123541    /*
    30133542     * Release the semaphore.
    30143543     */
    3015     rtlogUnlock(pLogger);
     3544    rtlogUnlock(pLoggerInt);
    30163545}
    30173546RT_EXPORT_SYMBOL(RTLogLoggerExV);
     
    32113740 * Opens/creates the log file.
    32123741 *
    3213  * @param   pLogger         The logger instance to update. NULL is not allowed!
     3742 * @param   pLoggerInt      The logger instance to update. NULL is not allowed!
    32143743 * @param   pErrInfo        Where to return extended error information.
    32153744 *                          Optional.
    32163745 */
    3217 static int rtlogFileOpen(PRTLOGGER pLogger, PRTERRINFO pErrInfo)
     3746static int rtlogFileOpen(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo)
    32183747{
    32193748    uint32_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_NONE;
    3220     if (pLogger->fFlags & RTLOGFLAGS_APPEND)
     3749    if (pLoggerInt->fFlags & RTLOGFLAGS_APPEND)
    32213750        fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND;
    32223751    else
    32233752    {
    3224         RTFileDelete(pLogger->pInt->szFilename);
     3753        RTFileDelete(pLoggerInt->szFilename);
    32253754        fOpen |= RTFILE_O_CREATE;
    32263755    }
    3227     if (pLogger->fFlags & RTLOGFLAGS_WRITE_THROUGH)
     3756    if (pLoggerInt->fFlags & RTLOGFLAGS_WRITE_THROUGH)
    32283757        fOpen |= RTFILE_O_WRITE_THROUGH;
    3229     if (pLogger->fDestFlags & RTLOGDEST_F_NO_DENY)
     3758    if (pLoggerInt->fDestFlags & RTLOGDEST_F_NO_DENY)
    32303759        fOpen = (fOpen & ~RTFILE_O_DENY_NONE) | RTFILE_O_DENY_NOT_DELETE;
    32313760
    32323761    unsigned cBackoff = 0;
    3233     int rc = RTFileOpen(&pLogger->pInt->hFile, pLogger->pInt->szFilename, fOpen);
     3762    int rc = RTFileOpen(&pLoggerInt->hFile, pLoggerInt->szFilename, fOpen);
    32343763    while (   (   rc == VERR_SHARING_VIOLATION
    3235                || (rc == VERR_ALREADY_EXISTS && !(pLogger->fFlags & RTLOGFLAGS_APPEND)))
     3764               || (rc == VERR_ALREADY_EXISTS && !(pLoggerInt->fFlags & RTLOGFLAGS_APPEND)))
    32363765           && cBackoff < RT_ELEMENTS(g_acMsLogBackoff))
    32373766    {
    32383767        RTThreadSleep(g_acMsLogBackoff[cBackoff++]);
    3239         if (!(pLogger->fFlags & RTLOGFLAGS_APPEND))
    3240             RTFileDelete(pLogger->pInt->szFilename);
    3241         rc = RTFileOpen(&pLogger->pInt->hFile, pLogger->pInt->szFilename, fOpen);
     3768        if (!(pLoggerInt->fFlags & RTLOGFLAGS_APPEND))
     3769            RTFileDelete(pLoggerInt->szFilename);
     3770        rc = RTFileOpen(&pLoggerInt->hFile, pLoggerInt->szFilename, fOpen);
    32423771    }
    32433772    if (RT_SUCCESS(rc))
    32443773    {
    3245         rc = RTFileQuerySize(pLogger->pInt->hFile, &pLogger->pInt->cbHistoryFileWritten);
     3774        rc = RTFileQuerySize(pLoggerInt->hFile, &pLoggerInt->cbHistoryFileWritten);
    32463775        if (RT_FAILURE(rc))
    32473776        {
    32483777            /* Don't complain if this fails, assume the file is empty. */
    3249             pLogger->pInt->cbHistoryFileWritten = 0;
     3778            pLoggerInt->cbHistoryFileWritten = 0;
    32503779            rc = VINF_SUCCESS;
    32513780        }
     
    32533782    else
    32543783    {
    3255         pLogger->pInt->hFile = NIL_RTFILE;
    3256         RTErrInfoSetF(pErrInfo, rc, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pInt->szFilename, fOpen);
     3784        pLoggerInt->hFile = NIL_RTFILE;
     3785        RTErrInfoSetF(pErrInfo, rc, N_("could not open file '%s' (fOpen=%#x)"), pLoggerInt->szFilename, fOpen);
    32573786    }
    32583787    return rc;
     
    32653794 * Used by the rtlogFlush() function as well as RTLogCreateExV.
    32663795 *
    3267  * @param   pLogger     The logger instance to update. NULL is not allowed!
     3796 * @param   pLoggerInt  The logger instance to update. NULL is not allowed!
    32683797 * @param   uTimeSlot   Current time slot (for tikme based rotation).
    32693798 * @param   fFirst      Flag whether this is the beginning of logging, i.e.
     
    32723801 * @param   pErrInfo    Where to return extended error information. Optional.
    32733802 */
    3274 static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst, PRTERRINFO pErrInfo)
     3803static void rtlogRotate(PRTLOGGERINTERNAL pLoggerInt, uint32_t uTimeSlot, bool fFirst, PRTERRINFO pErrInfo)
    32753804{
    32763805    /* Suppress rotating empty log files simply because the time elapsed. */
    3277     if (RT_UNLIKELY(!pLogger->pInt->cbHistoryFileWritten))
    3278         pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
     3806    if (RT_UNLIKELY(!pLoggerInt->cbHistoryFileWritten))
     3807        pLoggerInt->uHistoryTimeSlotStart = uTimeSlot;
    32793808
    32803809    /* Check rotation condition: file still small enough and not too old? */
    3281     if (RT_LIKELY(   pLogger->pInt->cbHistoryFileWritten < pLogger->pInt->cbHistoryFileMax
    3282                   && uTimeSlot == pLogger->pInt->uHistoryTimeSlotStart))
     3810    if (RT_LIKELY(   pLoggerInt->cbHistoryFileWritten < pLoggerInt->cbHistoryFileMax
     3811                  && uTimeSlot == pLoggerInt->uHistoryTimeSlotStart))
    32833812        return;
    32843813
     
    32883817     * rotation would cause severe trouble otherwise.
    32893818     */
    3290     uint32_t const fSavedFlags = pLogger->fFlags;
    3291     pLogger->fFlags |= RTLOGFLAGS_DISABLED;
     3819    uint32_t const fSavedFlags = pLoggerInt->fFlags;
     3820    pLoggerInt->fFlags |= RTLOGFLAGS_DISABLED;
    32923821
    32933822    /*
     
    32953824     * chatty phase logging we could run into endless rotation.
    32963825     */
    3297     uint32_t const cSavedHistory = pLogger->pInt->cHistory;
    3298     pLogger->pInt->cHistory = 0;
     3826    uint32_t const cSavedHistory = pLoggerInt->cHistory;
     3827    pLoggerInt->cHistory = 0;
    32993828
    33003829    /*
    33013830     * Close the old log file.
    33023831     */
    3303     if (pLogger->pInt->hFile != NIL_RTFILE)
     3832    if (pLoggerInt->hFile != NIL_RTFILE)
    33043833    {
    33053834        /* Use the callback to generate some final log contents, but only if
    33063835         * this is a rotation with a fully set up logger. Leave the other case
    33073836         * to the RTLogCreateExV function. */
    3308         if (pLogger->pInt->pfnPhase && !fFirst)
    3309         {
    3310             uint32_t fODestFlags = pLogger->fDestFlags;
    3311             pLogger->fDestFlags &= RTLOGDEST_FILE;
    3312             pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);
    3313             pLogger->fDestFlags = fODestFlags;
    3314         }
    3315         RTFileClose(pLogger->pInt->hFile);
    3316         pLogger->pInt->hFile = NIL_RTFILE;
     3837        if (pLoggerInt->pfnPhase && !fFirst)
     3838        {
     3839            uint32_t fODestFlags = pLoggerInt->fDestFlags;
     3840            pLoggerInt->fDestFlags &= RTLOGDEST_FILE;
     3841            pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);
     3842            pLoggerInt->fDestFlags = fODestFlags;
     3843        }
     3844        RTFileClose(pLoggerInt->hFile);
     3845        pLoggerInt->hFile = NIL_RTFILE;
    33173846    }
    33183847
     
    33243853        for (uint32_t i = cSavedHistory - 1; i + 1 > 0; i--)
    33253854        {
    3326             char szOldName[sizeof(pLogger->pInt->szFilename) + 32];
     3855            char szOldName[sizeof(pLoggerInt->szFilename) + 32];
    33273856            if (i > 0)
    3328                 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pInt->szFilename, i);
     3857                RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLoggerInt->szFilename, i);
    33293858            else
    3330                 RTStrCopy(szOldName, sizeof(szOldName), pLogger->pInt->szFilename);
    3331 
    3332             char szNewName[sizeof(pLogger->pInt->szFilename) + 32];
    3333             RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pInt->szFilename, i + 1);
     3859                RTStrCopy(szOldName, sizeof(szOldName), pLoggerInt->szFilename);
     3860
     3861            char szNewName[sizeof(pLoggerInt->szFilename) + 32];
     3862            RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLoggerInt->szFilename, i + 1);
    33343863
    33353864            unsigned cBackoff = 0;
     
    33513880        for (uint32_t i = cSavedHistory + 1; ; i++)
    33523881        {
    3353             char szExcessName[sizeof(pLogger->pInt->szFilename) + 32];
    3354             RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pInt->szFilename, i);
     3882            char szExcessName[sizeof(pLoggerInt->szFilename) + 32];
     3883            RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLoggerInt->szFilename, i);
    33553884            int rc = RTFileDelete(szExcessName);
    33563885            if (RT_FAILURE(rc))
     
    33623891     * Update logger state and create new log file.
    33633892     */
    3364     pLogger->pInt->cbHistoryFileWritten = 0;
    3365     pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
    3366     rtlogFileOpen(pLogger, pErrInfo);
     3893    pLoggerInt->cbHistoryFileWritten = 0;
     3894    pLoggerInt->uHistoryTimeSlotStart = uTimeSlot;
     3895    rtlogFileOpen(pLoggerInt, pErrInfo);
    33673896
    33683897    /*
     
    33713900     * RTLogCreateExV function.
    33723901     */
    3373     if (pLogger->pInt->pfnPhase && !fFirst)
    3374     {
    3375         uint32_t const fSavedDestFlags = pLogger->fDestFlags;
    3376         pLogger->fDestFlags &= RTLOGDEST_FILE;
    3377         pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);
    3378         pLogger->fDestFlags = fSavedDestFlags;
     3902    if (pLoggerInt->pfnPhase && !fFirst)
     3903    {
     3904        uint32_t const fSavedDestFlags = pLoggerInt->fDestFlags;
     3905        pLoggerInt->fDestFlags &= RTLOGDEST_FILE;
     3906        pLoggerInt->pfnPhase(&pLoggerInt->Core, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);
     3907        pLoggerInt->fDestFlags = fSavedDestFlags;
    33793908    }
    33803909
    33813910    /* Restore saved values. */
    3382     pLogger->pInt->cHistory = cSavedHistory;
    3383     pLogger->fFlags         = fSavedFlags;
     3911    pLoggerInt->cHistory = cSavedHistory;
     3912    pLoggerInt->fFlags   = fSavedFlags;
    33843913}
    33853914
     
    33913920 *
    33923921 * @returns IPRT status code.
    3393  * @param   pLogger             The logger.
     3922 * @param   pLoggerInt          The logger.
    33943923 * @param   pErrInfo            Where to return extended error information.
    33953924 *                              Optional.
    33963925 */
    3397 static int rtR3LogOpenFileDestination(PRTLOGGER pLogger, PRTERRINFO pErrInfo)
     3926static int rtR3LogOpenFileDestination(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo)
    33983927{
    33993928    int rc;
    3400     if (pLogger->fFlags & RTLOGFLAGS_APPEND)
    3401     {
    3402         rc = rtlogFileOpen(pLogger, pErrInfo);
     3929    if (pLoggerInt->fFlags & RTLOGFLAGS_APPEND)
     3930    {
     3931        rc = rtlogFileOpen(pLoggerInt, pErrInfo);
    34033932
    34043933        /* Rotate in case of appending to a too big log file,
    34053934           otherwise this simply doesn't do anything. */
    3406         rtlogRotate(pLogger, 0, true /* fFirst */, pErrInfo);
     3935        rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo);
    34073936    }
    34083937    else
    34093938    {
    34103939        /* Force rotation if it is configured. */
    3411         pLogger->pInt->cbHistoryFileWritten = UINT64_MAX;
    3412         rtlogRotate(pLogger, 0, true /* fFirst */, pErrInfo);
     3940        pLoggerInt->cbHistoryFileWritten = UINT64_MAX;
     3941        rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo);
    34133942
    34143943        /* If the file is not open then rotation is not set up. */
    3415         if (pLogger->pInt->hFile == NIL_RTFILE)
    3416         {
    3417             pLogger->pInt->cbHistoryFileWritten = 0;
    3418             rc = rtlogFileOpen(pLogger, pErrInfo);
     3944        if (pLoggerInt->hFile == NIL_RTFILE)
     3945        {
     3946            pLoggerInt->cbHistoryFileWritten = 0;
     3947            rc = rtlogFileOpen(pLoggerInt, pErrInfo);
    34193948        }
    34203949        else
     
    34333962 * Used by the RTLogFlush() function.
    34343963 *
    3435  * @param   pLogger     The logger instance to write to. NULL is not allowed!
     3964 * @param   pLoggerInt  The logger instance to write to. NULL is not allowed!
    34363965 * @param   fNeedSpace  Set if the caller assumes space will be made available.
    34373966 */
    3438 static void rtlogFlush(PRTLOGGER pLogger, bool fNeedSpace)
    3439 {
    3440     uint32_t const cchScratch = pLogger->offScratch;
    3441     if (cchScratch == 0)
     3967static void rtlogFlush(PRTLOGGERINTERNAL pLoggerInt, bool fNeedSpace)
     3968{
     3969    PRTLOGBUFFERDESC const pBufDesc   = pLoggerInt->pBufDesc;
     3970    uint32_t               cchToFlush = pBufDesc->offBuf;
     3971    char * const           pchToFlush = pBufDesc->pchBuf;
     3972    uint32_t const         cbBuf      = pBufDesc->cbBuf;
     3973    Assert(pBufDesc->u32Magic == RTLOGBUFFERDESC_MAGIC);
     3974
     3975    NOREF(fNeedSpace);
     3976    if (cchToFlush == 0)
    34423977        return; /* nothing to flush. */
    3443     NOREF(fNeedSpace);
    3444 
    3445 #ifndef IN_RC
     3978
     3979    AssertPtrReturnVoid(pchToFlush);
     3980    AssertReturnVoid(cbBuf > 0);
     3981    AssertMsgStmt(cchToFlush < cbBuf, ("%#x vs %#x\n", cchToFlush, cbBuf), cchToFlush = cbBuf - 1);
     3982
    34463983    /*
    34473984     * If the ring buffer is active, the other destinations are only written
    34483985     * to when the ring buffer is flushed by RTLogFlush().
    34493986     */
    3450     if (   (pLogger->fDestFlags & RTLOGDEST_RINGBUF)
    3451         && pLogger->pInt
    3452         && pLogger->pInt->pszRingBuf /* paraoia */)
    3453     {
    3454         rtLogRingBufWrite(pLogger->pInt, pLogger->achScratch, pLogger->offScratch);
    3455         pLogger->offScratch = 0; /* empty the buffer. */
     3987    if (   (pLoggerInt->fDestFlags & RTLOGDEST_RINGBUF)
     3988        && pLoggerInt->pszRingBuf /* paranoia */)
     3989    {
     3990        rtLogRingBufWrite(pLoggerInt, pchToFlush, cchToFlush);
     3991
     3992        /* empty the buffer. */
     3993        pBufDesc->offBuf = 0;
     3994        *pchToFlush      = '\0';
    34563995    }
    34573996    /*
     
    34603999     */
    34614000    else
    3462 # ifdef IN_RING3
    3463         if (!(pLogger->fDestFlags & RTLOGDEST_F_DELAY_FILE))
    3464 # endif
     4001#ifdef IN_RING3
     4002         if (!(pLoggerInt->fDestFlags & RTLOGDEST_F_DELAY_FILE))
    34654003#endif
    34664004    {
    34674005        /* Make sure the string is terminated.  On Windows, RTLogWriteDebugger
    34684006           will get upset if it isn't. */
    3469         if (RT_LIKELY(cchScratch < sizeof(pLogger->achScratch)))
    3470             pLogger->achScratch[cchScratch] = '\0';
    3471         else
    3472             AssertFailed();
    3473 
    3474 #ifndef IN_RC
    3475         if (pLogger->fDestFlags & RTLOGDEST_USER)
    3476             RTLogWriteUser(pLogger->achScratch, cchScratch);
    3477 
    3478         if (pLogger->fDestFlags & RTLOGDEST_DEBUGGER)
    3479             RTLogWriteDebugger(pLogger->achScratch, cchScratch);
    3480 
    3481 # ifdef IN_RING3
    3482         if ((pLogger->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_RINGBUF)) == RTLOGDEST_FILE)
    3483         {
    3484             if (pLogger->pInt->hFile != NIL_RTFILE)
     4007        pchToFlush[cchToFlush] = '\0';
     4008
     4009        if (pLoggerInt->fDestFlags & RTLOGDEST_USER)
     4010            RTLogWriteUser(pchToFlush, cchToFlush);
     4011
     4012        if (pLoggerInt->fDestFlags & RTLOGDEST_DEBUGGER)
     4013            RTLogWriteDebugger(pchToFlush, cchToFlush);
     4014
     4015#ifdef IN_RING3
     4016        if ((pLoggerInt->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_RINGBUF)) == RTLOGDEST_FILE)
     4017        {
     4018            if (pLoggerInt->hFile != NIL_RTFILE)
    34854019            {
    3486                 RTFileWrite(pLogger->pInt->hFile, pLogger->achScratch, cchScratch, NULL);
    3487                 if (pLogger->fFlags & RTLOGFLAGS_FLUSH)
    3488                     RTFileFlush(pLogger->pInt->hFile);
     4020                RTFileWrite(pLoggerInt->hFile, pchToFlush, cchToFlush, NULL);
     4021                if (pLoggerInt->fFlags & RTLOGFLAGS_FLUSH)
     4022                    RTFileFlush(pLoggerInt->hFile);
    34894023            }
    3490             if (pLogger->pInt->cHistory)
    3491                 pLogger->pInt->cbHistoryFileWritten += cchScratch;
    3492         }
    3493 # endif
    3494 
    3495         if (pLogger->fDestFlags & RTLOGDEST_STDOUT)
    3496             RTLogWriteStdOut(pLogger->achScratch, cchScratch);
    3497 
    3498         if (pLogger->fDestFlags & RTLOGDEST_STDERR)
    3499             RTLogWriteStdErr(pLogger->achScratch, cchScratch);
    3500 
    3501 # if (defined(IN_RING0) || defined(IN_RC)) && !defined(LOG_NO_COM)
    3502         if (pLogger->fDestFlags & RTLOGDEST_COM)
    3503             RTLogWriteCom(pLogger->achScratch, cchScratch);
    3504 # endif
    3505 #endif /* !IN_RC */
    3506 
    3507 #ifdef IN_RC
    3508         if (pLogger->pfnFlush)
    3509             pLogger->pfnFlush(pLogger);
    3510 #else
    3511         if (pLogger->pInt->pfnFlush)
    3512             pLogger->pInt->pfnFlush(pLogger);
     4024            if (pLoggerInt->cHistory)
     4025                pLoggerInt->cbHistoryFileWritten += cchToFlush;
     4026        }
    35134027#endif
    35144028
     4029        if (pLoggerInt->fDestFlags & RTLOGDEST_STDOUT)
     4030            RTLogWriteStdOut(pchToFlush, cchToFlush);
     4031
     4032        if (pLoggerInt->fDestFlags & RTLOGDEST_STDERR)
     4033            RTLogWriteStdErr(pchToFlush, cchToFlush);
     4034
     4035#if (defined(IN_RING0) || defined(IN_RC)) && !defined(LOG_NO_COM)
     4036        if (pLoggerInt->fDestFlags & RTLOGDEST_COM)
     4037            RTLogWriteCom(pchToFlush, cchToFlush);
     4038#endif
     4039
     4040        if (pLoggerInt->pfnFlush)
     4041        {
     4042            /** @todo implement asynchronous buffer switching protocol. */
     4043            bool fDone;
     4044            if (pBufDesc->pAux)
     4045                pBufDesc->pAux->offBuf = cchToFlush;
     4046            fDone = pLoggerInt->pfnFlush(&pLoggerInt->Core, pBufDesc);
     4047            Assert(fDone == true); RT_NOREF(fDone);
     4048        }
     4049
    35154050        /* empty the buffer. */
    3516         pLogger->offScratch = 0;
     4051        pBufDesc->offBuf = 0;
     4052        if (pBufDesc->pAux)
     4053            pBufDesc->pAux->offBuf = 0;
     4054        *pchToFlush      = '\0';
    35174055
    35184056#ifdef IN_RING3
     
    35224060         * and footer messages.
    35234061         */
    3524         if (   (pLogger->fDestFlags & RTLOGDEST_FILE)
    3525             && pLogger->pInt->cHistory)
    3526             rtlogRotate(pLogger, RTTimeProgramSecTS() / pLogger->pInt->cSecsHistoryTimeSlot, false /*fFirst*/, NULL /*pErrInfo*/);
     4062        if (   pLoggerInt->cHistory > 0
     4063            && (pLoggerInt->fDestFlags & RTLOGDEST_FILE))
     4064            rtlogRotate(pLoggerInt, RTTimeProgramSecTS() / pLoggerInt->cSecsHistoryTimeSlot, false /*fFirst*/, NULL /*pErrInfo*/);
    35274065#endif
    35284066    }
     
    35344072         * buffer and insert a message indicating that we've dropped output.
    35354073         */
    3536         uint32_t offHalf = sizeof(pLogger->achScratch) / 2;
    3537         if (cchScratch > offHalf)
    3538         {
    3539             if (pLogger->fFlags & RTLOGFLAGS_USECRLF)
    3540                 pLogger->achScratch[offHalf++] = '\r';
    3541             static const char s_szDropMsg[] = "\n[DROP DROP DROP]";
    3542             memcpy(&pLogger->achScratch[offHalf], RT_STR_TUPLE(s_szDropMsg));
    3543             offHalf += sizeof(s_szDropMsg) - 1;
    3544             if (pLogger->fFlags & RTLOGFLAGS_USECRLF)
    3545                 pLogger->achScratch[offHalf++] = '\r';
    3546             pLogger->achScratch[offHalf++] = '\n';
    3547 
    3548             pLogger->offScratch = offHalf;
     4074        uint32_t offHalf = cbBuf / 2;
     4075        if (cchToFlush > offHalf)
     4076        {
     4077            static const char s_szDropMsgLf[]   = "\n[DROP DROP DROP]\n";
     4078            static const char s_szDropMsgCrLf[] = "\r\n[DROP DROP DROP]\r\n";
     4079            if (!(pLoggerInt->fFlags & RTLOGFLAGS_USECRLF))
     4080            {
     4081                memcpy(&pchToFlush[offHalf], RT_STR_TUPLE(s_szDropMsgLf));
     4082                offHalf += sizeof(s_szDropMsgLf) - 1;
     4083            }
     4084            else
     4085            {
     4086                memcpy(&pchToFlush[offHalf], RT_STR_TUPLE(s_szDropMsgCrLf));
     4087                offHalf += sizeof(s_szDropMsgCrLf) - 1;
     4088            }
     4089            pBufDesc->offBuf = offHalf;
    35494090        }
    35504091    }
     
    35594100static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars)
    35604101{
    3561     PRTLOGGER pLogger = (PRTLOGGER)pv;
     4102    PRTLOGGERINTERNAL pLoggerInt  = (PRTLOGGERINTERNAL)pv;
    35624103    if (cbChars)
    35634104    {
     
    35654106        for (;;)
    35664107        {
    3567 #if defined(DEBUG) && defined(IN_RING3)
    3568             /* sanity */
    3569             if (pLogger->offScratch >= sizeof(pLogger->achScratch))
     4108            PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc;
     4109            if (pBufDesc->offBuf < pBufDesc->cbBuf)
    35704110            {
    3571                 fprintf(stderr, "pLogger->offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",
    3572                         pLogger->offScratch, (unsigned)sizeof(pLogger->achScratch));
     4111                /* how much */
     4112                char    *pchBuf = pBufDesc->pchBuf;
     4113                uint32_t offBuf = pBufDesc->offBuf;
     4114                size_t   cb     = pBufDesc->cbBuf - offBuf - 1;
     4115                if (cb > cbChars)
     4116                    cb = cbChars;
     4117
     4118                switch (cb)
     4119                {
     4120                    default:
     4121                        memcpy(&pchBuf[offBuf], pachChars, cb);
     4122                        pBufDesc->offBuf   = offBuf + (uint32_t)cb;
     4123                        cbRet             += cb;
     4124                        cbChars           -= cb;
     4125                        if (cbChars <= 0)
     4126                            return cbRet;
     4127                        pachChars += cb;
     4128                        break;
     4129
     4130                    case 1:
     4131                        pchBuf[offBuf]     = pachChars[0];
     4132                        pBufDesc->offBuf   = offBuf + 1;
     4133                        if (cbChars == 1)
     4134                            return cbRet + 1;
     4135                        cbChars   -= 1;
     4136                        pachChars += 1;
     4137                        break;
     4138
     4139                    case 2:
     4140                        pchBuf[offBuf]     = pachChars[0];
     4141                        pchBuf[offBuf + 1] = pachChars[1];
     4142                        pBufDesc->offBuf   = offBuf + 2;
     4143                        if (cbChars == 2)
     4144                            return cbRet + 2;
     4145                        cbChars   -= 2;
     4146                        pachChars += 2;
     4147                        break;
     4148
     4149                    case 3:
     4150                        pchBuf[offBuf]     = pachChars[0];
     4151                        pchBuf[offBuf + 1] = pachChars[1];
     4152                        pchBuf[offBuf + 2] = pachChars[2];
     4153                        pBufDesc->offBuf   = offBuf + 3;
     4154                        if (cbChars == 3)
     4155                            return cbRet + 3;
     4156                        cbChars   -= 3;
     4157                        pachChars += 3;
     4158                        break;
     4159                }
     4160
     4161            }
     4162#if defined(RT_STRICT) && defined(IN_RING3)
     4163            else
     4164            {
     4165                fprintf(stderr, "pBufDesc->offBuf >= pBufDesc->cbBuf (%#x >= %#x)\n", pBufDesc->offBuf, pBufDesc->cbBuf);
    35734166                AssertBreakpoint(); AssertBreakpoint();
    35744167            }
    35754168#endif
    35764169
    3577             /* how much */
    3578             size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
    3579             if (cb > cbChars)
    3580                 cb = cbChars;
    3581 
    3582             /* copy */
    3583             memcpy(&pLogger->achScratch[pLogger->offScratch], pachChars, cb);
    3584 
    3585             /* advance */
    3586             pLogger->offScratch += (uint32_t)cb;
    3587             cbRet += cb;
    3588             cbChars -= cb;
    3589 
    3590             /* done? */
    3591             if (cbChars <= 0)
    3592                 return cbRet;
    3593 
    3594             pachChars += cb;
    3595 
    35964170            /* flush */
    3597             rtlogFlush(pLogger, true /*fNeedSpace*/);
     4171            rtlogFlush(pLoggerInt, true /*fNeedSpace*/);
    35984172        }
    35994173
     
    36064180         * There's always space for a terminator, and it's not counted.
    36074181         */
    3608         pLogger->achScratch[pLogger->offScratch] = '\0';
     4182        PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc;
     4183        pBufDesc->pchBuf[RT_MIN(pBufDesc->offBuf, pBufDesc->cbBuf - 1)] = '\0';
    36094184        return 0;
    36104185    }
     
    36784253static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars)
    36794254{
    3680     PRTLOGOUTPUTPREFIXEDARGS    pArgs = (PRTLOGOUTPUTPREFIXEDARGS)pv;
    3681     PRTLOGGER                   pLogger = pArgs->pLogger;
     4255    PRTLOGOUTPUTPREFIXEDARGS    pArgs      = (PRTLOGOUTPUTPREFIXEDARGS)pv;
     4256    PRTLOGGERINTERNAL           pLoggerInt = pArgs->pLoggerInt;
    36824257    if (cbChars)
    36834258    {
     
    36854260        for (;;)
    36864261        {
    3687             uint32_t    offScratch = pLogger->offScratch;
    3688             size_t      cb         = sizeof(pLogger->achScratch) - offScratch - 1;
    3689             const char *pszNewLine;
    3690             char       *psz;
    3691 #ifdef IN_RC
    3692             bool       *pfPendingPrefix = &pLogger->fPendingPrefix;
    3693 #else
    3694             bool       *pfPendingPrefix = &pLogger->pInt->fPendingPrefix;
     4262            PRTLOGBUFFERDESC const  pBufDesc = pLoggerInt->pBufDesc;
     4263            char * const            pchBuf   = pBufDesc->pchBuf;
     4264            uint32_t const          cbBuf    = pBufDesc->cbBuf;
     4265            uint32_t                offBuf   = pBufDesc->offBuf;
     4266            size_t                  cb       = cbBuf - offBuf - 1;
     4267            const char             *pszNewLine;
     4268            char                   *psz;
     4269
     4270#if defined(RT_STRICT) && defined(IN_RING3)
     4271            /* sanity */
     4272            if (offBuf < cbBuf)
     4273            { /* likely */ }
     4274            else
     4275            {
     4276                fprintf(stderr, "offBuf >= cbBuf (%#x >= %#x)\n", offBuf, cbBuf);
     4277                AssertBreakpoint(); AssertBreakpoint();
     4278            }
    36954279#endif
    36964280
     
    36984282             * Pending prefix?
    36994283             */
    3700             if (*pfPendingPrefix)
     4284            if (pLoggerInt->fPendingPrefix)
    37014285            {
    3702                 *pfPendingPrefix = false;
    3703 
    3704 #if defined(DEBUG) && defined(IN_RING3)
    3705                 /* sanity */
    3706                 if (offScratch >= sizeof(pLogger->achScratch))
    3707                 {
    3708                     fprintf(stderr, "offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",
    3709                             offScratch, (unsigned)sizeof(pLogger->achScratch));
    3710                     AssertBreakpoint(); AssertBreakpoint();
    3711                 }
    3712 #endif
    3713 
    37144286                /*
    37154287                 * Flush the buffer if there isn't enough room for the maximum prefix config.
    37164288                 * Max is 256, add a couple of extra bytes.  See CCH_PREFIX check way below.
    37174289                 */
    3718                 if (cb < 256 + 16)
     4290                if (cb >= 256 + 16)
     4291                    pLoggerInt->fPendingPrefix = false;
     4292                else
    37194293                {
    3720                     rtlogFlush(pLogger, true /*fNeedSpace*/);
    3721                     offScratch = pLogger->offScratch;
    3722                     cb = sizeof(pLogger->achScratch) - offScratch - 1;
     4294                    rtlogFlush(pLoggerInt, true /*fNeedSpace*/);
     4295                    continue;
    37234296                }
    37244297
     
    37274300                 * psz is pointing to the current position.
    37284301                 */
    3729                 psz = &pLogger->achScratch[offScratch];
    3730                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TS)
     4302                psz = &pchBuf[offBuf];
     4303                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TS)
    37314304                {
    37324305                    uint64_t     u64    = RTTimeNanoTS();
    37334306                    int          iBase  = 16;
    37344307                    unsigned int fFlags = RTSTR_F_ZEROPAD;
    3735                     if (pLogger->fFlags & RTLOGFLAGS_DECIMAL_TS)
     4308                    if (pLoggerInt->fFlags & RTLOGFLAGS_DECIMAL_TS)
    37364309                    {
    37374310                        iBase = 10;
    37384311                        fFlags = 0;
    37394312                    }
    3740                     if (pLogger->fFlags & RTLOGFLAGS_REL_TS)
     4313                    if (pLoggerInt->fFlags & RTLOGFLAGS_REL_TS)
    37414314                    {
    37424315                        static volatile uint64_t s_u64LastTs;
     
    37544327#define CCH_PREFIX_01   0 + 17
    37554328
    3756                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TSC)
     4329                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TSC)
    37574330                {
    37584331#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     
    37634336                    int          iBase  = 16;
    37644337                    unsigned int fFlags = RTSTR_F_ZEROPAD;
    3765                     if (pLogger->fFlags & RTLOGFLAGS_DECIMAL_TS)
     4338                    if (pLoggerInt->fFlags & RTLOGFLAGS_DECIMAL_TS)
    37664339                    {
    37674340                        iBase = 10;
    37684341                        fFlags = 0;
    37694342                    }
    3770                     if (pLogger->fFlags & RTLOGFLAGS_REL_TS)
     4343                    if (pLoggerInt->fFlags & RTLOGFLAGS_REL_TS)
    37714344                    {
    37724345                        static volatile uint64_t s_u64LastTsc;
     
    37844357#define CCH_PREFIX_02   CCH_PREFIX_01 + 17
    37854358
    3786                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_MS_PROG)
     4359                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_MS_PROG)
    37874360                {
    37884361#if defined(IN_RING3) || defined(IN_RC)
    37894362                    uint64_t u64 = RTTimeProgramMilliTS();
    37904363#else
    3791                     uint64_t u64 = (RTTimeNanoTS() - pLogger->pInt->nsR0ProgramStart) / RT_NS_1MS;
     4364                    uint64_t u64 = (RTTimeNanoTS() - pLoggerInt->nsR0ProgramStart) / RT_NS_1MS;
    37924365#endif
    37934366                    /* 1E8 milliseconds = 27 hours */
     
    37974370#define CCH_PREFIX_03   CCH_PREFIX_02 + 21
    37984371
    3799                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TIME)
     4372                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TIME)
    38004373                {
    38014374#if defined(IN_RING3) || defined(IN_RING0)
     
    38184391#define CCH_PREFIX_04   CCH_PREFIX_03 + (3+1+3+1+3+1+7+1)
    38194392
    3820                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TIME_PROG)
     4393                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TIME_PROG)
    38214394                {
    38224395
     
    38244397                    uint64_t u64 = RTTimeProgramMicroTS();
    38254398#else
    3826                     uint64_t u64 = (RTTimeNanoTS() - pLogger->pInt->nsR0ProgramStart) / RT_NS_1US;
     4399                    uint64_t u64 = (RTTimeNanoTS() - pLoggerInt->nsR0ProgramStart) / RT_NS_1US;
    38274400
    38284401#endif
     
    38424415
    38434416# if 0
    3844                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_DATETIME)
     4417                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_DATETIME)
    38454418                {
    38464419                    char szDate[32];
     
    38574430# endif
    38584431
    3859                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_PID)
     4432                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_PID)
    38604433                {
    38614434#ifndef IN_RC
     
    38694442#define CCH_PREFIX_07   CCH_PREFIX_06 + 9
    38704443
    3871                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TID)
     4444                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_TID)
    38724445                {
    38734446#ifndef IN_RC
     
    38814454#define CCH_PREFIX_08   CCH_PREFIX_07 + 17
    38824455
    3883                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_THREAD)
     4456                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_THREAD)
    38844457                {
    38854458#ifdef IN_RING3
     
    38884461                    const char *pszName = "EMT-RC";
    38894462#else
    3890                     const char *pszName = pLogger->pInt->szR0ThreadName[0] ? pLogger->pInt->szR0ThreadName : "R0";
     4463                    const char *pszName = pLoggerInt->szR0ThreadName[0] ? pLoggerInt->szR0ThreadName : "R0";
    38914464#endif
    38924465                    psz = rtLogStPNCpyPad(psz, pszName, 16, 8);
     
    38944467#define CCH_PREFIX_09   CCH_PREFIX_08 + 17
    38954468
    3896                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_CPUID)
     4469                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_CPUID)
    38974470                {
    38984471#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     
    39074480
    39084481#ifndef IN_RC
    3909                 if (    (pLogger->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)
    3910                     &&  pLogger->pInt->pfnPrefix)
     4482                if (    (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)
     4483                    &&  pLoggerInt->pfnPrefix)
    39114484                {
    3912                     psz += pLogger->pInt->pfnPrefix(pLogger, psz, 31, pLogger->pInt->pvPrefixUserArg);
     4485                    psz += pLoggerInt->pfnPrefix(&pLoggerInt->Core, psz, 31, pLoggerInt->pvPrefixUserArg);
    39134486                    *psz++ = ' ';                                                               /* +32 */
    39144487                }
     
    39164489#define CCH_PREFIX_11   CCH_PREFIX_10 + 32
    39174490
    3918                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_LOCK_COUNTS)
     4491                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_LOCK_COUNTS)
    39194492                {
    39204493#ifdef IN_RING3 /** @todo implement these counters in ring-0 too? */
     
    39414514#define CCH_PREFIX_12   CCH_PREFIX_11 + 8
    39424515
    3943                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_FLAG_NO)
     4516                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_FLAG_NO)
    39444517                {
    39454518                    psz += RTStrFormatNumber(psz, pArgs->fFlags, 16, 8, 0, RTSTR_F_ZEROPAD);
     
    39484521#define CCH_PREFIX_13   CCH_PREFIX_12 + 9
    39494522
    3950                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_FLAG)
     4523                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_FLAG)
    39514524                {
    39524525#ifdef IN_RING3
    3953                     const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->pInt->papszGroups[pArgs->iGroup] : NULL;
     4526                    const char *pszGroup = pArgs->iGroup != ~0U ? pLoggerInt->papszGroups[pArgs->iGroup] : NULL;
    39544527#else
    39554528                    const char *pszGroup = NULL;
     
    39594532#define CCH_PREFIX_14   CCH_PREFIX_13 + 17
    39604533
    3961                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_GROUP_NO)
     4534                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_GROUP_NO)
    39624535                {
    39634536                    if (pArgs->iGroup != ~0U)
     
    39744547#define CCH_PREFIX_15   CCH_PREFIX_14 + 9
    39754548
    3976                 if (pLogger->fFlags & RTLOGFLAGS_PREFIX_GROUP)
     4549                if (pLoggerInt->fFlags & RTLOGFLAGS_PREFIX_GROUP)
    39774550                {
    3978                     const unsigned fGrp = pLogger->afGroups[pArgs->iGroup != ~0U ? pArgs->iGroup : 0];
     4551                    const unsigned fGrp = pLoggerInt->afGroups[pArgs->iGroup != ~0U ? pArgs->iGroup : 0];
    39794552                    const char *pszGroup;
    39804553                    size_t cchGroup;
     
    40094582                 * Done, figure what we've used and advance the buffer and free size.
    40104583                 */
    4011                 cb = psz - &pLogger->achScratch[offScratch];
    4012                 AssertMsg(cb <= 223, ("%#zx (%zd) - fFlags=%#x\n", cb, cb, pLogger->fFlags));
    4013                 pLogger->offScratch = offScratch += (uint32_t)cb;
    4014                 cb = sizeof(pLogger->achScratch) - offScratch - 1;
     4584                AssertMsg(psz - &pchBuf[offBuf] <= 223,
     4585                          ("%#zx (%zd) - fFlags=%#x\n", psz - &pchBuf[offBuf], psz - &pchBuf[offBuf], pLoggerInt->fFlags));
     4586                pBufDesc->offBuf = offBuf = (uint32_t)(psz - pchBuf);
     4587                cb = cbBuf - offBuf - 1;
    40154588            }
    40164589            else if (cb <= 0)
    40174590            {
    4018                 rtlogFlush(pLogger, true /*fNeedSpace*/);
    4019                 offScratch = pLogger->offScratch;
    4020                 cb = sizeof(pLogger->achScratch) - offScratch - 1;
     4591                rtlogFlush(pLoggerInt, true /*fNeedSpace*/);
     4592                continue;
    40214593            }
    4022 
    4023 #if defined(DEBUG) && defined(IN_RING3)
    4024             /* sanity */
    4025             if (offScratch >= sizeof(pLogger->achScratch))
    4026             {
    4027                 fprintf(stderr, "offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",
    4028                         offScratch, (unsigned)sizeof(pLogger->achScratch));
    4029                 AssertBreakpoint(); AssertBreakpoint();
    4030             }
    4031 #endif
    40324594
    40334595            /* how much */
     
    40394601            if (pszNewLine)
    40404602            {
    4041                 if (pLogger->fFlags & RTLOGFLAGS_USECRLF)
     4603                if (!(pLoggerInt->fFlags & RTLOGFLAGS_USECRLF))
     4604                {
     4605                    cb = pszNewLine - pachChars + 1;
     4606                    memcpy(&pchBuf[offBuf], pachChars, cb);
     4607                    pLoggerInt->fPendingPrefix = true;
     4608                }
     4609                else if (cbBuf - offBuf < (uintptr_t)(pszNewLine - pachChars + 2))
     4610                {
    40424611                    cb = pszNewLine - pachChars;
     4612                    memcpy(&pchBuf[offBuf], pachChars, cb);
     4613                    pchBuf[offBuf + cb++] = '\r';
     4614                    pchBuf[offBuf + cb++] = '\n';
     4615                    pachChars--;    /* Discount the extra '\r'. */
     4616                    cbChars++;      /* Discount the extra '\r'. */
     4617                    cbRet--;        /* Ditto. */
     4618                    pLoggerInt->fPendingPrefix = true;
     4619                }
    40434620                else
    40444621                {
    4045                     cb = pszNewLine - pachChars + 1;
    4046                     *pfPendingPrefix = true;
     4622                    /* Insufficient buffer space, leave the '\n' for the next iteration. */
     4623                    cb = pszNewLine - pachChars;
     4624                    memcpy(&pchBuf[offBuf], pachChars, cb);
    40474625                }
    40484626            }
    4049 
    4050             /* copy */
    4051             memcpy(&pLogger->achScratch[offScratch], pachChars, cb);
     4627            else
     4628                memcpy(&pchBuf[offBuf], pachChars, cb);
    40524629
    40534630            /* advance */
    4054             pLogger->offScratch = offScratch += (uint32_t)cb;
    4055             cbRet += cb;
     4631            pBufDesc->offBuf = offBuf += (uint32_t)cb;
     4632            cbRet   += cb;
    40564633            cbChars -= cb;
    4057 
    4058             if (    pszNewLine
    4059                 &&  (pLogger->fFlags & RTLOGFLAGS_USECRLF)
    4060                 &&  offScratch + 2 < sizeof(pLogger->achScratch))
    4061             {
    4062                 memcpy(&pLogger->achScratch[offScratch], "\r\n", 2);
    4063                 pLogger->offScratch = offScratch += 2;
    4064                 cbRet++;
    4065                 cbChars--;
    4066                 cb++;
    4067                 *pfPendingPrefix = true;
    4068             }
    40694634
    40704635            /* done? */
     
    40824647         * There's always space for a terminator, and it's not counted.
    40834648         */
    4084         pLogger->achScratch[pLogger->offScratch] = '\0';
     4649        PRTLOGBUFFERDESC const pBufDesc = pLoggerInt->pBufDesc;
     4650        pBufDesc->pchBuf[RT_MIN(pBufDesc->offBuf, pBufDesc->cbBuf - 1)] = '\0';
    40854651        return 0;
    40864652    }
     
    40944660 * logging kind which is currently enabled before writing anything to the log.
    40954661 *
    4096  * @param   pLogger     Pointer to logger instance. Must be non-NULL.
     4662 * @param   pLoggerInt  Pointer to logger instance. Must be non-NULL.
    40974663 * @param   fFlags      The logging flags.
    40984664 * @param   iGroup      The group.
     
    41024668 * @param   args        Format arguments.
    41034669 */
    4104 static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
    4105 {
    4106     /*
    4107      * Format the message and perhaps flush it.
    4108      */
    4109     if (pLogger->fFlags & (RTLOGFLAGS_PREFIX_MASK | RTLOGFLAGS_USECRLF))
     4670static void rtlogLoggerExVLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup,
     4671                                 const char *pszFormat, va_list args)
     4672{
     4673    /*
     4674     * If we've got an auxilary descriptor, check if the buffer was flushed.
     4675     */
     4676    PRTLOGBUFFERDESC    pBufDesc = pLoggerInt->pBufDesc;
     4677    PRTLOGBUFFERAUXDESC pAuxDesc = pBufDesc->pAux;
     4678    if (!pAuxDesc || !pAuxDesc->fFlushedIndicator)
     4679    { /* likely, except maybe for ring-0 */ }
     4680    else
     4681    {
     4682        pAuxDesc->fFlushedIndicator = false;
     4683        pBufDesc->offBuf        = 0;
     4684    }
     4685
     4686    /*
     4687     * Format the message.
     4688     */
     4689    if (pLoggerInt->fFlags & (RTLOGFLAGS_PREFIX_MASK | RTLOGFLAGS_USECRLF))
    41104690    {
    41114691        RTLOGOUTPUTPREFIXEDARGS OutputArgs;
    4112         OutputArgs.pLogger = pLogger;
    4113         OutputArgs.iGroup  = iGroup;
    4114         OutputArgs.fFlags  = fFlags;
     4692        OutputArgs.pLoggerInt = pLoggerInt;
     4693        OutputArgs.iGroup     = iGroup;
     4694        OutputArgs.fFlags     = fFlags;
    41154695        RTLogFormatV(rtLogOutputPrefixed, &OutputArgs, pszFormat, args);
    41164696    }
    41174697    else
    4118         RTLogFormatV(rtLogOutput, pLogger, pszFormat, args);
    4119     if (    !(pLogger->fFlags & RTLOGFLAGS_BUFFERED)
    4120         &&  pLogger->offScratch)
    4121         rtlogFlush(pLogger, false /*fNeedSpace*/);
     4698        RTLogFormatV(rtLogOutput, pLoggerInt, pszFormat, args);
     4699
     4700    /*
     4701     * Maybe flush the buffer and update the auxiliary descriptor if there is one.
     4702     */
     4703    pBufDesc = pLoggerInt->pBufDesc;  /* (the descriptor may have changed) */
     4704    if (    !(pLoggerInt->fFlags & RTLOGFLAGS_BUFFERED)
     4705        &&  pBufDesc->offBuf)
     4706        rtlogFlush(pLoggerInt, false /*fNeedSpace*/);
     4707    else
     4708    {
     4709        pAuxDesc = pBufDesc->pAux;
     4710        if (pAuxDesc)
     4711            pAuxDesc->offBuf = pBufDesc->offBuf;
     4712    }
    41224713}
    41234714
     
    41274718 * For calling rtlogLoggerExVLocked.
    41284719 *
    4129  * @param   pLogger     The logger.
     4720 * @param   pLoggerInt  The logger.
    41304721 * @param   fFlags      The logging flags.
    41314722 * @param   iGroup      The group.
     
    41354726 * @param   ...         Format arguments.
    41364727 */
    4137 static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
     4728static void rtlogLoggerExFLocked(PRTLOGGERINTERNAL pLoggerInt, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
    41384729{
    41394730    va_list va;
    41404731    va_start(va, pszFormat);
    4141     rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, va);
     4732    rtlogLoggerExVLocked(pLoggerInt, fFlags, iGroup, pszFormat, va);
    41424733    va_end(va);
    41434734}
  • trunk/src/VBox/Runtime/common/log/logrel.cpp

    r82968 r90829  
    5656# include <stdio.h>
    5757#endif
    58 
    59 
    60 /*********************************************************************************************************************************
    61 *   Global Variables                                                                                                             *
    62 *********************************************************************************************************************************/
    63 #ifdef IN_RC
    64 /** Default release logger instance. */
    65 extern "C" DECLIMPORT(RTLOGGERRC)   g_RelLogger;
    66 #else /* !IN_RC */
    67 /** Default release logger instance. */
    68 static PRTLOGGER                    g_pRelLogger;
    69 #endif /* !IN_RC */
    70 
    71 
    72 RTDECL(PRTLOGGER)   RTLogRelGetDefaultInstance(void)
    73 {
    74 #ifdef IN_RC
    75     return &g_RelLogger;
    76 #else /* !IN_RC */
    77     return g_pRelLogger;
    78 #endif /* !IN_RC */
    79 }
    80 RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstance);
    81 
    82 
    83 RTDECL(PRTLOGGER)   RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup)
    84 {
    85 #ifdef IN_RC
    86     PRTLOGGER pLogger = &g_RelLogger;
    87 #else /* !IN_RC */
    88     PRTLOGGER pLogger = g_pRelLogger;
    89 #endif /* !IN_RC */
    90     if (pLogger)
    91     {
    92         if (pLogger->fFlags & RTLOGFLAGS_DISABLED)
    93             pLogger = NULL;
    94         else
    95         {
    96             uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup);
    97             uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
    98             if (   iGroup != UINT16_MAX
    99                  && (   (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED))
    100                      != (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED)))
    101             pLogger = NULL;
    102         }
    103     }
    104     return pLogger;
    105 }
    106 RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstanceEx);
    107 
    108 
    109 #ifndef IN_RC
    110 /**
    111  * Sets the default logger instance.
    112  *
    113  * @returns iprt status code.
    114  * @param   pLogger     The new default release logger instance.
    115  */
    116 RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger)
    117 {
    118     return ASMAtomicXchgPtrT(&g_pRelLogger, pLogger, PRTLOGGER);
    119 }
    120 RT_EXPORT_SYMBOL(RTLogRelSetDefaultInstance);
    121 #endif /* !IN_RC */
    12258
    12359
  • trunk/src/VBox/Runtime/testcase/tstLog.cpp

    r82968 r90829  
    6969    {
    7070#if 0   /* Old tests: */
    71         printf("tstLog: Requires manual inspection of the log output!\n");
     71        RTTestIPrintf(RTTESTLVL_ALWAYS, "Requires manual inspection of the log output!\n");
    7272        RTLogPrintf("%%Rrc %d: %Rrc\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER);
    7373        RTLogPrintf("%%Rrs %d: %Rrs\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER);
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r90824 r90829  
    13251325    PGMR0CleanupVM(pGVM);
    13261326    TMR0CleanupVM(pGVM);
    1327 
    1328     AssertCompile(NIL_RTTHREADCTXHOOK == (RTTHREADCTXHOOK)0); /* Depends on zero initialized memory working for NIL at the moment. */
    1329     for (VMCPUID idCpu = 0; idCpu < pGVM->cCpus; idCpu++)
    1330     {
    1331         /** @todo Can we busy wait here for all thread-context hooks to be
    1332          *        deregistered before releasing (destroying) it? Only until we find a
    1333          *        solution for not deregistering hooks everytime we're leaving HMR0
    1334          *        context. */
    1335         VMMR0ThreadCtxHookDestroyForEmt(&pGVM->aCpus[idCpu]);
    1336     }
     1327    VMMR0CleanupVM(pGVM);
    13371328}
    13381329
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r90784 r90829  
    5555#include <iprt/assert.h>
    5656#include <iprt/crc.h>
     57#include <iprt/mem.h>
     58#include <iprt/memobj.h>
    5759#include <iprt/mp.h>
    5860#include <iprt/once.h>
     
    141143#endif
    142144RT_C_DECLS_END
     145static int vmmR0UpdateLoggers(PGVM pGVM, VMCPUID idCpu, PVMMR0UPDATELOGGERSREQ pReq, bool fRelease);
     146static FNRTLOGFLUSH vmmR0LogFlush;
     147static FNRTLOGFLUSH vmmR0LogRelFlush;
    143148
    144149
     
    365370VMMR0_INT_DECL(void) VMMR0InitPerVMData(PGVM pGVM)
    366371{
     372    pGVM->vmmr0.s.hMemObjLogger         = NIL_RTR0MEMOBJ;
     373    pGVM->vmmr0.s.hMapObjLogger         = NIL_RTR0MEMOBJ;
     374    pGVM->vmmr0.s.hMemObjReleaseLogger  = NIL_RTR0MEMOBJ;
     375    pGVM->vmmr0.s.hMapObjReleaseLogger  = NIL_RTR0MEMOBJ;
     376    pGVM->vmmr0.s.fCalledInitVm         = false;
     377
    367378    for (VMCPUID idCpu = 0; idCpu < pGVM->cCpus; idCpu++)
    368379    {
     
    378389
    379390/**
     391 * Helper for vmmR0InitLoggers
     392 */
     393static int vmmR0InitLoggerOne(PGVMCPU pGVCpu, bool fRelease, PVMMR0PERVCPULOGGER pR0Log, PVMMR3CPULOGGER pShared,
     394                              uint32_t cbBuf, char *pchBuf, RTR3PTR pchBufR3)
     395{
     396    pR0Log->BufDesc.u32Magic    = RTLOGBUFFERDESC_MAGIC;
     397    pR0Log->BufDesc.uReserved   = 0;
     398    pR0Log->BufDesc.cbBuf       = cbBuf;
     399    pR0Log->BufDesc.offBuf      = 0;
     400    pR0Log->BufDesc.pchBuf      = pchBuf;
     401    pR0Log->BufDesc.pAux        = &pShared->AuxDesc;
     402
     403    pShared->AuxDesc.fFlushedIndicator   = false;
     404    pShared->AuxDesc.afPadding[0]        = 0;
     405    pShared->AuxDesc.afPadding[1]        = 0;
     406    pShared->AuxDesc.afPadding[2]        = 0;
     407    pShared->AuxDesc.offBuf              = 0;
     408    pShared->pchBufR3                    = pchBufR3;
     409    pShared->cbBuf                       = cbBuf;
     410
     411    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
     412    int rc = RTLogCreateEx(&pR0Log->pLogger, fRelease ? "VBOX_RELEASE_LOG" : "VBOX_LOG", RTLOG_F_NO_LOCKING | RTLOGFLAGS_BUFFERED,
     413                           "all", RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
     414                           fRelease ? vmmR0LogRelFlush : vmmR0LogFlush, 1 /*cBufDescs*/, &pR0Log->BufDesc,
     415                           RTLOGDEST_DUMMY,
     416                           NULL /*pfnPhase*/, 0 /*cHistory*/, 0 /*cbHistoryFileMax*/, 0 /*cSecsHistoryTimeSlot*/,
     417                           NULL /*pErrInfo*/, NULL /*pszFilenameFmt*/);
     418    if (RT_SUCCESS(rc))
     419    {
     420        PRTLOGGER pLogger = pR0Log->pLogger;
     421        pLogger->u32UserValue1 = VMMR0_LOGGER_FLAGS_MAGIC_VALUE;
     422        pLogger->u64UserValue2 = (uintptr_t)pGVCpu;
     423        pLogger->u64UserValue3 = (uintptr_t)pGVCpu;
     424
     425        RTLogSetR0ThreadNameF(pLogger, "EMT-%u-R0", pGVCpu->idCpu);
     426    }
     427    else
     428        pR0Log->pLogger = NULL;
     429    return rc;
     430}
     431
     432
     433/**
     434 * Initializes one type of loggers for each EMT.
     435 */
     436static int vmmR0InitLoggers(PGVM pGVM, bool fRelease, uint32_t cbBuf, PRTR0MEMOBJ phMemObj, PRTR0MEMOBJ phMapObj)
     437{
     438    /* Allocate buffers first. */
     439    int rc = RTR0MemObjAllocPage(phMemObj, cbBuf * pGVM->cCpus, false /*fExecutable*/);
     440    if (RT_SUCCESS(rc))
     441    {
     442        rc = RTR0MemObjMapUser(phMapObj, *phMemObj, (RTR3PTR)-1, 0 /*uAlignment*/, RTMEM_PROT_READ, NIL_RTR0PROCESS);
     443        if (RT_SUCCESS(rc))
     444        {
     445            char  * const pchBuf   = (char *)RTR0MemObjAddress(*phMemObj);
     446            AssertPtrReturn(pchBuf, VERR_INTERNAL_ERROR_2);
     447
     448            RTR3PTR const pchBufR3 = RTR0MemObjAddressR3(*phMapObj);
     449            AssertReturn(pchBufR3 != NIL_RTR3PTR, VERR_INTERNAL_ERROR_3);
     450
     451            /* Initialize the per-CPU loggers. */
     452            for (uint32_t i = 0; i < pGVM->cCpus; i++)
     453            {
     454                PGVMCPU             pGVCpu  = &pGVM->aCpus[i];
     455                PVMMR0PERVCPULOGGER pR0Log  = fRelease ? &pGVCpu->vmmr0.s.RelLogger : &pGVCpu->vmmr0.s.Logger;
     456                PVMMR3CPULOGGER     pShared = fRelease ? &pGVCpu->vmm.s.RelLogger   : &pGVCpu->vmm.s.Logger;
     457                rc = vmmR0InitLoggerOne(pGVCpu, fRelease, pR0Log, pShared, cbBuf, pchBuf + i * cbBuf, pchBufR3 + i * cbBuf);
     458                if (RT_FAILURE(rc))
     459                {
     460                    pR0Log->pLogger   = NULL;
     461                    pShared->pchBufR3 = NIL_RTR3PTR;
     462                    while (i-- > 0)
     463                    {
     464                        pGVCpu  = &pGVM->aCpus[i];
     465                        pR0Log  = fRelease ? &pGVCpu->vmmr0.s.RelLogger : &pGVCpu->vmmr0.s.Logger;
     466                        pShared = fRelease ? &pGVCpu->vmm.s.RelLogger   : &pGVCpu->vmm.s.Logger;
     467                        RTLogDestroy(pR0Log->pLogger);
     468                        pR0Log->pLogger   = NULL;
     469                        pShared->pchBufR3 = NIL_RTR3PTR;
     470                    }
     471                    break;
     472                }
     473            }
     474            if (RT_SUCCESS(rc))
     475                return VINF_SUCCESS;
     476
     477            /* Bail out. */
     478            RTR0MemObjFree(*phMapObj, false /*fFreeMappings*/);
     479            *phMapObj = NIL_RTR0MEMOBJ;
     480        }
     481        RTR0MemObjFree(*phMemObj, true /*fFreeMappings*/);
     482        *phMemObj = NIL_RTR0MEMOBJ;
     483    }
     484    return rc;
     485}
     486
     487
     488/**
    380489 * Initiates the R0 driver for a particular VM instance.
    381490 *
     
    412521        return rc;
    413522
     523    /* Don't allow this to be called more than once. */
     524    if (!pGVM->vmmr0.s.fCalledInitVm)
     525        pGVM->vmmr0.s.fCalledInitVm = true;
     526    else
     527        return VERR_ALREADY_INITIALIZED;
     528
     529    /*
     530     * Create the ring-0 release loggers.
     531     */
     532    rc = vmmR0InitLoggers(pGVM, true /*fRelease*/, _8K, &pGVM->vmmr0.s.hMemObjReleaseLogger, &pGVM->vmmr0.s.hMapObjReleaseLogger);
     533    if (RT_FAILURE(rc))
     534        return rc;
     535
    414536#ifdef LOG_ENABLED
    415537    /*
     538     * Create debug loggers.
     539     */
     540    rc = vmmR0InitLoggers(pGVM, false /*fRelease*/, _64K, &pGVM->vmmr0.s.hMemObjLogger, &pGVM->vmmr0.s.hMapObjLogger);
     541    if (RT_FAILURE(rc))
     542        return rc;
     543
     544    /*
    416545     * Register the EMT R0 logger instance for VCPU 0.
    417546     */
    418547    PVMCPUCC pVCpu = VMCC_GET_CPU_0(pGVM);
    419 
    420     PVMMR0LOGGER pR0Logger = pVCpu->vmm.s.pR0LoggerR0;
    421     if (pR0Logger)
     548    if (pVCpu->vmmr0.s.Logger.pLogger)
    422549    {
    423550# if 0 /* testing of the logger. */
     
    451578        LogCom(("vmmR0InitVM: RTLogPrintf returned fine offScratch=%d\n", pR0Logger->Logger.offScratch));
    452579# endif
    453         Log(("Switching to per-thread logging instance %p (key=%p)\n", &pR0Logger->Logger, pGVM->pSession));
    454         RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pGVM->pSession);
    455         pR0Logger->fRegistered = true;
     580# ifdef VBOX_WITH_R0_LOGGING
     581        Log(("Switching to per-thread logging instance %p (key=%p)\n", pVCpu->vmmr0.s.Logger.pLogger, pGVM->pSession));
     582        RTLogSetDefaultInstanceThread(pVCpu->vmmr0.s.Logger.pLogger, (uintptr_t)pGVM->pSession);
     583        pVCpu->vmmr0.s.Logger.fRegistered = true;
     584# endif
    456585    }
    457586#endif /* LOG_ENABLED */
     
    548677    AssertReturn(pGVM->aCpus[idCpu].hEMT == RTThreadNativeSelf(), VERR_INVALID_CPU_ID);
    549678
    550 #ifdef LOG_ENABLED
     679#if defined(LOG_ENABLED) && defined(VBOX_WITH_R0_LOGGING)
    551680    /*
    552681     * Registration of ring 0 loggers.
    553682     */
    554     PVMCPUCC       pVCpu     = &pGVM->aCpus[idCpu];
    555     PVMMR0LOGGER pR0Logger = pVCpu->vmm.s.pR0LoggerR0;
    556     if (   pR0Logger
    557         && !pR0Logger->fRegistered)
    558     {
    559         RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pGVM->pSession);
    560         pR0Logger->fRegistered = true;
     683    PVMCPUCC pVCpu = &pGVM->aCpus[idCpu];
     684    if (   pVCpu->vmmr0.s.Logger.pLogger
     685        && !pVCpu->vmmr0.s.Logger.fRegistered)
     686    {
     687        RTLogSetDefaultInstanceThread(pVCpu->vmmr0.s.Logger.pLogger, (uintptr_t)pGVM->pSession);
     688        pVCpu->vmmr0.s.Logger.fRegistered = true;
    561689    }
    562690#endif
     
    614742
    615743    /*
    616      * Deregister the logger.
     744     * Deregister the logger for this EMT.
    617745     */
    618746    RTLogSetDefaultInstanceThread(NULL, (uintptr_t)pGVM->pSession);
    619747    return VINF_SUCCESS;
     748}
     749
     750
     751/**
     752 * This is called at the end of gvmmR0CleanupVM().
     753 *
     754 * @param   pGVM        The global (ring-0) VM structure.
     755 */
     756VMMR0_INT_DECL(void) VMMR0CleanupVM(PGVM pGVM)
     757{
     758    AssertCompile(NIL_RTTHREADCTXHOOK == (RTTHREADCTXHOOK)0); /* Depends on zero initialized memory working for NIL at the moment. */
     759    for (VMCPUID idCpu = 0; idCpu < pGVM->cCpus; idCpu++)
     760    {
     761        PGVMCPU pGVCpu = &pGVM->aCpus[idCpu];
     762
     763        /** @todo Can we busy wait here for all thread-context hooks to be
     764         *        deregistered before releasing (destroying) it? Only until we find a
     765         *        solution for not deregistering hooks everytime we're leaving HMR0
     766         *        context. */
     767        VMMR0ThreadCtxHookDestroyForEmt(pGVCpu);
     768
     769        /* Destroy the release logger. */
     770        RTLogDestroy(pGVCpu->vmmr0.s.RelLogger.pLogger);
     771        pGVCpu->vmmr0.s.RelLogger.pLogger = NULL;
     772        pGVCpu->vmm.s.RelLogger.pchBufR3  = NIL_RTR3PTR;
     773
     774        /* Destroy the regular logger. */
     775        RTLogDestroy(pGVCpu->vmmr0.s.Logger.pLogger);
     776        pGVCpu->vmmr0.s.Logger.pLogger = NULL;
     777        pGVCpu->vmm.s.Logger.pchBufR3  = NIL_RTR3PTR;
     778    }
     779
     780    /*
     781     * Free logger buffer memory.
     782     */
     783    RTR0MemObjFree(pGVM->vmmr0.s.hMapObjReleaseLogger, false /*fFreeMappings*/);
     784    pGVM->vmmr0.s.hMapObjReleaseLogger = NIL_RTR0MEMOBJ;
     785    RTR0MemObjFree(pGVM->vmmr0.s.hMemObjReleaseLogger, true /*fFreeMappings*/);
     786    pGVM->vmmr0.s.hMemObjReleaseLogger = NIL_RTR0MEMOBJ;
     787
     788    RTR0MemObjFree(pGVM->vmmr0.s.hMapObjLogger, false /*fFreeMappings*/);
     789    pGVM->vmmr0.s.hMapObjLogger = NIL_RTR0MEMOBJ;
     790    RTR0MemObjFree(pGVM->vmmr0.s.hMemObjLogger, true /*fFreeMappings*/);
     791    pGVM->vmmr0.s.hMemObjLogger = NIL_RTR0MEMOBJ;
    620792}
    621793
     
    11711343VMMR0_INT_DECL(PRTLOGGER) VMMR0GetReleaseLogger(PVMCPUCC pVCpu)
    11721344{
    1173     PVMMR0LOGGER pLogger = pVCpu->vmm.s.pR0RelLoggerR0;
    1174     if (pLogger)
    1175         return &pLogger->Logger;
    1176     return NULL;
     1345    return pVCpu->vmmr0.s.RelLogger.pLogger;
    11771346}
    11781347
     
    18802049
    18812050        /*
     2051         * Update release or debug logger instances.
     2052         */
     2053        case VMMR0_DO_VMMR0_UPDATE_LOGGERS:
     2054            if (idCpu == NIL_VMCPUID)
     2055                return VERR_INVALID_CPU_ID;
     2056            if (u64Arg <= 1 && pReqHdr != NULL)
     2057                rc = vmmR0UpdateLoggers(pGVM, idCpu /*idCpu*/, (PVMMR0UPDATELOGGERSREQ)pReqHdr, u64Arg != 0);
     2058            else
     2059                return VERR_INVALID_PARAMETER;
     2060            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
     2061            break;
     2062
     2063        /*
    18822064         * Attempt to enable hm mode and check the current setting.
    18832065         */
     
    26882870
    26892871/**
    2690  * Internal R0 logger worker: Flush logger.
    2691  *
    2692  * @param   pLogger     The logger instance to flush.
    2693  * @remark  This function must be exported!
    2694  */
    2695 VMMR0DECL(void) vmmR0LoggerFlush(PRTLOGGER pLogger)
     2872 * Updates the EMT loggers for the VM.
     2873 *
     2874 * @returns VBox status code.
     2875 * @param   pGVM            The global (ring-0) VM structure.
     2876 * @param   idCpu           The ID of the calling EMT.
     2877 * @param   pReq            The request data.
     2878 * @param   fRelease        Which logger set to update.
     2879 * @thread  EMT(idCpu)
     2880 */
     2881static int vmmR0UpdateLoggers(PGVM pGVM, VMCPUID idCpu, PVMMR0UPDATELOGGERSREQ pReq, bool fRelease)
     2882{
     2883    /*
     2884     * Check sanity.  First we require EMT to be calling us.
     2885     */
     2886    AssertReturn(idCpu < pGVM->cCpus, VERR_INVALID_CPU_ID);
     2887    AssertReturn(pGVM->aCpus[idCpu].hEMT == RTThreadNativeSelf(), VERR_INVALID_CPU_ID);
     2888
     2889    AssertReturn(pReq->Hdr.cbReq >= RT_UOFFSETOF_DYN(VMMR0UPDATELOGGERSREQ, afGroups[0]), VERR_INVALID_PARAMETER);
     2890    AssertReturn(pReq->cGroups < _8K, VERR_INVALID_PARAMETER);
     2891    AssertReturn(pReq->Hdr.cbReq == RT_UOFFSETOF_DYN(VMMR0UPDATELOGGERSREQ, afGroups[pReq->cGroups]), VERR_INVALID_PARAMETER);
     2892
     2893    /*
     2894     * Adjust flags.
     2895     */
     2896    /* Always buffered: */
     2897    pReq->fFlags |= RTLOGFLAGS_BUFFERED;
     2898    /* These doesn't make sense at present: */
     2899    pReq->fFlags &= ~(RTLOGFLAGS_FLUSH | RTLOGFLAGS_WRITE_THROUGH);
     2900    /* We've traditionally skipped the group restrictions. */
     2901    pReq->fFlags &= ~RTLOGFLAGS_RESTRICT_GROUPS;
     2902
     2903    /*
     2904     * Do the updating.
     2905     */
     2906    int rc = VINF_SUCCESS;
     2907    for (idCpu = 0; idCpu < pGVM->cCpus; idCpu++)
     2908    {
     2909        PGVMCPU pGVCpu = &pGVM->aCpus[idCpu];
     2910        PRTLOGGER pLogger = fRelease ? pGVCpu->vmmr0.s.RelLogger.pLogger : pGVCpu->vmmr0.s.Logger.pLogger;
     2911        if (pLogger)
     2912            rc = RTLogBulkUpdate(pLogger, pReq->fFlags, pReq->uGroupCrc32, pReq->cGroups, pReq->afGroups);
     2913    }
     2914
     2915    return rc;
     2916}
     2917
     2918
     2919/**
     2920 * Common worker for vmmR0LogFlush and vmmR0LogRelFlush.
     2921 */
     2922static bool vmmR0LoggerFlushCommon(PRTLOGGER pLogger, PRTLOGBUFFERDESC pBufDesc, bool fRelease)
     2923{
     2924    RT_NOREF(pBufDesc, fRelease);
     2925
     2926    /*
     2927     * Convert the pLogger into a GVMCPU handle and 'call' back to Ring-3.
     2928     * (This is a bit paranoid code.)
     2929     */
     2930    if (RT_VALID_PTR(pLogger))
     2931    {
     2932        if (   pLogger->u32Magic == RTLOGGER_MAGIC
     2933            && (pLogger->u32UserValue1 & VMMR0_LOGGER_FLAGS_MAGIC_MASK) == VMMR0_LOGGER_FLAGS_MAGIC_VALUE
     2934            && pLogger->u64UserValue2 == pLogger->u64UserValue3)
     2935        {
     2936            if (!(pLogger->u32UserValue1 & VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED))
     2937            {
     2938                PGVMCPU const pGVCpu = (PGVMCPU)(uintptr_t)pLogger->u64UserValue2;
     2939                if (   RT_VALID_PTR(pGVCpu)
     2940                    && ((uintptr_t)pGVCpu & PAGE_OFFSET_MASK) == 0)
     2941                {
     2942                    RTNATIVETHREAD const hNativeSelf = RTThreadNativeSelf();
     2943                    if (   hNativeSelf == pGVCpu->hEMT
     2944                        && RT_VALID_PTR(pGVCpu->pGVM))
     2945                    {
     2946                        /*
     2947                         * Check that the jump buffer is armed.
     2948                         */
     2949#ifdef RT_ARCH_X86
     2950                        if (   pGVCpu->vmm.s.CallRing3JmpBufR0.eip != 0
     2951                            && !pGVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call)
     2952#else
     2953                        if (   pGVCpu->vmm.s.CallRing3JmpBufR0.rip != 0
     2954                            && !pGVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call)
     2955#endif
     2956                        {
     2957                            VMMRZCallRing3(pGVCpu->pGVM, pGVCpu, VMMCALLRING3_VMM_LOGGER_FLUSH, fRelease);
     2958                        }
     2959#ifdef DEBUG
     2960                        else SUPR0Printf("vmmR0LoggerFlush: Jump buffer isn't armed!\n");
     2961#endif
     2962                    }
     2963#ifdef DEBUG
     2964                    else SUPR0Printf("vmmR0LoggerFlush: pLogger=%p pGVCpu=%p hEMT=%p hNativeSelf=%p!\n",
     2965                                     pLogger, pGVCpu, pGVCpu->hEMT, hNativeSelf);
     2966#endif
     2967
     2968                }
     2969#ifdef DEBUG
     2970                else SUPR0Printf("vmmR0LoggerFlush: pLogger=%p pGVCpu=%p!\n", pLogger, pGVCpu);
     2971#endif
     2972            }
     2973            /* else: quiet */
     2974        }
     2975#ifdef DEBUG
     2976        else SUPR0Printf("vmmR0LoggerFlush: pLogger=%p u32Magic=%#x u32UserValue1=%#x u64UserValue2=%#RX64 u64UserValue3=%#RX64!\n",
     2977                        pLogger, pLogger->u32Magic, pLogger->u32UserValue1, pLogger->u64UserValue2, pLogger->u64UserValue3);
     2978#endif
     2979    }
     2980#ifdef DEBUG
     2981    else SUPR0Printf("vmmR0LoggerFlush: pLogger=%p!\n", pLogger);
     2982#endif
     2983    return true;
     2984}
     2985
     2986
     2987/**
     2988 * @callback_method_impl{FNRTLOGFLUSH, Release logger buffer flush callback.}
     2989 */
     2990static DECLCALLBACK(bool) vmmR0LogRelFlush(PRTLOGGER pLogger, PRTLOGBUFFERDESC pBufDesc)
     2991{
     2992    return vmmR0LoggerFlushCommon(pLogger, pBufDesc, true /*fRelease*/);
     2993}
     2994
     2995
     2996/**
     2997 * @callback_method_impl{FNRTLOGFLUSH, Logger (debug) buffer flush callback.}
     2998 */
     2999static DECLCALLBACK(bool) vmmR0LogFlush(PRTLOGGER pLogger, PRTLOGBUFFERDESC pBufDesc)
    26963000{
    26973001#ifdef LOG_ENABLED
    2698     /*
    2699      * Convert the pLogger into a VM handle and 'call' back to Ring-3.
    2700      * (This is a bit paranoid code.)
    2701      */
    2702     PVMMR0LOGGER pR0Logger = (PVMMR0LOGGER)((uintptr_t)pLogger - RT_UOFFSETOF(VMMR0LOGGER, Logger));
    2703     if (    !RT_VALID_PTR(pR0Logger)
    2704         ||  !RT_VALID_PTR(pR0Logger + 1)
    2705         ||  pLogger->u32Magic != RTLOGGER_MAGIC)
    2706     {
    2707 # ifdef DEBUG
    2708         SUPR0Printf("vmmR0LoggerFlush: pLogger=%p!\n", pLogger);
    2709 # endif
    2710         return;
    2711     }
    2712     if (pR0Logger->fFlushingDisabled)
    2713         return; /* quietly */
    2714 
    2715     PVMCC pVM = pR0Logger->pVM;
    2716     if (   !RT_VALID_PTR(pVM)
    2717         || pVM->pSelf != pVM)
    2718     {
    2719 # ifdef DEBUG
    2720         SUPR0Printf("vmmR0LoggerFlush: pVM=%p! pSelf=%p! pLogger=%p\n", pVM, pVM->pSelf, pLogger);
    2721 # endif
    2722         return;
    2723     }
    2724 
    2725     PVMCPUCC pVCpu = VMMGetCpu(pVM);
    2726     if (pVCpu)
    2727     {
    2728         /*
    2729          * Check that the jump buffer is armed.
    2730          */
    2731 # ifdef RT_ARCH_X86
    2732         if (    !pVCpu->vmm.s.CallRing3JmpBufR0.eip
    2733             ||  pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call)
    2734 # else
    2735         if (    !pVCpu->vmm.s.CallRing3JmpBufR0.rip
    2736             ||  pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call)
    2737 # endif
    2738         {
    2739 # ifdef DEBUG
    2740             SUPR0Printf("vmmR0LoggerFlush: Jump buffer isn't armed!\n");
    2741 # endif
    2742             return;
    2743         }
    2744         VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_VMM_LOGGER_FLUSH, 0);
    2745     }
    2746 # ifdef DEBUG
    2747     else
    2748         SUPR0Printf("vmmR0LoggerFlush: invalid VCPU context!\n");
    2749 # endif
     3002    return vmmR0LoggerFlushCommon(pLogger, pBufDesc, false /*fRelease*/);
    27503003#else
    2751     NOREF(pLogger);
    2752 #endif  /* LOG_ENABLED */
     3004    RT_NOREF(pLogger, pBufDesc);
     3005    return true;
     3006#endif
    27533007}
    27543008
     
    27623016VMMR0_INT_DECL(void) VMMR0LogFlushDisable(PVMCPUCC pVCpu)
    27633017{
    2764     if (pVCpu->vmm.s.pR0LoggerR0)
    2765         pVCpu->vmm.s.pR0LoggerR0->fFlushingDisabled = true;
    2766     if (pVCpu->vmm.s.pR0RelLoggerR0)
    2767         pVCpu->vmm.s.pR0RelLoggerR0->fFlushingDisabled = true;
     3018    pVCpu->vmmr0.s.fLogFlushingDisabled = true;
     3019    if (pVCpu->vmmr0.s.Logger.pLogger)
     3020        pVCpu->vmmr0.s.Logger.pLogger->u32UserValue1 |= VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
     3021    if (pVCpu->vmmr0.s.RelLogger.pLogger)
     3022        pVCpu->vmmr0.s.RelLogger.pLogger->u32UserValue1 |= VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
    27683023}
    27693024
     
    27763031VMMR0_INT_DECL(void) VMMR0LogFlushEnable(PVMCPUCC pVCpu)
    27773032{
    2778     if (pVCpu->vmm.s.pR0LoggerR0)
    2779         pVCpu->vmm.s.pR0LoggerR0->fFlushingDisabled = false;
    2780     if (pVCpu->vmm.s.pR0RelLoggerR0)
    2781         pVCpu->vmm.s.pR0RelLoggerR0->fFlushingDisabled = false;
     3033    pVCpu->vmmr0.s.fLogFlushingDisabled = false;
     3034    if (pVCpu->vmmr0.s.Logger.pLogger)
     3035        pVCpu->vmmr0.s.Logger.pLogger->u32UserValue1 &= ~VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
     3036    if (pVCpu->vmmr0.s.RelLogger.pLogger)
     3037        pVCpu->vmmr0.s.RelLogger.pLogger->u32UserValue1 &= ~VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
    27823038}
    27833039
     
    27903046VMMR0_INT_DECL(bool) VMMR0IsLogFlushDisabled(PVMCPUCC pVCpu)
    27913047{
    2792     if (pVCpu->vmm.s.pR0LoggerR0)
    2793         return pVCpu->vmm.s.pR0LoggerR0->fFlushingDisabled;
    2794     if (pVCpu->vmm.s.pR0RelLoggerR0)
    2795         return pVCpu->vmm.s.pR0RelLoggerR0->fFlushingDisabled;
    2796     return true;
     3048    return pVCpu->vmmr0.s.fLogFlushingDisabled;
    27973049}
    27983050
    27993051#endif /* LOG_ENABLED */
     3052
     3053/*
     3054 * Override RTLogGetDefaultInstanceEx so we can do logging from EMTs in ring-0.
     3055 */
     3056DECLEXPORT(PRTLOGGER) RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup)
     3057{
     3058#ifdef LOG_ENABLED
     3059    PGVMCPU pGVCpu = GVMMR0GetGVCpuByEMT(NIL_RTNATIVETHREAD);
     3060    if (pGVCpu)
     3061    {
     3062        PRTLOGGER pLogger = pGVCpu->vmmr0.s.Logger.pLogger;
     3063        if (RT_VALID_PTR(pLogger))
     3064        {
     3065            if (   pLogger->u64UserValue2 == (uintptr_t)pGVCpu
     3066                && pLogger->u64UserValue3 == (uintptr_t)pGVCpu)
     3067            {
     3068                if (!(pGVCpu->vmmr0.s.fLogFlushingDisabled))
     3069                    return RTLogCheckGroupFlags(pLogger, fFlagsAndGroup);
     3070                return NULL;
     3071            }
     3072        }
     3073    }
     3074#endif
     3075    return SUPR0GetDefaultLogInstanceEx(fFlagsAndGroup);
     3076}
     3077
    28003078
    28013079/*
     
    28073085    if (pGVCpu)
    28083086    {
    2809         PVMCPUCC pVCpu = pGVCpu;
    2810         if (RT_VALID_PTR(pVCpu))
    2811         {
    2812             PVMMR0LOGGER pVmmLogger = pVCpu->vmm.s.pR0RelLoggerR0;
    2813             if (RT_VALID_PTR(pVmmLogger))
     3087        PRTLOGGER pLogger = pGVCpu->vmmr0.s.RelLogger.pLogger;
     3088        if (RT_VALID_PTR(pLogger))
     3089        {
     3090            if (   pLogger->u64UserValue2 == (uintptr_t)pGVCpu
     3091                && pLogger->u64UserValue3 == (uintptr_t)pGVCpu)
    28143092            {
    2815                 if (   pVmmLogger->fCreated
    2816                     && pVmmLogger->pVM == pGVCpu->pGVM)
    2817                 {
    2818                     if (pVmmLogger->Logger.fFlags & RTLOGFLAGS_DISABLED)
    2819                         return NULL;
    2820                     uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup);
    2821                     uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
    2822                     if (   iGroup != UINT16_MAX
    2823                         && (   (  pVmmLogger->Logger.afGroups[iGroup < pVmmLogger->Logger.cGroups ? iGroup : 0]
    2824                                 & (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED))
    2825                             != (fFlags | (uint32_t)RTLOGGRPFLAGS_ENABLED)))
    2826                         return NULL;
    2827                     return &pVmmLogger->Logger;
    2828                 }
     3093                if (!(pGVCpu->vmmr0.s.fLogFlushingDisabled))
     3094                    return RTLogCheckGroupFlags(pLogger, fFlagsAndGroup);
     3095                return NULL;
    28293096            }
    28303097        }
  • trunk/src/VBox/VMM/VMMR0/VMMR0.def

    r90346 r90829  
    3737    RTLogDefaultInstance
    3838    RTLogDefaultInstanceEx
     39    RTLogGetDefaultInstanceEx
    3940    RTLogRelGetDefaultInstance
    4041    RTLogRelGetDefaultInstanceEx
     
    6364    TMTimerUnlock
    6465    VMMGetSvnRev
    65     vmmR0LoggerFlush
    66     vmmR0LoggerWrapper
    6766    VMSetError
    6867    VMSetErrorV
  • trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm

    r90189 r90829  
    505505ENDPROC vmmR0CallRing3LongJmp
    506506
    507 
    508 ;;
    509 ; Internal R0 logger worker: Logger wrapper.
    510 ;
    511 ; @cproto VMMR0DECL(void) vmmR0LoggerWrapper(const char *pszFormat, ...)
    512 ;
    513 BEGINPROC_EXPORTED vmmR0LoggerWrapper
    514 SEH64_END_PROLOGUE
    515     int3
    516     int3
    517     int3
    518     ret
    519 ENDPROC vmmR0LoggerWrapper
    520 
  • trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-x86.asm

    r82968 r90829  
    3131%define STACK_PADDING   0eeeeeeeeh
    3232
    33 
    34 ; For vmmR0LoggerWrapper. (The other architecture(s) use(s) C99 variadic macros.)
    35 extern NAME(RTLogLogger)
    3633
    3734
     
    387384ENDPROC vmmR0CallRing3LongJmp
    388385
    389 
    390 ;;
    391 ; Internal R0 logger worker: Logger wrapper.
    392 ;
    393 ; @cproto VMMR0DECL(void) vmmR0LoggerWrapper(const char *pszFormat, ...)
    394 ;
    395 EXPORTEDNAME vmmR0LoggerWrapper
    396     push    0                           ; assumes we're the wrapper for a default instance.
    397     call    NAME(RTLogLogger)
    398     add     esp, byte 4
    399     ret
    400 ENDPROC vmmR0LoggerWrapper
    401 
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r90597 r90829  
    151151
    152152/** Macro for flushing the ring-0 logging. */
    153 #define VMM_FLUSH_R0_LOG(a_pR0Logger, a_pR3Logger) \
     153#define VMM_FLUSH_R0_LOG(a_pLogger, a_pR3Logger) \
    154154    do { \
    155         PVMMR0LOGGER pVmmLogger = (a_pR0Logger); \
    156         if (!pVmmLogger || pVmmLogger->Logger.offScratch == 0) \
     155        if ((a_pLogger)->AuxDesc.offBuf == 0 || (a_pLogger)->AuxDesc.fFlushedIndicator) \
    157156        { /* likely? */ } \
    158157        else \
    159             RTLogFlushR0(a_pR3Logger, &pVmmLogger->Logger); \
     158        { \
     159            RTLogBulkWrite(a_pR3Logger, (a_pLogger)->pchBufR3, (a_pLogger)->AuxDesc.offBuf); \
     160            (a_pLogger)->AuxDesc.fFlushedIndicator = true; \
     161        } \
    160162    } while (0)
    161163
     
    165167*********************************************************************************************************************************/
    166168static int                  vmmR3InitStacks(PVM pVM);
    167 static int                  vmmR3InitLoggers(PVM pVM);
    168169static void                 vmmR3InitRegisterStats(PVM pVM);
    169170static DECLCALLBACK(int)    vmmR3Save(PVM pVM, PSSMHANDLE pSSM);
     
    281282    if (RT_SUCCESS(rc))
    282283    {
    283         rc = vmmR3InitLoggers(pVM);
    284 
    285284#ifdef VBOX_WITH_NMI
    286285        /*
    287286         * Allocate mapping for the host APIC.
    288287         */
    289         if (RT_SUCCESS(rc))
    290         {
    291             rc = MMR3HyperReserve(pVM, PAGE_SIZE, "Host APIC", &pVM->vmm.s.GCPtrApicBase);
    292             AssertRC(rc);
    293         }
     288        rc = MMR3HyperReserve(pVM, PAGE_SIZE, "Host APIC", &pVM->vmm.s.GCPtrApicBase);
     289        AssertRC(rc);
    294290#endif
    295291        if (RT_SUCCESS(rc))
     
    352348
    353349    return rc;
    354 }
    355 
    356 
    357 /**
    358  * Initialize the loggers.
    359  *
    360  * @returns VBox status code.
    361  * @param   pVM         The cross context VM structure.
    362  */
    363 static int vmmR3InitLoggers(PVM pVM)
    364 {
    365     int rc;
    366 #define RTLogCalcSizeForR0(cGroups, fFlags) (RT_UOFFSETOF_DYN(VMMR0LOGGER, Logger.afGroups[cGroups]) + PAGE_SIZE)
    367 
    368     /*
    369      * Allocate R0 Logger instance (finalized in the relocator).
    370      */
    371 #if defined(LOG_ENABLED) && defined(VBOX_WITH_R0_LOGGING)
    372     PRTLOGGER pLogger = RTLogDefaultInstance();
    373     if (pLogger)
    374     {
    375         size_t const cbLogger = RTLogCalcSizeForR0(pLogger->cGroups, 0);
    376         for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    377         {
    378             PVMCPU pVCpu = pVM->apCpusR3[idCpu];
    379             rc = MMR3HyperAllocOnceNoRelEx(pVM, cbLogger, PAGE_SIZE, MM_TAG_VMM, MMHYPER_AONR_FLAGS_KERNEL_MAPPING,
    380                                            (void **)&pVCpu->vmm.s.pR0LoggerR3);
    381             if (RT_FAILURE(rc))
    382                 return rc;
    383             pVCpu->vmm.s.pR0LoggerR3->pVM        = VMCC_GET_VMR0_FOR_CALL(pVM);
    384             //pVCpu->vmm.s.pR0LoggerR3->fCreated = false;
    385             pVCpu->vmm.s.pR0LoggerR3->cbLogger   = (uint32_t)cbLogger;
    386             pVCpu->vmm.s.pR0LoggerR0 = MMHyperR3ToR0(pVM, pVCpu->vmm.s.pR0LoggerR3);
    387         }
    388     }
    389 #endif /* LOG_ENABLED && VBOX_WITH_R0_LOGGING */
    390 
    391     /*
    392      * Release logging.
    393      */
    394     PRTLOGGER pRelLogger = RTLogRelGetDefaultInstance();
    395     if (pRelLogger)
    396     {
    397         /*
    398          * Ring-0 release logger.
    399          */
    400         RTR0PTR pfnLoggerWrapper = NIL_RTR0PTR;
    401         rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerWrapper", &pfnLoggerWrapper);
    402         AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerWrapper not found! rc=%Rra\n", rc), rc);
    403 
    404         RTR0PTR pfnLoggerFlush = NIL_RTR0PTR;
    405         rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerFlush", &pfnLoggerFlush);
    406         AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerFlush not found! rc=%Rra\n", rc), rc);
    407 
    408         size_t const cbLogger = RTLogCalcSizeForR0(pRelLogger->cGroups, 0);
    409 
    410         for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    411         {
    412             PVMCPU pVCpu = pVM->apCpusR3[idCpu];
    413             rc = MMR3HyperAllocOnceNoRelEx(pVM, cbLogger, PAGE_SIZE, MM_TAG_VMM, MMHYPER_AONR_FLAGS_KERNEL_MAPPING,
    414                                            (void **)&pVCpu->vmm.s.pR0RelLoggerR3);
    415             if (RT_FAILURE(rc))
    416                 return rc;
    417             PVMMR0LOGGER pVmmLogger = pVCpu->vmm.s.pR0RelLoggerR3;
    418             RTR0PTR      R0PtrVmmLogger = MMHyperR3ToR0(pVM, pVmmLogger);
    419             pVCpu->vmm.s.pR0RelLoggerR0     = R0PtrVmmLogger;
    420             pVmmLogger->pVM                 = VMCC_GET_VMR0_FOR_CALL(pVM);
    421             pVmmLogger->cbLogger            = (uint32_t)cbLogger;
    422             pVmmLogger->fCreated            = false;
    423             pVmmLogger->fFlushingDisabled   = false;
    424             pVmmLogger->fRegistered         = false;
    425             pVmmLogger->idCpu               = idCpu;
    426 
    427             char szR0ThreadName[16];
    428             RTStrPrintf(szR0ThreadName, sizeof(szR0ThreadName), "EMT-%u-R0", idCpu);
    429             rc = RTLogCreateForR0(&pVmmLogger->Logger, pVmmLogger->cbLogger, R0PtrVmmLogger + RT_UOFFSETOF(VMMR0LOGGER, Logger),
    430                                   pfnLoggerWrapper, pfnLoggerFlush,
    431                                   RTLOGFLAGS_BUFFERED, RTLOGDEST_DUMMY, szR0ThreadName);
    432             AssertReleaseMsgRCReturn(rc, ("RTLogCreateForR0 failed! rc=%Rra\n", rc), rc);
    433 
    434             /* We only update the release log instance here. */
    435             rc = RTLogCopyGroupsAndFlagsForR0(&pVmmLogger->Logger, R0PtrVmmLogger + RT_UOFFSETOF(VMMR0LOGGER, Logger),
    436                                               pRelLogger, RTLOGFLAGS_BUFFERED, UINT32_MAX);
    437             AssertReleaseMsgRCReturn(rc, ("RTLogCopyGroupsAndFlagsForR0 failed! rc=%Rra\n", rc), rc);
    438 
    439             pVmmLogger->fCreated = true;
    440         }
    441     }
    442 
    443     return VINF_SUCCESS;
    444350}
    445351
     
    582488    Assert(pVCpu && pVCpu->idCpu == 0);
    583489
    584 #ifdef LOG_ENABLED
    585     /*
    586      * Initialize the ring-0 logger if we haven't done so yet.
    587      */
    588     if (    pVCpu->vmm.s.pR0LoggerR3
    589         &&  !pVCpu->vmm.s.pR0LoggerR3->fCreated)
    590     {
    591         rc = VMMR3UpdateLoggers(pVM);
    592         if (RT_FAILURE(rc))
    593             return rc;
    594     }
    595 #endif
     490    /*
     491     * Make sure the ring-0 loggers are up to date.
     492     */
     493    rc = VMMR3UpdateLoggers(pVM);
     494    if (RT_FAILURE(rc))
     495        return rc;
    596496
    597497    /*
     
    610510         */
    611511#ifdef LOG_ENABLED
    612         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
    613 #endif
    614         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
     512        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.Logger, NULL);
     513#endif
     514        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.RelLogger, RTLogRelGetDefaultInstance());
    615515        if (rc != VINF_VMM_CALL_HOST)
    616516            break;
     
    743643         */
    744644#ifdef LOG_ENABLED
    745         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
    746 #endif
    747         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
     645        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.Logger, NULL);
     646#endif
     647        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.RelLogger, RTLogRelGetDefaultInstance());
    748648        if (rc != VINF_VMM_CALL_HOST)
    749649            break;
     
    810710
    811711/**
     712 * Worker for VMMR3UpdateLoggers.
     713 */
     714static int vmmR3UpdateLoggersWorker(PVM pVM, PVMCPU pVCpu, PRTLOGGER pSrcLogger, bool fReleaseLogger)
     715{
     716    /*
     717     * Get the group count.
     718     */
     719    uint32_t uGroupsCrc32 = 0;
     720    uint32_t cGroups      = 0;
     721    uint64_t fFlags       = 0;
     722    int rc = RTLogQueryBulk(pSrcLogger, &fFlags, &uGroupsCrc32, &cGroups, NULL);
     723    Assert(rc == VERR_BUFFER_OVERFLOW);
     724
     725    /*
     726     * Allocate the request of the right size.
     727     */
     728    uint32_t const         cbReq = RT_UOFFSETOF_DYN(VMMR0UPDATELOGGERSREQ, afGroups[cGroups]);
     729    PVMMR0UPDATELOGGERSREQ pReq  = (PVMMR0UPDATELOGGERSREQ)RTMemAllocZVar(cbReq);
     730    if (pReq)
     731    {
     732        pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     733        pReq->Hdr.cbReq    = cbReq;
     734        pReq->cGroups      = cGroups;
     735        rc = RTLogQueryBulk(pSrcLogger, &pReq->fFlags, &pReq->uGroupCrc32, &pReq->cGroups, pReq->afGroups);
     736        AssertRC(rc);
     737        if (RT_SUCCESS(rc))
     738            rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_VMMR0_UPDATE_LOGGERS, fReleaseLogger, &pReq->Hdr);
     739
     740        RTMemFree(pReq);
     741    }
     742    else
     743        rc = VERR_NO_MEMORY;
     744    return rc;
     745}
     746
     747
     748/**
    812749 * Updates the settings for the RC and R0 loggers.
    813750 *
    814751 * @returns VBox status code.
    815752 * @param   pVM     The cross context VM structure.
     753 * @param   EMT
    816754 */
    817755VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM)
    818756{
    819     int rc = VINF_SUCCESS;
    820 
     757    VM_ASSERT_EMT(pVM);
     758    PVMCPU pVCpu = VMMGetCpu(pVM);
     759    AssertReturn(pVCpu, VERR_VM_THREAD_NOT_EMT);
     760
     761    /*
     762     * Each EMT has each own logger instance.
     763     */
     764    /* Debug logging.*/
     765    int rcDebug = VINF_SUCCESS;
    821766#ifdef LOG_ENABLED
    822     /*
    823      * For the ring-0 EMT logger, we use a per-thread logger instance
    824      * in ring-0. Only initialize it once.
    825      */
    826767    PRTLOGGER const pDefault = RTLogDefaultInstance();
    827     for (VMCPUID i = 0; i < pVM->cCpus; i++)
    828     {
    829         PVMCPU       pVCpu = pVM->apCpusR3[i];
    830         PVMMR0LOGGER pR0LoggerR3 = pVCpu->vmm.s.pR0LoggerR3;
    831         if (pR0LoggerR3)
    832         {
    833             if (!pR0LoggerR3->fCreated)
    834             {
    835                 RTR0PTR pfnLoggerWrapper = NIL_RTR0PTR;
    836                 rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerWrapper", &pfnLoggerWrapper);
    837                 AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerWrapper not found! rc=%Rra\n", rc), rc);
    838 
    839                 RTR0PTR pfnLoggerFlush = NIL_RTR0PTR;
    840                 rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerFlush", &pfnLoggerFlush);
    841                 AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerFlush not found! rc=%Rra\n", rc), rc);
    842 
    843                 char szR0ThreadName[16];
    844                 RTStrPrintf(szR0ThreadName, sizeof(szR0ThreadName), "EMT-%u-R0", i);
    845                 rc = RTLogCreateForR0(&pR0LoggerR3->Logger, pR0LoggerR3->cbLogger,
    846                                       pVCpu->vmm.s.pR0LoggerR0 + RT_UOFFSETOF(VMMR0LOGGER, Logger),
    847                                       pfnLoggerWrapper, pfnLoggerFlush,
    848                                       RTLOGFLAGS_BUFFERED, RTLOGDEST_DUMMY, szR0ThreadName);
    849                 AssertReleaseMsgRCReturn(rc, ("RTLogCreateForR0 failed! rc=%Rra\n", rc), rc);
    850 
    851                 pR0LoggerR3->idCpu = i;
    852                 pR0LoggerR3->fCreated = true;
    853                 pR0LoggerR3->fFlushingDisabled = false;
    854             }
    855 
    856             rc = RTLogCopyGroupsAndFlagsForR0(&pR0LoggerR3->Logger, pVCpu->vmm.s.pR0LoggerR0 + RT_UOFFSETOF(VMMR0LOGGER, Logger),
    857                                               pDefault, RTLOGFLAGS_BUFFERED, UINT32_MAX);
    858             AssertRC(rc);
    859         }
    860     }
     768    if (pDefault)
     769        rcDebug = vmmR3UpdateLoggersWorker(pVM, pVCpu, pDefault, false /*fReleaseLogger*/);
    861770#else
    862771    RT_NOREF(pVM);
    863772#endif
    864773
    865     return rc;
     774    /* Release logging. */
     775    int rcRelease = VINF_SUCCESS;
     776    PRTLOGGER const pRelease = RTLogRelGetDefaultInstance();
     777    if (pRelease)
     778        rcRelease = vmmR3UpdateLoggersWorker(pVM, pVCpu, pRelease, true /*fReleaseLogger*/);
     779
     780    return RT_SUCCESS(rcDebug) ? rcRelease : rcDebug;
    866781}
    867782
     
    11391054         */
    11401055#ifdef LOG_ENABLED
    1141         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
    1142 #endif
    1143         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
     1056        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.Logger, NULL);
     1057#endif
     1058        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.RelLogger, RTLogRelGetDefaultInstance());
    11441059        if (rc != VINF_VMM_CALL_HOST)
    11451060        {
     
    11831098         */
    11841099#ifdef LOG_ENABLED
    1185         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
    1186 #endif
    1187         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
     1100        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.Logger, NULL);
     1101#endif
     1102        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.RelLogger, RTLogRelGetDefaultInstance());
    11881103        if (rcStrict != VINF_VMM_CALL_HOST)
    11891104            return rcStrict;
     
    23402255         */
    23412256#ifdef LOG_ENABLED
    2342         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
    2343 #endif
    2344         VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
     2257        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.Logger, NULL);
     2258#endif
     2259        VMM_FLUSH_R0_LOG(&pVCpu->vmm.s.RelLogger, RTLogRelGetDefaultInstance());
    23452260        if (rc != VINF_VMM_CALL_HOST)
    23462261            break;
  • trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp

    r90549 r90829  
    218218    if (pHlp->pRelLogger)
    219219    {
    220         pHlp->fRelLoggerFlags = pHlp->pRelLogger->fFlags;
    221         pHlp->pRelLogger->fFlags &= ~RTLOGFLAGS_DISABLED;
    222         pHlp->pRelLogger->fFlags |= RTLOGFLAGS_BUFFERED;
     220        pHlp->fRelLoggerFlags = RTLogGetFlags(pHlp->pRelLogger);
     221        RTLogChangeFlags(pHlp->pRelLogger, RTLOGFLAGS_BUFFERED, RTLOGFLAGS_DISABLED);
    223222    }
    224223
    225224    if (pHlp->pLogger)
    226225    {
    227         pHlp->fLoggerFlags     = pHlp->pLogger->fFlags;
    228         pHlp->fLoggerDestFlags = pHlp->pLogger->fDestFlags;
    229         pHlp->pLogger->fFlags     &= ~RTLOGFLAGS_DISABLED;
    230         pHlp->pLogger->fFlags     |= RTLOGFLAGS_BUFFERED;
     226        pHlp->fLoggerFlags     = RTLogGetFlags(pHlp->pLogger);
     227        pHlp->fLoggerDestFlags = RTLogGetDestinations(pHlp->pLogger);
     228        RTLogChangeFlags(pHlp->pLogger, RTLOGFLAGS_BUFFERED, RTLOGFLAGS_DISABLED);
    231229#ifndef DEBUG_sandervl
    232         pHlp->pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
     230        RTLogChangeDestinations(pHlp->pLogger, RTLOGDEST_DEBUGGER, 0);
    233231#endif
    234232    }
     
    237235     * Check if we need write to stderr.
    238236     */
    239     pHlp->fStdErr = (!pHlp->pRelLogger || !(pHlp->pRelLogger->fDestFlags & (RTLOGDEST_STDOUT | RTLOGDEST_STDERR)))
    240                  && (!pHlp->pLogger    || !(pHlp->pLogger->fDestFlags    & (RTLOGDEST_STDOUT | RTLOGDEST_STDERR)));
     237    pHlp->fStdErr = (!pHlp->pRelLogger || !(RTLogGetDestinations(pHlp->pRelLogger) & (RTLOGDEST_STDOUT | RTLOGDEST_STDERR)))
     238                 && (!pHlp->pLogger    || !(RTLogGetDestinations(pHlp->pLogger)    & (RTLOGDEST_STDOUT | RTLOGDEST_STDERR)));
    241239#ifdef DEBUG_sandervl
    242240    pHlp->fStdErr = false; /* takes too long to display here */
     
    263261    {
    264262        RTLogFlush(pHlp->pRelLogger);
    265         pHlp->pRelLogger->fFlags = pHlp->fRelLoggerFlags;
     263        RTLogChangeFlags(pHlp->pRelLogger,
     264                         pHlp->fRelLoggerFlags & RTLOGFLAGS_DISABLED,
     265                         pHlp->fRelLoggerFlags & RTLOGFLAGS_BUFFERED);
    266266    }
    267267
     
    269269    {
    270270        RTLogFlush(pHlp->pLogger);
    271         pHlp->pLogger->fFlags     = pHlp->fLoggerFlags;
    272         pHlp->pLogger->fDestFlags = pHlp->fLoggerDestFlags;
     271        RTLogChangeFlags(pHlp->pLogger,
     272                         pHlp->fLoggerFlags & RTLOGFLAGS_DISABLED,
     273                         pHlp->fLoggerFlags & RTLOGFLAGS_BUFFERED);
     274        RTLogChangeDestinations(pHlp->pLogger, 0, pHlp->fLoggerDestFlags & RTLOGDEST_DEBUGGER);
    273275    }
    274276
  • trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp

    r82968 r90829  
    144144        pVCpu->pVMRC->vmm.s.fRCLoggerFlushingDisabled = true;
    145145#else
    146 # ifdef LOG_ENABLED
    147         if (pVCpu->vmm.s.pR0LoggerR0)
    148             pVCpu->vmm.s.pR0LoggerR0->fFlushingDisabled = true;
    149 # endif
    150         if (pVCpu->vmm.s.pR0RelLoggerR0)
    151             pVCpu->vmm.s.pR0RelLoggerR0->fFlushingDisabled = true;
     146        pVCpu->vmmr0.s.fLogFlushingDisabled = true;
     147        if (pVCpu->vmmr0.s.Logger.pLogger)
     148            pVCpu->vmmr0.s.Logger.pLogger->u32UserValue1 |= VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
     149        if (pVCpu->vmmr0.s.RelLogger.pLogger)
     150            pVCpu->vmmr0.s.RelLogger.pLogger->u32UserValue1 |= VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
    152151#endif
    153152    }
     
    178177        pVCpu->pVMRC->vmm.s.fRCLoggerFlushingDisabled = false;
    179178#else
    180 # ifdef LOG_ENABLED
    181         if (pVCpu->vmm.s.pR0LoggerR0)
    182             pVCpu->vmm.s.pR0LoggerR0->fFlushingDisabled = false;
    183 # endif
    184         if (pVCpu->vmm.s.pR0RelLoggerR0)
    185             pVCpu->vmm.s.pR0RelLoggerR0->fFlushingDisabled = false;
     179        pVCpu->vmmr0.s.fLogFlushingDisabled = false;
     180        if (pVCpu->vmmr0.s.Logger.pLogger)
     181            pVCpu->vmmr0.s.Logger.pLogger->u32UserValue1 &= ~VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
     182        if (pVCpu->vmmr0.s.RelLogger.pLogger)
     183            pVCpu->vmmr0.s.RelLogger.pLogger->u32UserValue1 &= ~VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED;
    186184#endif
    187185    }
  • trunk/src/VBox/VMM/include/VMMInternal.h

    r90597 r90829  
    6767
    6868/**
    69  * The ring-0 logger instance wrapper.
    70  *
    71  * We need to be able to find the VM handle from the logger instance, so we wrap
    72  * it in this structure.
    73  */
    74 typedef struct VMMR0LOGGER
     69 * R0 logger data (ring-0 only data).
     70 */
     71typedef struct VMMR0PERVCPULOGGER
    7572{
    76     /** Pointer to Pointer to the VM. */
    77     R0PTRTYPE(PVMCC)            pVM;
    78     /** Size of the allocated logger instance (Logger). */
    79     uint32_t                    cbLogger;
    80     /** Flag indicating whether we've create the logger Ring-0 instance yet. */
    81     bool                        fCreated;
    82     /** Flag indicating whether we've disabled flushing (world switch) or not. */
    83     bool                        fFlushingDisabled;
     73    /** Pointer to the logger instance.
     74     * The RTLOGGER::u32UserValue1 member is used for flags and magic, while the
     75     * RTLOGGER::u64UserValue2 member is the corresponding PGVMCPU value.
     76     * RTLOGGER::u64UserValue3 is currently and set to the PGVMCPU value too. */
     77    R0PTRTYPE(PRTLOGGER)    pLogger;
     78    /** Log buffer descriptor.
     79     * The buffer is allocated in a common block for all VCpus, see VMMR0PERVM. */
     80    RTLOGBUFFERDESC         BufDesc;
    8481    /** Flag indicating whether we've registered the instance already. */
    85     bool                        fRegistered;
    86     bool                        a8Alignment;
    87     /** The CPU ID. */
    88     VMCPUID                     idCpu;
    89 #if HC_ARCH_BITS == 64
    90     uint32_t                    u32Alignment;
    91 #endif
    92     /** The ring-0 logger instance. This extends beyond the size.  */
    93     RTLOGGER                    Logger;
    94 } VMMR0LOGGER;
    95 /** Pointer to a ring-0 logger instance wrapper. */
    96 typedef VMMR0LOGGER *PVMMR0LOGGER;
     82    bool                    fRegistered;
     83    bool                    afPadding[7];
     84} VMMR0PERVCPULOGGER;
     85/** Pointer to the R0 logger data (ring-0 only). */
     86typedef VMMR0PERVCPULOGGER *PVMMR0PERVCPULOGGER;
     87
     88
     89/**
     90 * R0 logger data shared with ring-3 (per CPU).
     91 */
     92typedef struct VMMR3CPULOGGER
     93{
     94    /** Auxiliary buffer descriptor. */
     95    RTLOGBUFFERAUXDESC      AuxDesc;
     96    /** Ring-3 mapping of the logging buffer. */
     97    R3PTRTYPE(char *)       pchBufR3;
     98    /** The buffer size. */
     99    uint32_t                cbBuf;
     100    uint32_t                uReserved;
     101} VMMR3CPULOGGER;
     102/** Pointer to r0 logger data shared with ring-3. */
     103typedef VMMR3CPULOGGER *PVMMR3CPULOGGER;
    97104
    98105
     
    367374    R3PTRTYPE(uint8_t *)        pbEMTStackR3;
    368375
    369     /** Pointer to the R0 logger instance - R3 Ptr.
    370      * This is NULL if logging is disabled. */
    371     R3PTRTYPE(PVMMR0LOGGER)     pR0LoggerR3;
    372     /** Pointer to the R0 logger instance - R0 Ptr.
    373      * This is NULL if logging is disabled. */
    374     R0PTRTYPE(PVMMR0LOGGER)     pR0LoggerR0;
    375 
    376     /** Pointer to the R0 release logger instance - R3 Ptr.
    377      * This is NULL if logging is disabled. */
    378     R3PTRTYPE(PVMMR0LOGGER)     pR0RelLoggerR3;
    379     /** Pointer to the R0 release instance - R0 Ptr.
    380      * This is NULL if logging is disabled. */
    381     R0PTRTYPE(PVMMR0LOGGER)     pR0RelLoggerR0;
    382 
    383376    /** @name Rendezvous
    384377     * @{ */
     
    435428    VMMR0JMPBUF                 CallRing3JmpBufR0;
    436429    /** @} */
     430
     431    /** @name Logging
     432     * @{ */
     433    /** The R0 logger data shared with ring-3. */
     434    VMMR3CPULOGGER              Logger;
     435    /** The R0 release logger data shared with ring-3. */
     436    VMMR3CPULOGGER              RelLogger;
     437    /** @}  */
    437438
    438439    STAMPROFILE                 StatR0HaltBlock;
     
    462463    /** Set if we've entered HM context. */
    463464    bool volatile                       fInHmContext;
    464 
    465     bool                                afPadding[5];
     465    /** Flag indicating whether we've disabled flushing (world switch) or not. */
     466    bool                                fLogFlushingDisabled;
    466467    /** The EMT hash table index. */
    467468    uint16_t                            idxEmtHash;
     
    483484    PSUPDRVSESSION                      pSession;
    484485    /** @} */
     486
     487    /** @name Loggers
     488     * @{ */
     489    /** The R0 logger data. */
     490    VMMR0PERVCPULOGGER                  Logger;
     491    /** The R0 release logger data. */
     492    VMMR0PERVCPULOGGER                  RelLogger;
     493    /** @} */
    485494} VMMR0PERVCPU;
    486495/** Pointer to VMM ring-0 VMCPU instance data. */
    487496typedef VMMR0PERVCPU *PVMMR0PERVCPU;
    488497
     498/** @name RTLOGGER::u32UserValue1 Flags
     499 * @{ */
     500/** The magic value. */
     501#define VMMR0_LOGGER_FLAGS_MAGIC_VALUE          UINT32_C(0x7d297f05)
     502/** Part of the flags value used for the magic. */
     503#define VMMR0_LOGGER_FLAGS_MAGIC_MASK           UINT32_C(0xffffff0f)
     504/** Set if flushing is disabled (copy of fLogFlushingDisabled). */
     505#define VMMR0_LOGGER_FLAGS_FLUSHING_DISABLED    UINT32_C(0x00000010)
     506/** @} */
     507
     508
     509/**
     510 * VMM data kept in the ring-0 GVM.
     511 */
     512typedef struct VMMR0PERVM
     513{
     514    /** Logger (debug) buffer allocation.
     515     * This covers all CPUs.  */
     516    RTR0MEMOBJ          hMemObjLogger;
     517    /** The ring-3 mapping object for hMemObjLogger. */
     518    RTR0MEMOBJ          hMapObjLogger;
     519
     520    /** Release logger buffer allocation.
     521     * This covers all CPUs.  */
     522    RTR0MEMOBJ          hMemObjReleaseLogger;
     523    /** The ring-3 mapping object for hMemObjReleaseLogger. */
     524    RTR0MEMOBJ          hMapObjReleaseLogger;
     525
     526    /** Set if vmmR0InitVM has been called. */
     527    bool                fCalledInitVm;
     528} VMMR0PERVM;
    489529
    490530RT_C_DECLS_BEGIN
     
    593633DECLASM(int)    vmmR0CallRing3LongJmp(PVMMR0JMPBUF pJmpBuf, int rc);
    594634
    595 /**
    596  * Internal R0 logger worker: Logger wrapper.
    597  */
    598 VMMR0DECL(void) vmmR0LoggerWrapper(const char *pszFormat, ...);
    599 
    600 /**
    601  * Internal R0 logger worker: Flush logger.
    602  *
    603  * @param   pLogger     The logger instance to flush.
    604  * @remark  This function must be exported!
    605  */
    606 VMMR0DECL(void) vmmR0LoggerFlush(PRTLOGGER pLogger);
    607 
    608 /**
    609  * Internal R0 logger worker: Custom prefix.
    610  *
    611  * @returns Number of chars written.
    612  *
    613  * @param   pLogger     The logger instance.
    614  * @param   pchBuf      The output buffer.
    615  * @param   cchBuf      The size of the buffer.
    616  * @param   pvUser      User argument (ignored).
    617  */
    618 VMMR0DECL(size_t) vmmR0LoggerPrefix(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
    619 
    620635# ifdef VBOX_WITH_TRIPLE_FAULT_HACK
    621636int  vmmR0TripleFaultHackInit(void);
  • trunk/src/VBox/VMM/include/VMMInternal.mac

    r90379 r90829  
    116116        .pbEMTStackR3           RTR3PTR_RES 1
    117117
    118         .pR0LoggerR3            RTR3PTR_RES 1
    119         .pR0LoggerR0            RTR0PTR_RES 1
    120         .pR0RelLoggerR3         RTR3PTR_RES 1
    121         .pR0RelLoggerR0         RTR0PTR_RES 1
    122 
    123118        .fInRendezvous          resb 1
    124119        .afPadding1             resb 2
Note: See TracChangeset for help on using the changeset viewer.

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