VirtualBox

Changeset 12581 in vbox for trunk/src


Ignore:
Timestamp:
Sep 18, 2008 4:10:12 PM (16 years ago)
Author:
vboxsync
Message:

IPRT/log: Added a fallback path that deals with failure to obtain the logger lock when the IRQL is too high (more or less windows only).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/log/log.cpp

    r12302 r12581  
    8282#ifndef IN_GC
    8383static unsigned rtlogGroupFlags(const char *psz);
     84#endif
     85#ifdef IN_RING0
     86static void rtR0LogLoggerExFallback(uint32_t fDestFlags, const char *pszFormat, va_list va);
    8487#endif
    8588static void rtlogFlush(PRTLOGGER pLogger);
     
    565568     */
    566569    rc = rtlogLock(pLogger);
    567     if (RT_FAILURE(rc))
    568         return rc;
     570    AssertRCReturn(rc, rc);
    569571
    570572    pLogger->fFlags |= RTLOGFLAGS_DISABLED;
     
    15851587    rc = rtlogLock(pLogger);
    15861588    if (RT_FAILURE(rc))
     1589    {
     1590#ifdef IN_RING0
     1591        if (pLogger->fDestFlags & ~RTLOGDEST_FILE)
     1592            rtR0LogLoggerExFallback(pLogger->fDestFlags, pszFormat, args);
     1593#endif
    15871594        return;
     1595    }
    15881596
    15891597    /*
     
    16091617    rtlogUnlock(pLogger);
    16101618}
     1619
     1620#ifdef IN_RING0
     1621/**
     1622 * For rtR0LogLoggerExFallbackOutput and rtR0LogLoggerExFallbackFlush.
     1623 */
     1624typedef struct RTR0LOGLOGGERFALLBACK
     1625{
     1626    /** The current scratch buffer offset. */
     1627    uint32_t offScratch;
     1628    /** The destination flags. */
     1629    uint32_t fDestFlags;
     1630    /** The scratch buffer. */
     1631    char achScratch[80];
     1632} RTR0LOGLOGGERFALLBACK;
     1633/** Pointer to RTR0LOGLOGGERFALLBACK which is used by
     1634 * rtR0LogLoggerExFallbackOutput. */
     1635typedef RTR0LOGLOGGERFALLBACK *PRTR0LOGLOGGERFALLBACK;
     1636
     1637
     1638/**
     1639 * Flushes the fallback buffer.
     1640 *
     1641 * @param   pThis       The scratch buffer.
     1642 */
     1643static void rtR0LogLoggerExFallbackFlush(PRTR0LOGLOGGERFALLBACK pThis)
     1644{
     1645    if (!pThis->offScratch)
     1646        return;
     1647
     1648    if (pThis->fDestFlags & RTLOGDEST_USER)
     1649        RTLogWriteUser(pThis->achScratch, pThis->offScratch);
     1650
     1651    if (pThis->fDestFlags & RTLOGDEST_DEBUGGER)
     1652        RTLogWriteDebugger(pThis->achScratch, pThis->offScratch);
     1653
     1654    if (pThis->fDestFlags & RTLOGDEST_STDOUT)
     1655        RTLogWriteStdOut(pThis->achScratch, pThis->offScratch);
     1656
     1657    if (pThis->fDestFlags & RTLOGDEST_STDERR)
     1658        RTLogWriteStdErr(pThis->achScratch, pThis->offScratch);
     1659
     1660#ifndef LOG_NO_COM
     1661    if (pThis->fDestFlags & RTLOGDEST_COM)
     1662        RTLogWriteCom(pThis->achScratch, pThis->offScratch);
     1663#endif
     1664
     1665    /* empty the buffer. */
     1666    pThis->offScratch = 0;
     1667}
     1668
     1669
     1670/**
     1671 * Callback for RTLogFormatV used by rtR0LogLoggerExFallback.
     1672 * See PFNLOGOUTPUT() for details.
     1673 */
     1674static DECLCALLBACK(size_t) rtR0LogLoggerExFallbackOutput(void *pv, const char *pachChars, size_t cbChars)
     1675{
     1676    PRTR0LOGLOGGERFALLBACK pThis = (PRTR0LOGLOGGERFALLBACK)pv;
     1677    if (cbChars)
     1678    {
     1679        size_t cbRet = 0;
     1680        for (;;)
     1681        {
     1682            /* how much */
     1683            uint32_t cb = sizeof(pThis->achScratch) - pThis->offScratch - 1; /* minus 1 - for the string terminator. */
     1684            if (cb > cbChars)
     1685                cb = cbChars;
     1686
     1687            /* copy */
     1688            memcpy(&pThis->achScratch[pThis->offScratch], pachChars, cb);
     1689
     1690            /* advance */
     1691            pThis->offScratch += cb;
     1692            cbRet += cb;
     1693            cbChars -= cb;
     1694
     1695            /* done? */
     1696            if (cbChars <= 0)
     1697                return cbRet;
     1698
     1699            pachChars += cb;
     1700
     1701            /* flush */
     1702            pThis->achScratch[pThis->offScratch] = '\0';
     1703            rtR0LogLoggerExFallbackFlush(pThis);
     1704        }
     1705
     1706        /* won't ever get here! */
     1707    }
     1708    else
     1709    {
     1710        /*
     1711         * Termination call, flush the log.
     1712         */
     1713        pThis->achScratch[pThis->offScratch] = '\0';
     1714        rtR0LogLoggerExFallbackFlush(pThis);
     1715        return 0;
     1716    }
     1717}
     1718
     1719
     1720/**
     1721 * Ring-0 fallback for cases where we're unable to grab the lock.
     1722 *
     1723 * This will happen when we're at a too high IRQL on Windows for instance and
     1724 * needs to be dealt with or we'll drop a lot of log output. This fallback will
     1725 * only output to some of the log destinations as a few of them may be doing
     1726 * dangerouse things. We won't be doing any prefixing here either, at least not
     1727 * for the present, because it's too much hazzle.
     1728 *
     1729 * @param   pLogger     The destination flags.
     1730 * @param   pszFormat   The format string.
     1731 * @param   va          The format arguments.
     1732 */
     1733static void rtR0LogLoggerExFallback(uint32_t fDestFlags, const char *pszFormat, va_list va)
     1734{
     1735    RTR0LOGLOGGERFALLBACK This;
     1736    This.fDestFlags = fDestFlags;
     1737    This.offScratch = 0;
     1738    RTLogFormatV(rtR0LogLoggerExFallbackOutput, &This, pszFormat, va);
     1739}
     1740#endif /* IN_RING0 */
    16111741
    16121742
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