log.cpp revision 19f5c34b5a25bad35564b359413fb6b74a1cf648
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync * Runtime VBox - Logger.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync * available from http://www.virtualbox.org. This file is free software;
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync * you can redistribute it and/or modify it under the terms of the GNU
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync * General Public License (GPL) as published by the Free Software
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * The contents of this file may alternatively be used under the terms
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * of the Common Development and Distribution License Version 1.0
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * VirtualBox OSE distribution, in which case the provisions of the
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * CDDL are applicable instead of those of the GPL.
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * You may elect to license modified versions of this file under the
2a2095adf36a009010d72cf36ffabb3c1261ad08vboxsync * terms and conditions of either the GPL or the CDDL or both.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
#ifndef IN_GC
#ifdef IN_RING3
#ifdef IN_RING3
# include <stdio.h>
typedef struct RTLOGOUTPUTPREFIXEDARGS
unsigned fFlags;
unsigned iGroup;
#ifndef IN_GC
static void rtlogLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
#ifdef IN_GC
#ifdef IN_RING3
#ifdef IN_RING0
static struct RTLOGGERPERTHREAD
{ { NIL_RTNATIVETHREAD, 0, 0},
{ NIL_RTNATIVETHREAD, 0, 0},
{ NIL_RTNATIVETHREAD, 0, 0},
{ NIL_RTNATIVETHREAD, 0, 0},
{ NIL_RTNATIVETHREAD, 0, 0},
{ NIL_RTNATIVETHREAD, 0, 0},
{ NIL_RTNATIVETHREAD, 0, 0},
{ NIL_RTNATIVETHREAD, 0, 0}
#ifndef IN_GC
return VINF_SUCCESS;
#ifndef IN_GC
#ifndef IN_GC
* @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL.
int rc;
return VERR_INVALID_PARAMETER;
if (pszErrorMsg)
if (pLogger)
if (pszGroupSettings)
if (pu8Code)
#ifdef RT_ARCH_AMD64
pu8Code += sizeof(void *);
if (pszFilenameFmt)
if (pszEnvVarBase)
if (pszVar)
while (*pszVar)
pszVar++;
if (!*pszVar)
const char *pszInstr;
unsigned fFlag;
} const aDest[] =
bool fNo = false;
fNo = true;
if (!fNo)
pszVar++;
pszVar++;
if (!pszEnd)
if (pszFile)
AssertMsgFailed(("Invalid %s_DEST! %s%s doesn't take a value!\n", pszEnvVarBase, fNo ? "no" : "", aDest[i].pszInstr));
pszVar++;
pszVar++;
if (pszVar)
if (pszVar)
#ifdef IN_RING3
return VINF_SUCCESS;
if (pszErrorMsg)
#ifdef IN_RING3
#ifdef RT_OS_LINUX
if (pszErrorMsg)
return rc;
int rc;
rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, fDestFlags, NULL, 0, pszFilenameFmt, args);
return rc;
* @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL.
int rc;
rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, fDestFlags, pszErrorMsg, cchErrorMsg, pszFilenameFmt, args);
return rc;
int rc;
if (!pLogger)
return VINF_SUCCESS;
return rc;
while (iGroup-- > 0)
#ifdef IN_RING3
int rc2;
return rc;
if ( !pLoggerGC
|| !pfnFlushGCPtr
|| !pfnLoggerGCPtr)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
AssertMsgFailed(("%d req=%d cGroups=%d\n", cbLoggerGC, RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]), pLogger->cGroups));
return VERR_INVALID_PARAMETER;
memcpy(&pLoggerGC->afGroups[0], &pLogger->afGroups[0], pLogger->cGroups * sizeof(pLoggerGC->afGroups[0]));
return VINF_SUCCESS;
if (!pLogger)
if (!pLogger)
#ifdef IN_RING3
RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger, PFNRTLOGGER pfnLogger, PFNRTLOGFLUSH pfnFlush, RTUINT fFlags, RTUINT fDestFlags)
pLogger->cMaxGroups = (cbLogger - RT_OFFSETOF(RTLOGGER, afGroups[0])) / sizeof(pLogger->afGroups[0]);
return VINF_SUCCESS;
RTDECL(int) RTLogCopyGroupsAndFlags(PRTLOGGER pDstLogger, PCRTLOGGER pSrcLogger, unsigned fFlagsOr, unsigned fFlagsAnd)
int rc;
unsigned cGroups;
if (!pSrcLogger)
if (!pSrcLogger)
return VINF_SUCCESS;
memcpy(&pDstLogger->afGroups[0], &pSrcLogger->afGroups[0], cGroups * sizeof(pDstLogger->afGroups[0]));
return rc;
if (!pDstLogger)
if (!pDstLogger)
const char *pachMask;
const char *pszTmp;
do pachMask++;
if ( !cchMask
if (!pszTmp)
if (!pszTmp)
if (!*++pszGrp)
pachMask++;
cchMask--;
if ( !cchMask
if (!--cchMask)
pachMask++;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
while (*pszVar)
bool fEnabled = true;
char ch;
const char *pszStart;
pszVar++;
if (!*pszVar)
pszVar++;
if (fEnabled)
if (fEnabled)
return VINF_SUCCESS;
unsigned fFlags = 0;
unsigned fFlag;
} aFlags[] =
bool fFound = false;
psz++;
psz1++;
psz2++;
if (!*psz1)
fFound = true;
psz++;
return fFlags;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
while (*pszVar)
const char *pszInstr;
unsigned fFlag;
bool fInverted;
} const aDest[] =
bool fNo = false;
char ch;
pszVar++;
if (!*pszVar)
return rc;
pszVar++;
fNo = true;
pszVar++;
pszVar++;
pszVar++;
return rc;
if (!pLogger)
#ifdef IN_GC
if (!pLogger)
#ifndef IN_GC
#ifndef IN_GC
#ifdef IN_GC
return &g_Logger;
# ifdef IN_RING0
if (g_cPerThreadLoggers)
if (!g_pLogger)
return g_pLogger;
#ifndef IN_GC
#ifdef IN_RING0
int rc;
if (pLogger)
int32_t i;
return VINF_SUCCESS;
&& ASMAtomicCmpXchgPtr((void * volatile *)&g_aPerThreadLoggers[i].NativeThread, (void *)Self, (void *)NIL_RTNATIVETHREAD))
return VINF_SUCCESS;
ASMAtomicXchgPtr((void * volatile *)&g_aPerThreadLoggers[i].NativeThread, (void *)NIL_RTNATIVETHREAD);
return rc;
#ifdef IN_GC
return &g_RelLogger;
return g_pRelLogger;
#ifndef IN_GC
RTDECL(void) RTLogLoggerEx(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
if (!pLogger)
if (!pLogger)
RTDECL(void) RTLogRelLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
RTDECL(void) RTLogRelLoggerV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
if (!pLogger)
if (!pLogger)
static void rtlogLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
int rc;
iGroup = 0;
#ifndef IN_GC
if ( iGroup != ~0U
&& (pLogger->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))
#ifndef IN_GC
# ifdef IN_RING3
if (cbChars)
if (cbChars <= 0)
return cbRet;
if (cbChars)
char *psz;
const char *pszNewLine;
fFlags = 0;
fFlags = 0;
#ifdef IN_RING3
#ifdef IN_RING3
#ifndef IN_GC
#ifndef IN_GC
#ifdef IN_RING3
if (pszName)
#ifdef IN_RING3
if (pszGroup)
const char *pszGroup;
if (pszGroup)
else if (cb <= 0)
if (pszNewLine)
if ( pszNewLine
cbRet++;
cbChars--;
cb++;
if (cbChars <= 0)
return cbRet;