VirtualBox

Changeset 40704 in vbox


Ignore:
Timestamp:
Mar 28, 2012 7:29:49 PM (13 years ago)
Author:
vboxsync
Message:

SUPDrv-dtrace.cpp: bugfixes and working around solaris bugs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp

    r40675 r40704  
    8383    /** Set when the module is unloaded or the driver deregisters its probes. */
    8484    bool                fZombie;
     85    /** The provider name (for logging purposes). */
     86    char                szName[1];
    8587} SUPDRVDTPROVIDER;
    8688/** Pointer to the data for a provider. */
     
    9597#endif
    9698
     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
    97108
    98109/*******************************************************************************
     
    104115static void     supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    105116                                            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
     118static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
     119                                           int iArg, int cFrames);
     120#endif
    108121static void     supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
    109122
     
    125138    /* .dtps_resume          = */ NULL,
    126139    /* .dtps_getargdesc      = */ supdrvDTracePOps_GetArgDesc,
     140#ifdef RT_OS_SOLARIS
     141    /* .dtps_getargval       = */ supdrvDTracePOps_GetArgVal,
     142#else
    127143    /* .dtps_getargval       = */ NULL/*supdrvDTracePOps_GetArgVal*/,
     144#endif
    128145    /* .dtps_usermode        = */ NULL,
    129146    /* .dtps_destroy         = */ supdrvDTracePOps_Destroy
     
    382399static void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv)
    383400{
     401    LOG_DTRACE(("Freeing DTrace provider '%s' / %p\n", pProv->szName, pProv->idDtProv));
    384402    pProv->fZombie = true;
    385403    pProv->pDesc   = NULL;
    386404    pProv->pHdr    = NULL;
    387405    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 */
     419static 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 */
     442static 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);
    388457}
    389458
     
    400469 * @param   pszModName          The module name.
    401470 */
    402 static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage, PSUPDRVSESSION pSession,
    403                              const char *pszModName)
     471static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
     472                             PSUPDRVSESSION pSession, const char *pszModName)
    404473{
    405474    int                 rc;
     
    424493
    425494    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;
    444514
    445515    /*
     
    449519    while (i-- > 0)
    450520    {
    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]));
    453525        if (pProv)
    454526        {
     
    461533            pProv->cProvidedProbes  = 0;
    462534            pProv->fZombie          = false;
     535            memcpy(pProv->szName, pszName, cchName + 1);
    463536            supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf);
    464537            supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod,      &pDesc->AttrModules);
     
    467540            supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_args,     &pDesc->AttrArguments);
    468541
    469             rc = dtrace_register(supdrvVtgGetString(pVtgHdr, pDesc->offName),
     542            rc = dtrace_register(pProv->szName,
    470543                                 &pProv->DtAttrs,
    471544                                 DTRACE_PRIV_KERNEL,
     
    481554                    RTListAppend(&pDevExt->DtProviderList, &pProv->ListEntry);
    482555                    RTSemFastMutexRelease(pDevExt->mtxDTrace);
     556                    LOG_DTRACE(("Registered DTrace provider '%s' in '%s' -> %p\n", pProv->szName, pszModName, pProv->idDtProv));
    483557                }
    484558                else
     
    502576                {
    503577                    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);
    510579                }
    511580            }
     
    516585
    517586    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);
    568587}
    569588
     
    754773    PSUPDRVDTPROVIDER pProv, pProvNext;
    755774    uint32_t i;
     775    LOG_DTRACE(("supdrvVtgTerm\n"));
    756776
    757777    /*
     
    774794
    775795        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);
    779801            if (!rc)
    780802            {
     
    783805            }
    784806            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));
    786810        }
    787811
     
    797821    RTSemFastMutexDestroy(pDevExt->mtxDTrace);
    798822    pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
     823    LOG_DTRACE(("supdrvVtgTerm: Done\n"));
    799824}
    800825
     
    9871012
    9881013
    989 #if 0
     1014#ifdef RT_OS_SOLARIS
     1015
     1016# ifdef __cplusplus
     1017extern "C"
     1018#endif
     1019uint64_t dtrace_getarg(int iArg, int cFrames);
     1020
    9901021/**
    9911022 * @callback_method_impl{dtrace_pops_t,dtps_getargval}
     
    9941025                                           int iArg, int cFrames)
    9951026{
    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 */
    9991045
    10001046
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