Changeset 84488 in vbox for trunk/src/VBox/VMM
- Timestamp:
- May 25, 2020 10:21:02 AM (5 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/DBGFAllTracer.cpp
r84458 r84488 94 94 size_t cbEvtDesc, uint64_t *pidEvt) 95 95 { 96 LogFlowFunc(("pVM=%p pThisCC=%p hEvtSrc=%llu enmTraceEvt=%u idEvtPrev=%llu pvEvtDesc=%p cbEvtDesc=%zu pidEvt=%p\n", 97 pVM, pThisCC, hEvtSrc, enmTraceEvt, idEvtPrev, pvEvtDesc, cbEvtDesc, pidEvt)); 98 96 99 PDBGFTRACERSHARED pSharedCC = pThisCC->CTX_SUFF(pShared); 97 100 size_t cRingBufEvts = dbgfTracerGetRingBufSz(pThisCC) / DBGF_TRACER_EVT_SZ; … … 109 112 * get its act together. 110 113 */ 114 AssertMsgFailed(("Flush thread can't keep up with event amount!\n")); 111 115 } 112 116 -
trunk/src/VBox/VMM/VMMR3/DBGFR3Tracer.cpp
r84458 r84488 222 222 223 223 224 #if 0225 224 static const RTTRACELOGEVTITEMDESC g_DevGCPhysRwStartEvtItems[] = 226 225 { 227 226 {"GCPhys", "Physical guest address being accessed", RTTRACELOGTYPE_UINT64, 0}, 228 227 {"cbXfer", "Number of bytes being transfered", RTTRACELOGTYPE_UINT64, 0}, 229 {"idRw", "Event ID for tracking larger accesses", RTTRACELOGTYPE_UINT64, 0}, 230 {"ab"} 231 }; 232 #endif 228 }; 229 230 231 static const RTTRACELOGEVTDESC g_DevGCPhysReadEvtDesc = 232 { 233 "Dev.GCPhysRead", 234 "Device read data from guest physical memory", 235 RTTRACELOGEVTSEVERITY_DEBUG, 236 RT_ELEMENTS(g_DevGCPhysRwStartEvtItems), 237 &g_DevGCPhysRwStartEvtItems[0] 238 }; 239 240 241 static const RTTRACELOGEVTDESC g_DevGCPhysWriteEvtDesc = 242 { 243 "Dev.GCPhysWrite", 244 "Device wrote data to guest physical memory", 245 RTTRACELOGEVTSEVERITY_DEBUG, 246 RT_ELEMENTS(g_DevGCPhysRwStartEvtItems), 247 &g_DevGCPhysRwStartEvtItems[0] 248 }; 249 250 251 static const RTTRACELOGEVTITEMDESC g_DevGCPhysRwDataEvtItems[] = 252 { 253 {"abData", "The data being read/written", RTTRACELOGTYPE_RAWDATA, 0} 254 }; 255 256 static const RTTRACELOGEVTDESC g_DevGCPhysRwDataEvtDesc = 257 { 258 "Dev.GCPhysRwData", 259 "The data being read or written", 260 RTTRACELOGEVTSEVERITY_DEBUG, 261 RT_ELEMENTS(g_DevGCPhysRwDataEvtItems), 262 &g_DevGCPhysRwDataEvtItems[0] 263 }; 233 264 234 265 … … 239 270 240 271 /** 272 * Returns an unused guest memory read/write data aggregation structure. 273 * 274 * @returns Pointer to a new aggregation structure or NULL if out of memory. 275 * @param pThis The DBGF tracer instance. 276 */ 277 static PDBGFTRACERGCPHYSRWAGG dbgfTracerR3EvtGCPhysRwAggNew(PDBGFTRACERINSR3 pThis) 278 { 279 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aGstMemRwData); i++) 280 { 281 if (pThis->aGstMemRwData[i].idEvtStart == DBGF_TRACER_EVT_HDR_ID_INVALID) 282 return &pThis->aGstMemRwData[i]; 283 } 284 285 return NULL; 286 } 287 288 289 /** 290 * Find the guest memory read/write data aggregation structure for the given event ID. 291 * 292 * @returns Pointer to a new aggregation structure or NULL if not found. 293 * @param pThis The DBGF tracer instance. 294 * @param idEvtPrev The event ID to look for. 295 */ 296 static PDBGFTRACERGCPHYSRWAGG dbgfTracerR3EvtGCPhysRwAggFind(PDBGFTRACERINSR3 pThis, uint64_t idEvtPrev) 297 { 298 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aGstMemRwData); i++) 299 { 300 if ( pThis->aGstMemRwData[i].idEvtStart != DBGF_TRACER_EVT_HDR_ID_INVALID 301 && pThis->aGstMemRwData[i].idEvtPrev == idEvtPrev) 302 return &pThis->aGstMemRwData[i]; 303 } 304 305 return NULL; 306 } 307 308 309 /** 310 * Starts a new guest memory read/write event. 311 * 312 * @returns VBox status code. 313 * @param pThis The DBGF tracer instance. 314 * @param pEvtHdr The event header. 315 * @param pEvtGCPhysRw The guest memory read/write event descriptor. 316 * @param pEvtDesc The event descriptor written to the trace log. 317 */ 318 static int dbgfTracerR3EvtGCPhysRwStart(PDBGFTRACERINSR3 pThis, PCDBGFTRACEREVTHDR pEvtHdr, 319 PCDBGFTRACEREVTGCPHYS pEvtGCPhysRw, PCRTTRACELOGEVTDESC pEvtDesc) 320 { 321 /* Write out the event header first in any case. */ 322 int rc = RTTraceLogWrEvtAddL(pThis->hTraceLog, pEvtDesc, RTTRACELOG_WR_ADD_EVT_F_GRP_START, 323 pEvtHdr->idEvt, pEvtHdr->hEvtSrc, pEvtGCPhysRw->GCPhys, pEvtGCPhysRw->cbXfer); 324 if (RT_SUCCESS(rc)) 325 { 326 /* 327 * If the amount of data is small enough to fit into the single event descriptor we can skip allocating 328 * an aggregation tracking structure and write the event containing the complete data out immediately. 329 */ 330 if (pEvtGCPhysRw->cbXfer <= sizeof(pEvtGCPhysRw->abData)) 331 { 332 size_t cbEvtData = pEvtGCPhysRw->cbXfer; 333 334 rc = RTTraceLogWrEvtAdd(pThis->hTraceLog, &g_DevGCPhysRwDataEvtDesc, RTTRACELOG_WR_ADD_EVT_F_GRP_FINISH, 335 pEvtHdr->idEvt, pEvtHdr->hEvtSrc, &pEvtGCPhysRw->abData[0], &cbEvtData); 336 } 337 else 338 { 339 /* Slow path, find an empty aggregation structure. */ 340 PDBGFTRACERGCPHYSRWAGG pDataAgg = dbgfTracerR3EvtGCPhysRwAggNew(pThis); 341 if (RT_LIKELY(pDataAgg)) 342 { 343 /* Initialize it. */ 344 pDataAgg->idEvtStart = pEvtHdr->idEvt; 345 pDataAgg->idEvtPrev = pEvtHdr->idEvt; 346 pDataAgg->cbXfer = pEvtGCPhysRw->cbXfer; 347 pDataAgg->cbLeft = pDataAgg->cbXfer; 348 pDataAgg->offBuf = 0; 349 350 /* Need to reallocate the buffer to hold the complete data? */ 351 if (RT_UNLIKELY(pDataAgg->cbBufMax < pDataAgg->cbXfer)) 352 { 353 uint8_t *pbBufNew = (uint8_t *)RTMemRealloc(pDataAgg->pbBuf, pDataAgg->cbXfer); 354 if (RT_LIKELY(pbBufNew)) 355 { 356 pDataAgg->pbBuf = pbBufNew; 357 pDataAgg->cbBufMax = pDataAgg->cbXfer; 358 } 359 else 360 rc = VERR_NO_MEMORY; 361 } 362 363 if (RT_SUCCESS(rc)) 364 { 365 memcpy(pDataAgg->pbBuf, &pEvtGCPhysRw->abData[0], sizeof(pEvtGCPhysRw->abData)); 366 pDataAgg->offBuf += sizeof(pEvtGCPhysRw->abData); 367 pDataAgg->cbLeft -= sizeof(pEvtGCPhysRw->abData); 368 } 369 } 370 else 371 rc = VERR_NO_MEMORY; 372 373 if (RT_FAILURE(rc)) 374 { 375 LogRelMax(10, ("DBGF: Creating new data aggregation structure for guest memory read/write failed with %Rrc, trace log will not contain data for this event!\n", rc)); 376 377 /* Write out the finish event without any data. */ 378 size_t cbEvtData = 0; 379 rc = RTTraceLogWrEvtAdd(pThis->hTraceLog, &g_DevGCPhysRwDataEvtDesc, RTTRACELOG_WR_ADD_EVT_F_GRP_FINISH, 380 pEvtHdr->idEvt, pEvtHdr->hEvtSrc, NULL, &cbEvtData); 381 if (pDataAgg) /* Reset the aggregation event. */ 382 pDataAgg->idEvtStart = DBGF_TRACER_EVT_HDR_ID_INVALID; 383 } 384 } 385 } 386 387 return rc; 388 } 389 390 391 /** 392 * Continues a previously started guest memory read/write event. 393 * 394 * @returns VBox status code. 395 * @param pThis The DBGF tracer instance. 396 * @param pEvtHdr The event header. 397 * @param pvData The data to log. 398 */ 399 static int dbgfTracerR3EvtGCPhysRwContinue(PDBGFTRACERINSR3 pThis, PCDBGFTRACEREVTHDR pEvtHdr, void *pvData) 400 { 401 int rc = VINF_SUCCESS; 402 PDBGFTRACERGCPHYSRWAGG pDataAgg = dbgfTracerR3EvtGCPhysRwAggFind(pThis, pEvtHdr->idEvtPrev); 403 404 if (RT_LIKELY(pDataAgg)) 405 { 406 size_t cbThisXfer = RT_MIN(pDataAgg->cbLeft, DBGF_TRACER_EVT_PAYLOAD_SZ); 407 408 memcpy(pDataAgg->pbBuf + pDataAgg->offBuf, pvData, cbThisXfer); 409 pDataAgg->offBuf += cbThisXfer; 410 pDataAgg->cbLeft -= cbThisXfer; 411 412 if (!pDataAgg->cbLeft) 413 { 414 /* All data aggregated, write it out and reset the structure. */ 415 rc = RTTraceLogWrEvtAdd(pThis->hTraceLog, &g_DevGCPhysRwDataEvtDesc, RTTRACELOG_WR_ADD_EVT_F_GRP_FINISH, 416 pDataAgg->idEvtStart, pEvtHdr->hEvtSrc, pDataAgg->pbBuf, &pDataAgg->cbXfer); 417 pDataAgg->offBuf = 0; 418 pDataAgg->idEvtStart = DBGF_TRACER_EVT_HDR_ID_INVALID; 419 } 420 else 421 pDataAgg->idEvtPrev = pEvtHdr->idEvt; /* So the next event containing more data can find the aggregation structure. */ 422 } 423 else /* This can only happen if creating a new structure failed before. */ 424 rc = VERR_DBGF_TRACER_IPE_1; 425 426 return rc; 427 } 428 429 430 /** 241 431 * Processes the given event. 242 432 * … … 248 438 { 249 439 int rc = VINF_SUCCESS; 440 441 LogFlowFunc(("pThis=%p pEvtHdr=%p{idEvt=%llu,enmEvt=%u}\n", 442 pThis, pEvtHdr, pEvtHdr->idEvt, pEvtHdr->enmEvt)); 250 443 251 444 switch (pEvtHdr->enmEvt) … … 343 536 case DBGFTRACEREVT_GCPHYS_READ: 344 537 case DBGFTRACEREVT_GCPHYS_WRITE: 538 { 539 PCRTTRACELOGEVTDESC pEvtDesc = pEvtHdr->enmEvt == DBGFTRACEREVT_GCPHYS_WRITE 540 ? &g_DevGCPhysWriteEvtDesc 541 : &g_DevGCPhysReadEvtDesc; 542 543 /* If the previous event ID is invalid this starts a new read/write we have to aggregate all the data for. */ 544 if (pEvtHdr->idEvtPrev == DBGF_TRACER_EVT_HDR_ID_INVALID) 545 { 546 PCDBGFTRACEREVTGCPHYS pEvtGCPhysRw = (PCDBGFTRACEREVTGCPHYS)(pEvtHdr + 1); 547 rc = dbgfTracerR3EvtGCPhysRwStart(pThis, pEvtHdr, pEvtGCPhysRw, pEvtDesc); 548 } 549 else 550 { 551 /* Continuation of a started read or write, look up the right tracking structure and process the new data. */ 552 void *pvData = pEvtHdr + 1; 553 rc = dbgfTracerR3EvtGCPhysRwContinue(pThis, pEvtHdr, pvData); 554 } 555 break; 556 } 345 557 default: 346 558 AssertLogRelMsgFailed(("Invalid or unsupported event: %u!\n", pEvtHdr->enmEvt)); … … 459 671 pThis->fShutdown = false; 460 672 673 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aGstMemRwData); i++) 674 pThis->aGstMemRwData[i].idEvtStart = DBGF_TRACER_EVT_HDR_ID_INVALID; 675 461 676 /* Try to create a file based trace log. */ 462 677 int rc = RTTraceLogWrCreateFile(&pThis->hTraceLog, RTBldCfgVersion(), pszTraceFilePath); … … 470 685 * to invalid values. 471 686 */ 472 uint64_t cEvtEntries = pShared->cbRingBuf %DBGF_TRACER_EVT_SZ;687 uint64_t cEvtEntries = pShared->cbRingBuf / DBGF_TRACER_EVT_SZ; 473 688 PDBGFTRACEREVTHDR pEvtHdr = (PDBGFTRACEREVTHDR)pThis->pbRingBufR3; 474 689 for (uint32_t i = 0; i < cEvtEntries; i++) … … 686 901 * Deregisters the given event source handle. 687 902 * 688 * @returns VBox sta uts code.903 * @returns VBox status code. 689 904 * @param pVM The cross context VM structure. 690 905 * @param hEvtSrc The event source handle to deregister. -
trunk/src/VBox/VMM/include/DBGFInternal.h
r84458 r84488 378 378 379 379 /** 380 * Guest memory read/write data aggregation. 381 */ 382 typedef struct DBGFTRACERGCPHYSRWAGG 383 { 384 /** The event ID which started the aggregation (used for the group ID when writing out the event). */ 385 uint64_t idEvtStart; 386 /** The previous event ID used to link all the chunks together. */ 387 uint64_t idEvtPrev; 388 /** Number of bytes being transfered. */ 389 size_t cbXfer; 390 /** Amount of data left to aggregate before it can be written. */ 391 size_t cbLeft; 392 /** Amount of bytes allocated. */ 393 size_t cbBufMax; 394 /** Offset into the buffer to write next. */ 395 size_t offBuf; 396 /** Pointer to the allocated buffer. */ 397 uint8_t *pbBuf; 398 } DBGFTRACERGCPHYSRWAGG; 399 /** Pointer to a guest memory read/write data aggregation structure. */ 400 typedef DBGFTRACERGCPHYSRWAGG *PDBGFTRACERGCPHYSRWAGG; 401 402 403 /** 380 404 * Tracer instance data, ring-3 381 405 */ … … 407 431 /** The trace log writer handle. */ 408 432 RTTRACELOGWR hTraceLog; 433 /** Guest memory data aggregation structures to track 434 * currently pending guest memory reads/writes. */ 435 DBGFTRACERGCPHYSRWAGG aGstMemRwData[10]; 409 436 } DBGFTRACERINSR3; 410 437 /** Pointer to a tarcer instance - Ring-3 Ptr. */
Note:
See TracChangeset
for help on using the changeset viewer.