log.cpp revision adfda3cce28f06b632afdb5ea301475bacfdabdd
1N/A * available from http://www.virtualbox.org. This file is free software;
1N/Atypedef struct RTLOGOUTPUTPREFIXEDARGS
1N/Atypedef struct RTLOGGERINTERNAL
1N/A void *pvPrefixUserArg;
1N/A bool fPendingPrefix;
1N/A const char * const *papszGroups;
1N/Astatic void rtR0LogLoggerExFallback(uint32_t fDestFlags, uint32_t fFlags, const char *pszFormat, va_list va);
1N/Astatic DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars);
1N/Astatic void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
1N/Astatic void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
1N/A# ifdef RT_OS_DARWIN
1N/Astatic struct RTLOGGERPERTHREAD
1N/A { NIL_RTNATIVETHREAD, 0, 0},
1N/A { NIL_RTNATIVETHREAD, 0, 0},
1N/A { NIL_RTNATIVETHREAD, 0, 0},
1N/A { NIL_RTNATIVETHREAD, 0, 0},
1N/A { NIL_RTNATIVETHREAD, 0, 0},
1N/A { NIL_RTNATIVETHREAD, 0, 0},
1N/A { NIL_RTNATIVETHREAD, 0, 0},
1N/A { NIL_RTNATIVETHREAD, 0, 0}
1N/A} const s_aLogFlags[] =
1N/A{ 10, 10, 10, 20, 50, 100, 200, 200, 200, 200, 500, 500, 500, 500, 1000, 1000, 1000, 1000, 1000, 1000, 1000 };
1N/A AssertMsgReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pInt->uRevision, RTLOGGERINTERNAL_REV),
1N/A return VINF_SUCCESS;
1N/A# ifdef SOME_UNUSED_FUNCTION
1N/Astatic DECLCALLBACK(size_t) rtlogPhaseFormatStr(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
1N/A AssertMsgFailed(("Invalid logger phase format type '%%%c%.10s'!\n", ch, *ppszFormat)); NOREF(ch);
int rc;
return VERR_INVALID_PARAMETER;
if (pszErrorMsg)
if (pLogger)
# ifdef IN_RING3
if (cbHistoryFileMax == 0)
if (cSecsHistoryTimeSlot == 0)
if (pszGroupSettings)
if (pu8Code)
pu8Code += sizeof(void *);
# ifdef RT_OS_LINUX
if (pszFilenameFmt)
if (pszEnvVarBase)
if (pszValue)
if (pszValue)
if (pszValue)
# ifdef IN_RING3
return VINF_SUCCESS;
if (pszErrorMsg)
# ifdef IN_RING3
return rc;
int rc;
return rc;
int rc;
return rc;
int rc;
if (!pLogger)
return VINF_SUCCESS;
while (iGroup-- > 0)
# ifdef IN_RING3
int rc2;
return rc;
if ( !pLoggerRC
|| !pfnFlushRCPtr
|| !pfnLoggerRCPtr)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
AssertMsgFailed(("%d req=%d cGroups=%d\n", cbLoggerRC, RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]), pLogger->cGroups));
return VERR_BUFFER_OVERFLOW;
memcpy(&pLoggerRC->afGroups[0], &pLogger->afGroups[0], pLogger->cGroups * sizeof(pLoggerRC->afGroups[0]));
return VINF_SUCCESS;
if (!pLogger)
if (!pLogger)
# ifdef IN_RING3
cMaxGroups--;
return VINF_SUCCESS;
return cb;
if (!pSrcLogger)
if (!pSrcLogger)
return VINF_SUCCESS;
PRTLOGGERINTERNAL pDstInt = (PRTLOGGERINTERNAL)((uintptr_t)pDstLogger->pInt - pDstLoggerR0Ptr + (uintptr_t)pDstLogger);
pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups]) + RTLOGGERINTERNAL_R0_SIZE));
memcpy(&pDstLogger->afGroups[0], &pSrcLogger->afGroups[0], cGroups * sizeof(pDstLogger->afGroups[0]));
return rc;
PRTLOGGERINTERNAL pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger->pInt - pLoggerR0Ptr + (uintptr_t)pLogger);
return VINF_SUCCESS;
if (!pLogger)
if (!pLogger)
if (!pDstLogger)
if (!pDstLogger)
RTDECL(int) RTLogSetCustomPrefixCallback(PRTLOGGER pLogger, PFNRTLOGPREFIX pfnCallback, void *pvUser)
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
return VINF_SUCCESS;
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 (*pszValue)
bool fEnabled = true;
char ch;
const char *pszStart;
pszValue++;
if (!*pszValue)
pszValue++;
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;
static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, char **ppszBuf, size_t *pcchBuf, bool *pfNotFirst)
# define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)
return VERR_BUFFER_OVERFLOW;
if (*pfNotFirst)
*pfNotFirst = true;
else if ( fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_LEVEL_2 | RTLOGGRPFLAGS_FLOW)
return VERR_BUFFER_OVERFLOW;
return VINF_SUCCESS;
bool fNotFirst = false;
uint32_t i;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
if (i >= cGroups)
for (i = 0; i < cGroups; i++)
if (fGroup)
if (pszName)
if (rc)
return rc;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
while (*pszValue)
bool fNo = false;
char ch;
pszValue++;
if (!*pszValue)
return rc;
pszValue++;
fNo = true;
pszValue++;
pszValue++;
pszValue++;
return rc;
bool fOld;
if (!pLogger)
if (!pLogger)
if (fBuffered)
return fOld;
#ifdef IN_RING3
if (!pLogger)
if (!pLogger)
return UINT32_MAX;
return cOld;
#ifndef IN_RC
bool fNotFirst = false;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
if (fNotFirst)
cchBuf--;
fNotFirst = true;
return rc;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
while (*pszValue)
bool fNo;
pszValue++;
if (!*pszValue)
fNo = false;
fNo = true;
if (!fNo)
pszValue++;
const char *pszEnd;
pszValue++;
if (!pszEnd)
# ifdef IN_RING3
if (!fNo)
AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc);
if (!fNo)
if (!fNo)
pszValue++;
return VINF_SUCCESS;
bool fNotFirst = false;
if (!pLogger)
if (!pLogger)
return VINF_SUCCESS;
if (fNotFirst)
return rc;
return rc;
fNotFirst = true;
# ifdef IN_RING3
return rc;
return rc;
fNotFirst = true;
RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " history=%u" : "history=%u", pLogger->pInt->cHistory);
return rc;
fNotFirst = true;
RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histsize=%llu" : "histsize=%llu", pLogger->pInt->cbHistoryFileMax);
return rc;
fNotFirst = true;
RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histtime=%llu" : "histtime=%llu", pLogger->pInt->cSecsHistoryTimeSlot);
return rc;
fNotFirst = true;
return VINF_SUCCESS;
if (!pLogger)
#ifdef IN_RC
if (!pLogger)
#ifndef IN_RC
#ifndef IN_RC
#ifdef IN_RC
return &g_Logger;
# ifdef IN_RING0
if (g_cPerThreadLoggers)
if (!g_pLogger)
return g_pLogger;
#ifdef IN_RC
return &g_Logger;
# ifdef IN_RING0
if (g_cPerThreadLoggers)
return g_pLogger;
#ifndef IN_RC
#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;
return rc;
RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
int rc;
if (!pLogger)
if (!pLogger)
iGroup = 0;
#ifndef IN_RC
if ( iGroup != ~0U
&& (pLogger->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))
#ifdef IN_RING0
#ifndef IN_RC
#ifdef IN_RING0
typedef struct RTR0LOGLOGGERFALLBACK
# ifndef LOG_NO_COM
static DECLCALLBACK(size_t) rtR0LogLoggerExFallbackOutput(void *pv, const char *pachChars, size_t cbChars)
if (cbChars)
uint32_t cb = sizeof(pThis->achScratch) - pThis->offScratch - 1; /* minus 1 - for the string terminator. */
if (cbChars <= 0)
return cbRet;
static void rtR0LogLoggerExFallback(uint32_t fDestFlags, uint32_t fFlags, const char *pszFormat, va_list va)
This.offScratch += RTStrFormatNumber(&This.achScratch[This.offScratch], Process, 16, sizeof(RTPROCESS) * 2, 0, RTSTR_F_ZEROPAD);
This.offScratch += RTStrFormatNumber(&This.achScratch[This.offScratch], Thread, 16, sizeof(RTNATIVETHREAD) * 2, 0, RTSTR_F_ZEROPAD);
#ifdef IN_RING3
int rc;
unsigned cBackoff = 0;
cBackoff++;
if (pszErrorMsg)
RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pInt->szFilename, fOpen);
return rc;
if (cSavedHistory)
int rc;
unsigned cBackoff = 0;
cBackoff++;
if (cchScratch == 0)
AssertFailed();
#ifndef IN_RC
# ifdef IN_RING3
#ifdef IN_RC
#ifdef IN_RING3
rtlogRotate(pLogger, RTTimeProgramSecTS() / pLogger->pInt->cSecsHistoryTimeSlot, false /* fFirst */);
if (cbChars)
if (cbChars <= 0)
return cbRet;
DECLINLINE(char *) rtLogStPNCpyPad(char *pszDst, const char *pszSrc, size_t cchSrcMax, size_t cchMinWidth)
if (pszSrc)
return pszDst;
if (cbChars)
const char *pszNewLine;
char *psz;
#ifdef IN_RC
if (*pfPendingPrefix)
*pfPendingPrefix = false;
fFlags = 0;
fFlags = 0;
#ifndef IN_RC
#ifndef IN_RC
#ifdef IN_RING3
#ifndef IN_RC
#ifdef IN_RING3
const char *pszGroup;
else if (cb <= 0)
if (pszNewLine)
*pfPendingPrefix = true;
if ( pszNewLine
cbRet++;
cbChars--;
cb++;
*pfPendingPrefix = true;
if (cbChars <= 0)
return cbRet;
static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
#ifndef IN_RC