Changeset 40704 in vbox
- Timestamp:
- Mar 28, 2012 7:29:49 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp
r40675 r40704 83 83 /** Set when the module is unloaded or the driver deregisters its probes. */ 84 84 bool fZombie; 85 /** The provider name (for logging purposes). */ 86 char szName[1]; 85 87 } SUPDRVDTPROVIDER; 86 88 /** Pointer to the data for a provider. */ … … 95 97 #endif 96 98 99 100 /******************************************************************************* 101 * Defined Constants And Macros * 102 *******************************************************************************/ 103 #if 0 104 # define LOG_DTRACE(a_Args) SUPR0Printf a_Args 105 #else 106 # define LOG_DTRACE(a_Args) do { } while (0) 107 #endif 97 108 98 109 /******************************************************************************* … … 104 115 static void supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe, 105 116 dtrace_argdesc_t *pArgDesc); 106 /*static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe, 107 int iArg, int cFrames);*/ 117 #ifdef RT_OS_SOLARIS 118 static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe, 119 int iArg, int cFrames); 120 #endif 108 121 static void supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe); 109 122 … … 125 138 /* .dtps_resume = */ NULL, 126 139 /* .dtps_getargdesc = */ supdrvDTracePOps_GetArgDesc, 140 #ifdef RT_OS_SOLARIS 141 /* .dtps_getargval = */ supdrvDTracePOps_GetArgVal, 142 #else 127 143 /* .dtps_getargval = */ NULL/*supdrvDTracePOps_GetArgVal*/, 144 #endif 128 145 /* .dtps_usermode = */ NULL, 129 146 /* .dtps_destroy = */ supdrvDTracePOps_Destroy … … 382 399 static void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv) 383 400 { 401 LOG_DTRACE(("Freeing DTrace provider '%s' / %p\n", pProv->szName, pProv->idDtProv)); 384 402 pProv->fZombie = true; 385 403 pProv->pDesc = NULL; 386 404 pProv->pHdr = NULL; 387 405 RTMemFree(pProv); 406 } 407 408 409 /** 410 * Deregisters a provider. 411 * 412 * If the provider is still busy, it will be put in the zombie list. 413 * 414 * @param pDevExt The device extension. 415 * @param pProv The provider. 416 * 417 * @remarks The caller owns mtxDTrace. 418 */ 419 static void supdrvVtgDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVDTPROVIDER pProv) 420 { 421 int rc; 422 423 dtrace_invalidate(pProv->idDtProv); 424 rc = dtrace_unregister(pProv->idDtProv); 425 if (!rc) 426 { 427 supdrvVtgFreeProvider(pProv); 428 return; 429 } 430 431 pProv->fZombie = true; 432 RTListAppend(&pDevExt->DtProviderZombieList, &pProv->ListEntry); 433 LOG_DTRACE(("Invalidate DTrace provider '%s' / %p and put it on the zombie list\n", pProv->szName, pProv->idDtProv)); 434 } 435 436 437 /** 438 * Processes the zombie list. 439 * 440 * @param pDevExt The device extension. 441 */ 442 static void supdrvVtgProcessZombies(PSUPDRVDEVEXT pDevExt) 443 { 444 PSUPDRVDTPROVIDER pProv, pProvNext; 445 446 RTSemFastMutexRequest(pDevExt->mtxDTrace); 447 RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry) 448 { 449 int rc = dtrace_unregister(pProv->idDtProv); 450 if (!rc) 451 { 452 RTListNodeRemove(&pProv->ListEntry); 453 supdrvVtgFreeProvider(pProv); 454 } 455 } 456 RTSemFastMutexRelease(pDevExt->mtxDTrace); 388 457 } 389 458 … … 400 469 * @param pszModName The module name. 401 470 */ 402 static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage, PSUPDRVSESSION pSession,403 const char *pszModName)471 static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage, 472 PSUPDRVSESSION pSession, const char *pszModName) 404 473 { 405 474 int rc; … … 424 493 425 494 rc = RTSemFastMutexRequest(pDevExt->mtxDTrace); 426 if (RT_SUCCESS(rc)) 427 { 428 RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry) 429 { 430 if (pProv->pHdr == pVtgHdr) 431 { 432 RTSemFastMutexRelease(pDevExt->mtxDTrace); 433 return VERR_SUPDRV_VTG_ALREADY_REGISTERED; 434 } 435 if ( pProv->pSession == pSession 436 && pProv->pImage == pImage) 437 { 438 RTSemFastMutexRelease(pDevExt->mtxDTrace); 439 return VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION; 440 } 441 } 442 RTSemFastMutexRelease(pDevExt->mtxDTrace); 443 } 495 if (RT_FAILURE(rc)) 496 return rc; 497 RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry) 498 { 499 if (pProv->pHdr == pVtgHdr) 500 { 501 rc = VERR_SUPDRV_VTG_ALREADY_REGISTERED; 502 break; 503 } 504 if ( pProv->pSession == pSession 505 && pProv->pImage == pImage) 506 { 507 rc = VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION; 508 break; 509 } 510 } 511 RTSemFastMutexRelease(pDevExt->mtxDTrace); 512 if (RT_FAILURE(rc)) 513 return rc; 444 514 445 515 /* … … 449 519 while (i-- > 0) 450 520 { 451 PVTGDESCPROVIDER pDesc = &pVtgHdr->paProviders[i]; 452 pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(sizeof(*pProv)); 521 PVTGDESCPROVIDER pDesc = &pVtgHdr->paProviders[i]; 522 const char *pszName = supdrvVtgGetString(pVtgHdr, pDesc->offName); 523 size_t const cchName = strlen(pszName); 524 pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVDTPROVIDER, szName[cchName + 1])); 453 525 if (pProv) 454 526 { … … 461 533 pProv->cProvidedProbes = 0; 462 534 pProv->fZombie = false; 535 memcpy(pProv->szName, pszName, cchName + 1); 463 536 supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf); 464 537 supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod, &pDesc->AttrModules); … … 467 540 supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_args, &pDesc->AttrArguments); 468 541 469 rc = dtrace_register( supdrvVtgGetString(pVtgHdr, pDesc->offName),542 rc = dtrace_register(pProv->szName, 470 543 &pProv->DtAttrs, 471 544 DTRACE_PRIV_KERNEL, … … 481 554 RTListAppend(&pDevExt->DtProviderList, &pProv->ListEntry); 482 555 RTSemFastMutexRelease(pDevExt->mtxDTrace); 556 LOG_DTRACE(("Registered DTrace provider '%s' in '%s' -> %p\n", pProv->szName, pszModName, pProv->idDtProv)); 483 557 } 484 558 else … … 502 576 { 503 577 RTListNodeRemove(&pProv->ListEntry); 504 RTSemFastMutexRelease(pDevExt->mtxDTrace); 505 506 dtrace_unregister(pProv->idDtProv); 507 RTMemFree(pProv); 508 509 RTSemFastMutexRequest(pDevExt->mtxDTrace); 578 supdrvVtgDeregister(pDevExt, pProv); 510 579 } 511 580 } … … 516 585 517 586 return VINF_SUCCESS; 518 }519 520 521 /**522 * Deregisters a provider.523 *524 * If the provider is still busy, it will be put in the zombie list.525 *526 * @param pDevExt The device extension.527 * @param pProv The provider.528 *529 * @remarks The caller owns mtxDTrace.530 */531 static void supdrvVtgDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVDTPROVIDER pProv)532 {533 int rc;534 535 dtrace_invalidate(pProv->idDtProv);536 rc = dtrace_unregister(pProv->idDtProv);537 if (!rc)538 {539 supdrvVtgFreeProvider(pProv);540 return;541 }542 543 pProv->fZombie = true;544 RTListAppend(&pDevExt->DtProviderZombieList, &pProv->ListEntry);545 }546 547 548 /**549 * Processes the zombie list.550 *551 * @param pDevExt The device extension.552 */553 static void supdrvVtgProcessZombies(PSUPDRVDEVEXT pDevExt)554 {555 PSUPDRVDTPROVIDER pProv, pProvNext;556 557 RTSemFastMutexRequest(pDevExt->mtxDTrace);558 RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)559 {560 int rc = dtrace_unregister(pProv->idDtProv);561 if (!rc)562 {563 RTListNodeRemove(&pProv->ListEntry);564 supdrvVtgFreeProvider(pProv);565 }566 }567 RTSemFastMutexRelease(pDevExt->mtxDTrace);568 587 } 569 588 … … 754 773 PSUPDRVDTPROVIDER pProv, pProvNext; 755 774 uint32_t i; 775 LOG_DTRACE(("supdrvVtgTerm\n")); 756 776 757 777 /* … … 774 794 775 795 RTSemFastMutexRequest(pDevExt->mtxDTrace); 776 RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry) 777 { 778 int rc = dtrace_unregister(pProv->idDtProv); 796 RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry) 797 { 798 int rc; 799 LOG_DTRACE(("supdrvVtgTerm: Attemting to unregister '%s' / %p...\n", pProv->szName, pProv->idDtProv)); 800 rc = dtrace_unregister(pProv->idDtProv); 779 801 if (!rc) 780 802 { … … 783 805 } 784 806 else if (!(i & 0xf)) 785 SUPR0Printf("supdrvVtgTerm: Waiting on busy provider %p\n", pProv->idDtProv); 807 SUPR0Printf("supdrvVtgTerm: Waiting on busy provider '%s' / %p (rc=%d)\n", pProv->szName, pProv->idDtProv, rc); 808 else 809 LOG_DTRACE(("supdrvVtgTerm: Failed to unregister provider '%s' / %p - rc=%d\n", pProv->szName, pProv->idDtProv, rc)); 786 810 } 787 811 … … 797 821 RTSemFastMutexDestroy(pDevExt->mtxDTrace); 798 822 pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX; 823 LOG_DTRACE(("supdrvVtgTerm: Done\n")); 799 824 } 800 825 … … 987 1012 988 1013 989 #if 0 1014 #ifdef RT_OS_SOLARIS 1015 1016 # ifdef __cplusplus 1017 extern "C" 1018 #endif 1019 uint64_t dtrace_getarg(int iArg, int cFrames); 1020 990 1021 /** 991 1022 * @callback_method_impl{dtrace_pops_t,dtps_getargval} … … 994 1025 int iArg, int cFrames) 995 1026 { 996 return 0xbeef; 997 } 998 #endif 1027 /* dtrace_getarg on AMD64 has a different opinion about how to use the 1028 cFrames argument than dtrace_caller() and/or dtrace_getpcstack(), at 1029 least when the probe is fired by dtrace_probe() the way we do. 1030 1031 Setting aframes to 1 when calling dtrace_probe_create gives me the right 1032 arguments, but the wrong 'caller'. Since I cannot do anything about 1033 'caller', the only solution is this hack. 1034 1035 Not sure why the Solaris guys hasn't seen this issue before, but maybe 1036 there isn't anyone using the default argument getter path for ring-0 1037 dtrace_probe() calls, SDT surely isn't. 1038 1039 WARNING! This code is subject to dtrace_getarg interface unstability! */ 1040 /** @todo File a solaris bug on dtrace_probe() + dtrace_getarg(). */ 1041 return dtrace_getarg(iArg, cFrames + 1); 1042 } 1043 1044 #endif /* RT_OS_SOLARIS */ 999 1045 1000 1046
Note:
See TracChangeset
for help on using the changeset viewer.