VirtualBox

Changeset 56965 in vbox


Ignore:
Timestamp:
Jul 17, 2015 12:37:30 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
101676
Message:

SSM.cpp: Dump (part of) the data unit on load failure to make it easier to debug.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/SSM.cpp

    r56956 r56965  
    29172917            pStrm->pCur = NULL;
    29182918        }
     2919        if (pStrm->pPending)
     2920        {
     2921            ssmR3StrmDestroyBufList(pStrm->pPending);
     2922            pStrm->pPending = NULL;
     2923        }
     2924        if (pStrm->pHead)
     2925        {
     2926            ssmR3StrmDestroyBufList(pStrm->pHead);
     2927            pStrm->pHead = NULL;
     2928        }
    29192929    }
    29202930    return rc;
     
    31213131    AssertRCReturnVoid(rc);
    31223132    ASMAtomicWriteHandle(&pStrm->hIoThread, hThread); /* paranoia */
     3133}
     3134
     3135
     3136/**
     3137 * Stops the I/O thread.
     3138 *
     3139 * @param   pStrm       The stream handle.
     3140 */
     3141static void ssmR3StrmStopIoThread(PSSMSTRM pStrm)
     3142{
     3143    LogFlow(("ssmR3StrmStopIoThread: %p\n", pStrm->hIoThread));
     3144    if (pStrm->hIoThread != NIL_RTTHREAD)
     3145    {
     3146        /*
     3147         * Signal the I/O thread and wait for it to complete.
     3148         */
     3149        ASMAtomicWriteBool(&pStrm->fTerminating, true);
     3150        if (pStrm->fWrite)
     3151        {
     3152            int rc1 = RTSemEventSignal(pStrm->hEvtHead);
     3153            AssertLogRelRC(rc1);
     3154        }
     3155        else
     3156        {
     3157            int rc2 = RTSemEventSignal(pStrm->hEvtFree);
     3158            AssertLogRelRC(rc2);
     3159        }
     3160        int rc3 = RTThreadWait(pStrm->hIoThread, RT_INDEFINITE_WAIT, NULL);
     3161        AssertLogRelRC(rc3);
     3162        pStrm->hIoThread = NIL_RTTHREAD;
     3163        pStrm->fTerminating = false; /* Can't read stuff otherwise. */
     3164    }
    31233165}
    31243166
     
    64876529     * Fend off previous errors and V1 data units.
    64886530     */
    6489     if (RT_FAILURE(pSSM->rc))
    6490         return pSSM->rc;
    6491     if (RT_UNLIKELY(pSSM->u.Read.uFmtVerMajor == 1))
     6531    if (RT_SUCCESS(pSSM->rc))
     6532    {
     6533        if (RT_LIKELY(pSSM->u.Read.uFmtVerMajor != 1))
     6534        {
     6535            /*
     6536             * Check if the requested data is buffered.
     6537             */
     6538            uint32_t off = pSSM->u.Read.offDataBuffer;
     6539            if (   off + cbBuf > pSSM->u.Read.cbDataBuffer
     6540                || cbBuf > sizeof(pSSM->u.Read.abDataBuffer))
     6541            {
     6542                if (cbBuf <= sizeof(pSSM->u.Read.abDataBuffer) / 8)
     6543                    return ssmR3DataReadBufferedV2(pSSM, pvBuf, cbBuf);
     6544                return ssmR3DataReadUnbufferedV2(pSSM, pvBuf, cbBuf);
     6545            }
     6546
     6547            memcpy(pvBuf, &pSSM->u.Read.abDataBuffer[off], cbBuf);
     6548            pSSM->u.Read.offDataBuffer = off + (uint32_t)cbBuf;
     6549            pSSM->offUnitUser += cbBuf;
     6550            Log4((cbBuf
     6551                  ? "ssmR3DataRead: %08llx|%08llx/%08x/%08x: cbBuf=%#x %.*Rhxs%s\n"
     6552                  : "ssmR3DataRead: %08llx|%08llx/%08x/%08x: cbBuf=%#x\n",
     6553                  ssmR3StrmTell(&pSSM->Strm), pSSM->offUnit, pSSM->u.Read.cbRecLeft, pSSM->u.Read.cbDataBuffer - pSSM->u.Read.offDataBuffer,
     6554                  cbBuf, RT_MIN(SSM_LOG_BYTES, cbBuf), pvBuf, cbBuf > SSM_LOG_BYTES ? "..." : ""));
     6555
     6556            return VINF_SUCCESS;
     6557        }
    64926558        return ssmR3DataReadV1(pSSM, pvBuf, cbBuf);
    6493 
    6494     /*
    6495      * Check if the requested data is buffered.
    6496      */
    6497     uint32_t off = pSSM->u.Read.offDataBuffer;
    6498     if (    off + cbBuf > pSSM->u.Read.cbDataBuffer
    6499         ||  cbBuf > sizeof(pSSM->u.Read.abDataBuffer))
    6500     {
    6501         if (cbBuf <= sizeof(pSSM->u.Read.abDataBuffer) / 8)
    6502             return ssmR3DataReadBufferedV2(pSSM, pvBuf, cbBuf);
    6503         return ssmR3DataReadUnbufferedV2(pSSM, pvBuf, cbBuf);
    6504     }
    6505 
    6506     memcpy(pvBuf, &pSSM->u.Read.abDataBuffer[off], cbBuf);
    6507     pSSM->u.Read.offDataBuffer = off + (uint32_t)cbBuf;
    6508     pSSM->offUnitUser += cbBuf;
    6509     Log4((cbBuf
    6510           ? "ssmR3DataRead: %08llx|%08llx/%08x/%08x: cbBuf=%#x %.*Rhxs%s\n"
    6511           : "ssmR3DataRead: %08llx|%08llx/%08x/%08x: cbBuf=%#x\n",
    6512           ssmR3StrmTell(&pSSM->Strm), pSSM->offUnit, pSSM->u.Read.cbRecLeft, pSSM->u.Read.cbDataBuffer - pSSM->u.Read.offDataBuffer,
    6513           cbBuf, RT_MIN(SSM_LOG_BYTES, cbBuf), pvBuf, cbBuf > SSM_LOG_BYTES ? "..." : ""));
    6514 
    6515     return VINF_SUCCESS;
     6559    }
     6560    return pSSM->rc;
    65166561}
    65176562
     
    80798124
    80808125#ifndef SSM_STANDALONE
     8126
     8127/**
     8128 * LogRel the unit content.
     8129 *
     8130 * @param   pSSM                The save state handle.
     8131 * @param   pUnitHdr            The unit head (for cbName).
     8132 * @param   offUnit             The offset of the unit header.
     8133 * @param   offStart            Where to start.
     8134 * @param   offEnd              Where to end.
     8135 */
     8136static void ssmR3StrmLogUnitContent(PSSMHANDLE pSSM, SSMFILEUNITHDRV2 const *pUnitHdr, uint64_t offUnit,
     8137                                    uint64_t offStart, uint64_t offEnd)
     8138{
     8139    /*
     8140     * Stop the I/O thread (if present).
     8141     */
     8142    ssmR3StrmStopIoThread(&pSSM->Strm);
     8143
     8144    /*
     8145     * Save the current status, resetting it so we can read + log the unit bytes.
     8146     */
     8147    int rcSaved = pSSM->rc;
     8148    pSSM->rc = VINF_SUCCESS;
     8149
     8150    /*
     8151     * Reverse back to the start of the unit if we can.
     8152     */
     8153    uint32_t cbUnitHdr = RT_UOFFSETOF(SSMFILEUNITHDRV2, szName[pUnitHdr->cbName]);
     8154    int rc = ssmR3StrmSeek(&pSSM->Strm, offUnit/* + cbUnitHdr*/, RTFILE_SEEK_BEGIN, pUnitHdr->u32CurStreamCRC);
     8155    if (RT_SUCCESS(rc))
     8156    {
     8157        SSMFILEUNITHDRV2 UnitHdr2;
     8158        rc = ssmR3StrmRead(&pSSM->Strm, &UnitHdr2, cbUnitHdr);
     8159        if (   RT_SUCCESS(rc)
     8160            && memcmp(&UnitHdr2, pUnitHdr, cbUnitHdr) == 0)
     8161        {
     8162            pSSM->u.Read.cbDataBuffer = 0; /* avoid assertions */
     8163            pSSM->u.Read.cbRecLeft    = 0;
     8164            ssmR3DataReadBeginV2(pSSM);
     8165
     8166            /*
     8167             * Read the unit, dumping the requested bits.
     8168             */
     8169            uint8_t     cbLine = 0;
     8170            uint8_t     abLine[16];
     8171            uint64_t    offCur = 0;
     8172            offStart &= ~(uint64_t)(sizeof(abLine) - 1);
     8173            Assert(offStart < offEnd);
     8174            LogRel(("SSM: Unit '%s' contents:\n", pUnitHdr->szName));
     8175
     8176            do
     8177            {
     8178                /*
     8179                 * Read the next 16 bytes into abLine.  We have to take some care to
     8180                 * get all the bytes in the unit, since we don't really know its size.
     8181                 */
     8182                while (   cbLine < sizeof(abLine)
     8183                       && !pSSM->u.Read.fEndOfData
     8184                       && RT_SUCCESS(pSSM->rc))
     8185                {
     8186                    uint32_t cbToRead = sizeof(abLine) - cbLine;
     8187                    if (cbToRead > 1)
     8188                    {
     8189                        int32_t cbInBuffer = pSSM->u.Read.cbDataBuffer - pSSM->u.Read.offDataBuffer;
     8190                        if ((int32_t)cbToRead > cbInBuffer)
     8191                        {
     8192                            if (cbInBuffer > 0)
     8193                                cbToRead = cbInBuffer;
     8194                            else if (pSSM->u.Read.cbRecLeft)
     8195                                cbToRead = 1;
     8196                            else
     8197                            {
     8198                                rc = ssmR3DataReadRecHdrV2(pSSM);
     8199                                if (RT_FAILURE(rc))
     8200                                {
     8201                                    pSSM->rc = rc;
     8202                                    break;
     8203                                }
     8204                                if (pSSM->u.Read.fEndOfData)
     8205                                    break;
     8206                            }
     8207                        }
     8208                    }
     8209                    rc = ssmR3DataRead(pSSM, &abLine[cbLine], cbToRead);
     8210                    if (RT_SUCCESS(rc))
     8211                        cbLine += cbToRead;
     8212                    else
     8213                        break;
     8214                }
     8215
     8216                /*
     8217                 * Display the bytes if in the requested range.
     8218                 */
     8219                if (   offCur >= offStart
     8220                    && offCur <= offEnd)
     8221                {
     8222                    char    szLine[132];
     8223                    char   *pchDst = szLine;
     8224                    uint8_t offSrc = 0;
     8225                    while (offSrc < cbLine)
     8226                    {
     8227                        static char const s_szHex[17] = "0123456789abcdef";
     8228                        uint8_t const b = abLine[offSrc++];
     8229                        *pchDst++ = s_szHex[b >> 4];
     8230                        *pchDst++ = s_szHex[b & 7];
     8231                        *pchDst++ = offSrc != 8 ? ' ' : '-';
     8232                    }
     8233                    while (offSrc < sizeof(abLine))
     8234                    {
     8235                        *pchDst++ = ' ';
     8236                        *pchDst++ = ' ';
     8237                        *pchDst++ = offSrc != 7 ? ' ' : '-';
     8238                        offSrc++;
     8239                    }
     8240                    *pchDst++ = ' ';
     8241
     8242                    offSrc = 0;
     8243                    while (offSrc < cbLine)
     8244                    {
     8245                        char const ch = (int8_t)abLine[offSrc++];
     8246                        if (ch < 0x20 || ch >= 0x7f)
     8247                            *pchDst++ = '.';
     8248                        else
     8249                            *pchDst++ = ch;
     8250                    }
     8251                    *pchDst = '\0';
     8252                    Assert((uintptr_t)(pchDst - &szLine[0]) < sizeof(szLine));
     8253                    Assert(strchr(szLine, '\0') == pchDst);
     8254
     8255                    LogRel(("%#010llx: %s\n", offCur, szLine));
     8256                }
     8257                offCur += cbLine;
     8258                cbLine = 0;
     8259            } while (   !pSSM->u.Read.fEndOfData
     8260                     && RT_SUCCESS(pSSM->rc));
     8261            LogRel(("SSM: offCur=%#llx fEndOfData=%d (rc=%Rrc)\n", offCur, pSSM->u.Read.fEndOfData, rc));
     8262        }
     8263        else if (RT_SUCCESS(rc))
     8264            LogRel(("SSM: Cannot dump unit - mismatching unit head\n"));
     8265        else
     8266            LogRel(("SSM: Cannot dump unit - unit header read error: %Rrc\n", rc));
     8267    }
     8268    else
     8269        LogRel(("SSM: Cannot dump unit - ssmR3StrmSeek error: %Rrc\n", rc));
     8270
     8271    pSSM->rc = rc;
     8272}
     8273
    80818274
    80828275/**
     
    84938686                LogRel(("SSM: LoadExec failed for '%s' instance #%u (version %u, pass %#x): %Rrc\n",
    84948687                        UnitHdr.szName, UnitHdr.u32Instance, UnitHdr.u32Version, UnitHdr.u32Pass, rc));
     8688                LogRel(("SSM: Unit at %#llx, current position: offUnit=%#llx offUnitUser=%#llx\n",
     8689                        offUnit, pSSM->offUnit, pSSM->offUnitUser));
     8690
    84958691                if (!ASMAtomicXchgBool(&pSSM->u.Read.fHaveSetError, true))
    84968692                {
     
    85018697                        rc = VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to load unit '%s'"), UnitHdr.szName);
    85028698                }
     8699
     8700                /* Try log the unit content, unless it's too big. */
     8701                if (pSSM->offUnitUser < _512KB)
     8702                    ssmR3StrmLogUnitContent(pSSM, &UnitHdr, offUnit, 0, pSSM->offUnitUser + _16K);
     8703                else
     8704                    ssmR3StrmLogUnitContent(pSSM, &UnitHdr, offUnit, pSSM->offUnitUser - _256K, pSSM->offUnitUser + _16K);
    85038705                return rc;
    85048706            }
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