Changeset 56965 in vbox
- Timestamp:
- Jul 17, 2015 12:37:30 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 101676
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/SSM.cpp
r56956 r56965 2917 2917 pStrm->pCur = NULL; 2918 2918 } 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 } 2919 2929 } 2920 2930 return rc; … … 3121 3131 AssertRCReturnVoid(rc); 3122 3132 ASMAtomicWriteHandle(&pStrm->hIoThread, hThread); /* paranoia */ 3133 } 3134 3135 3136 /** 3137 * Stops the I/O thread. 3138 * 3139 * @param pStrm The stream handle. 3140 */ 3141 static 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 } 3123 3165 } 3124 3166 … … 6487 6529 * Fend off previous errors and V1 data units. 6488 6530 */ 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 } 6492 6558 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; 6516 6561 } 6517 6562 … … 8079 8124 8080 8125 #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 */ 8136 static 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 8081 8274 8082 8275 /** … … 8493 8686 LogRel(("SSM: LoadExec failed for '%s' instance #%u (version %u, pass %#x): %Rrc\n", 8494 8687 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 8495 8691 if (!ASMAtomicXchgBool(&pSSM->u.Read.fHaveSetError, true)) 8496 8692 { … … 8501 8697 rc = VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to load unit '%s'"), UnitHdr.szName); 8502 8698 } 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); 8503 8705 return rc; 8504 8706 }
Note:
See TracChangeset
for help on using the changeset viewer.