Changeset 89763 in vbox
- Timestamp:
- Jun 17, 2021 9:40:24 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/DBGFR3SampleReport.cpp
r89722 r89763 135 135 /** The report created after sampling was stopped. */ 136 136 char *pszReport; 137 /** Number of EMTs having a guest sample operation queued. */ 138 volatile uint32_t cEmtsActive; 137 139 /** Array of per VCPU samples collected. */ 138 140 DBGFSAMPLEREPORTVCPU aCpus[1]; … … 377 379 * each VCPU. 378 380 * 379 * @returns Strict VBox status code. 380 * @param pVM The VM instance data. 381 * @param pVCpu The virtual CPU we execute on. 382 * @param pvUser Opaque user data. 383 */ 384 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3SampleReportSample(PVM pVM, PVMCPU pVCpu, void *pvUser) 385 { 386 RT_NOREF(pVM); 387 PDBGFSAMPLEREPORTINT pThis = (PDBGFSAMPLEREPORTINT)pvUser; 381 * @returns nothing. 382 * @param pThis Pointer to the sample report instance. 383 */ 384 static DECLCALLBACK(void) dbgfR3SampleReportSample(PDBGFSAMPLEREPORTINT pThis) 385 { 386 PVM pVM = pThis->pUVM->pVM; 387 PVMCPU pVCpu = VMMGetCpu(pVM); 388 388 389 389 PCDBGFSTACKFRAME pFrameFirst; … … 437 437 LogRelMax(10, ("Sampling guest stack on VCPU %u failed with rc=%Rrc\n", pVCpu->idCpu, rc)); 438 438 439 if (pVCpu->idCpu == 0) 440 { 441 /* Destroy the timer if requested. */ 442 if (ASMAtomicReadU32((volatile uint32_t *)&pThis->enmState) == DBGFSAMPLEREPORTSTATE_STOPPING) 443 { 444 #ifndef RT_OS_WINDOWS 445 rc = RTTimerStop(pThis->hTimer); AssertRC(rc); RT_NOREF(rc); 446 #endif 447 rc = RTTimerDestroy(pThis->hTimer); AssertRC(rc); RT_NOREF(rc); 448 pThis->hTimer = NULL; 449 450 DBGFSAMPLEREPORTINFOHLP Hlp; 451 PCDBGFINFOHLP pHlp = &Hlp.Core; 452 453 dbgfR3SampleReportInfoHlpInit(&Hlp); 454 455 /* Some early dump code. */ 456 for (uint32_t i = 0; i < pThis->pUVM->cCpus; i++) 457 { 458 PCDBGFSAMPLEREPORTVCPU pSampleVCpu = &pThis->aCpus[i]; 459 460 pHlp->pfnPrintf(pHlp, "Sample report for vCPU %u:\n", i); 461 dbgfR3SampleReportDumpFrame(pHlp, pThis->pUVM, &pSampleVCpu->FrameRoot, 0); 462 } 463 464 /* Shameless copy from VMMGuruMeditation.cpp */ 465 static struct 466 { 467 const char *pszInfo; 468 const char *pszArgs; 469 } const aInfo[] = 470 { 471 { "mappings", NULL }, 472 { "mode", "all" }, 473 { "handlers", "phys virt hyper stats" }, 474 { "timers", NULL }, 475 { "activetimers", NULL }, 476 }; 477 for (unsigned i = 0; i < RT_ELEMENTS(aInfo); i++) 478 { 479 pHlp->pfnPrintf(pHlp, 480 "!!\n" 481 "!! {%s, %s}\n" 482 "!!\n", 483 aInfo[i].pszInfo, aInfo[i].pszArgs); 484 DBGFR3Info(pVM->pUVM, aInfo[i].pszInfo, aInfo[i].pszArgs, pHlp); 485 } 486 487 /* All other info items */ 488 DBGFR3InfoMulti(pVM, 489 "*", 490 "mappings|hma|cpum|cpumguest|cpumguesthwvirt|cpumguestinstr|cpumhyper|cpumhost|cpumvmxfeat|mode|cpuid" 491 "|pgmpd|pgmcr3|timers|activetimers|handlers|help|cfgm", 439 /* Last EMT finishes the report when sampling was stopped. */ 440 uint32_t cEmtsActive = ASMAtomicDecU32(&pThis->cEmtsActive); 441 if ( ASMAtomicReadU32((volatile uint32_t *)&pThis->enmState) == DBGFSAMPLEREPORTSTATE_STOPPING 442 && !cEmtsActive) 443 { 444 rc = RTTimerDestroy(pThis->hTimer); AssertRC(rc); RT_NOREF(rc); 445 pThis->hTimer = NULL; 446 447 DBGFSAMPLEREPORTINFOHLP Hlp; 448 PCDBGFINFOHLP pHlp = &Hlp.Core; 449 450 dbgfR3SampleReportInfoHlpInit(&Hlp); 451 452 /* Some early dump code. */ 453 for (uint32_t i = 0; i < pThis->pUVM->cCpus; i++) 454 { 455 PCDBGFSAMPLEREPORTVCPU pSampleVCpu = &pThis->aCpus[i]; 456 457 pHlp->pfnPrintf(pHlp, "Sample report for vCPU %u:\n", i); 458 dbgfR3SampleReportDumpFrame(pHlp, pThis->pUVM, &pSampleVCpu->FrameRoot, 0); 459 } 460 461 /* Shameless copy from VMMGuruMeditation.cpp */ 462 static struct 463 { 464 const char *pszInfo; 465 const char *pszArgs; 466 } const aInfo[] = 467 { 468 { "mappings", NULL }, 469 { "mode", "all" }, 470 { "handlers", "phys virt hyper stats" }, 471 { "timers", NULL }, 472 { "activetimers", NULL }, 473 }; 474 for (unsigned i = 0; i < RT_ELEMENTS(aInfo); i++) 475 { 476 pHlp->pfnPrintf(pHlp, 492 477 "!!\n" 493 "!! {%s }\n"478 "!! {%s, %s}\n" 494 479 "!!\n", 495 pHlp); 496 497 498 /* done */ 499 pHlp->pfnPrintf(pHlp, 500 "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); 501 502 if (pThis->pszReport) 503 RTMemFree(pThis->pszReport); 504 pThis->pszReport = Hlp.pachBuf; 505 Hlp.pachBuf = NULL; 506 dbgfR3SampleReportInfoHlpDelete(&Hlp); 507 508 ASMAtomicXchgU32((volatile uint32_t *)&pThis->enmState, DBGFSAMPLEREPORTSTATE_READY); 509 510 if (pThis->pfnProgress) 511 { 512 pThis->pfnProgress(pThis->pvProgressUser, 100); 513 pThis->pfnProgress = NULL; 514 pThis->pvProgressUser = NULL; 515 } 516 517 DBGFR3SampleReportRelease(pThis); 518 } 519 } 520 521 return VINF_SUCCESS; 480 aInfo[i].pszInfo, aInfo[i].pszArgs); 481 DBGFR3Info(pVM->pUVM, aInfo[i].pszInfo, aInfo[i].pszArgs, pHlp); 482 } 483 484 /* All other info items */ 485 DBGFR3InfoMulti(pVM, 486 "*", 487 "mappings|hma|cpum|cpumguest|cpumguesthwvirt|cpumguestinstr|cpumhyper|cpumhost|cpumvmxfeat|mode|cpuid" 488 "|pgmpd|pgmcr3|timers|activetimers|handlers|help|cfgm", 489 "!!\n" 490 "!! {%s}\n" 491 "!!\n", 492 pHlp); 493 494 495 /* done */ 496 pHlp->pfnPrintf(pHlp, 497 "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); 498 499 if (pThis->pszReport) 500 RTMemFree(pThis->pszReport); 501 pThis->pszReport = Hlp.pachBuf; 502 Hlp.pachBuf = NULL; 503 dbgfR3SampleReportInfoHlpDelete(&Hlp); 504 505 ASMAtomicXchgU32((volatile uint32_t *)&pThis->enmState, DBGFSAMPLEREPORTSTATE_READY); 506 507 if (pThis->pfnProgress) 508 { 509 pThis->pfnProgress(pThis->pvProgressUser, 100); 510 pThis->pfnProgress = NULL; 511 pThis->pvProgressUser = NULL; 512 } 513 514 DBGFR3SampleReportRelease(pThis); 515 } 522 516 } 523 517 … … 528 522 static DECLCALLBACK(void) dbgfR3SampleReportTakeSample(PRTTIMER pTimer, void *pvUser, uint64_t iTick) 529 523 { 530 RT_NOREF(pTimer);531 524 PDBGFSAMPLEREPORTINT pThis = (PDBGFSAMPLEREPORTINT)pvUser; 532 525 … … 549 542 ASMAtomicCmpXchgU32((volatile uint32_t *)&pThis->enmState, DBGFSAMPLEREPORTSTATE_STOPPING, 550 543 DBGFSAMPLEREPORTSTATE_RUNNING); 551 } 552 } 553 554 int rc = VMMR3EmtRendezvous(pThis->pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING, 555 dbgfR3SampleReportSample, pThis); 556 AssertRC(rc); RT_NOREF(rc); 544 545 rc = RTTimerStop(pTimer); AssertRC(rc); RT_NOREF(rc); 546 } 547 } 548 549 ASMAtomicAddU32(&pThis->cEmtsActive, pThis->pUVM->cCpus); 550 551 for (uint32_t i = 0; i < pThis->pUVM->cCpus; i++) 552 { 553 int rc = VMR3ReqCallVoidNoWait(pThis->pUVM->pVM, i, (PFNRT)dbgfR3SampleReportSample, 1, pThis); 554 AssertRC(rc); 555 if (RT_FAILURE(rc)) 556 ASMAtomicDecU32(&pThis->cEmtsActive); 557 } 557 558 } 558 559 … … 583 584 pThis->cSampleIntervalUs = cSampleIntervalUs; 584 585 pThis->enmState = DBGFSAMPLEREPORTSTATE_READY; 586 pThis->cEmtsActive = 0; 585 587 586 588 for (uint32_t i = 0; i < pUVM->cCpus; i++) … … 684 686 DBGFR3SampleReportRetain(pThis); 685 687 686 #ifndef RT_OS_WINDOWS687 688 rc = RTTimerCreateEx(&pThis->hTimer, pThis->cSampleIntervalUs * 1000, 688 689 RTTIMER_FLAGS_CPU_ANY | RTTIMER_FLAGS_HIGH_RES, … … 690 691 if (RT_SUCCESS(rc)) 691 692 rc = RTTimerStart(pThis->hTimer, 0 /*u64First*/); 692 #else693 rc = RTTimerCreate(&pThis->hTimer, pThis->cSampleIntervalUs / 1000,694 dbgfR3SampleReportTakeSample, pThis);695 #endif696 697 693 if (RT_FAILURE(rc)) 698 694 {
Note:
See TracChangeset
for help on using the changeset viewer.