VirtualBox

Ignore:
Timestamp:
Apr 3, 2012 2:47:33 PM (13 years ago)
Author:
vboxsync
Message:

SUP: Working on a generic tracer interface.

File:
1 copied

Legend:

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

    r40753 r40756  
    11/* $Id$ */
    22/** @file
    3  * VBoxDrv - The VirtualBox Support Driver - DTrace Provider.
     3 * VBoxDrv - The VirtualBox Support Driver - Generic Tracer Interface.
    44 */
    55
     
    3030*******************************************************************************/
    3131#define LOG_GROUP LOG_GROUP_SUP_DRV
     32#define SUPDRV_AGNOSTIC
    3233#include "SUPDrvInternal.h"
    3334
     
    4344#include <iprt/thread.h>
    4445
    45 #ifdef RT_OS_DARWIN /** @todo figure this! */
    46 # include "/Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/dtrace.h"
    47 #else
    48 # include <sys/dtrace.h>
    49 #endif
    50 
    5146
    5247/*******************************************************************************
     
    5449*******************************************************************************/
    5550/**
    56  * Data for a provider.
    57  */
    58 typedef struct SUPDRVDTPROVIDER
     51 * Data for a tracepoint provider.
     52 */
     53typedef struct SUPDRVTPPROVIDER
    5954{
    6055    /** The entry in the provider list for this image. */
    61     RTLISTNODE          ListEntry;
    62 
    63     /** The provider descriptor. */
    64     PVTGDESCPROVIDER    pDesc;
    65     /** The VTG header. */
    66     PVTGOBJHDR          pHdr;
     56    RTLISTNODE              ListEntry;
     57
     58    /** The core structure. */
     59    SUPDRVVDTPROVIDERCORE   Core;
    6760
    6861    /** Pointer to the image this provider resides in.  NULL if it's a
    6962     * driver. */
    70     PSUPDRVLDRIMAGE     pImage;
     63    PSUPDRVLDRIMAGE         pImage;
    7164    /** The session this provider is associated with if registered via
    7265     * SUPR0VtgRegisterDrv.  NULL if pImage is set. */
    73     PSUPDRVSESSION      pSession;
     66    PSUPDRVSESSION          pSession;
    7467    /** The module name. */
    75     const char         *pszModName;
    76 
    77     /** Dtrace provider attributes. */
    78     dtrace_pattr_t      DtAttrs;
    79     /** The ID of this provider. */
    80     dtrace_provider_id_t idDtProv;
    81     /** The number of probes we've provided to DTrace. */
    82     uint32_t            cProvidedProbes;
     68    const char             *pszModName;
     69
    8370    /** Set when the module is unloaded or the driver deregisters its probes. */
    84     bool                fZombie;
     71    bool                    fZombie;
     72    /** Set if the provider has been successfully registered with the
     73     *  tracer. */
     74    bool                    fRegistered;
    8575    /** The provider name (for logging purposes). */
    86     char                szName[1];
    87 } SUPDRVDTPROVIDER;
    88 /** Pointer to the data for a provider. */
    89 typedef SUPDRVDTPROVIDER *PSUPDRVDTPROVIDER;
    90 
    91 /* Seems there is some return code difference here. Keep the return code and
    92    case it to whatever the host desires. */
    93 #ifdef RT_OS_DARWIN
    94 typedef void FNPOPS_ENABLE(void *, dtrace_id_t, void *);
    95 #else
    96 typedef int  FNPOPS_ENABLE(void *, dtrace_id_t, void *);
    97 #endif
     76    char                    szName[1];
     77} SUPDRVTPPROVIDER;
     78/** Pointer to the data for a tracepoint provider. */
     79typedef SUPDRVTPPROVIDER *PSUPDRVTPPROVIDER;
    9880
    9981
     
    10284*******************************************************************************/
    10385#if 0
    104 # define LOG_DTRACE(a_Args)  SUPR0Printf a_Args
     86# define LOG_TRACER(a_Args)  SUPR0Printf a_Args
    10587#else
    106 # define LOG_DTRACE(a_Args)  do { } while (0)
     88# define LOG_TRACER(a_Args)  do { } while (0)
    10789#endif
    108 
    109 /*******************************************************************************
    110 *   Internal Functions                                                         *
    111 *******************************************************************************/
    112 static void     supdrvDTracePOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc);
    113 static int      supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
    114 static void     supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
    115 static void     supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    116                                             dtrace_argdesc_t *pArgDesc);
    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
    121 static void     supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
    122 
    12390
    12491
     
    12693*   Global Variables                                                           *
    12794*******************************************************************************/
    128 /**
    129  * DTrace provider method table.
    130  */
    131 static const dtrace_pops_t g_SupDrvDTraceProvOps =
    132 {
    133     /* .dtps_provide         = */ supdrvDTracePOps_Provide,
    134     /* .dtps_provide_module  = */ NULL,
    135     /* .dtps_enable          = */ (FNPOPS_ENABLE *)supdrvDTracePOps_Enable,
    136     /* .dtps_disable         = */ supdrvDTracePOps_Disable,
    137     /* .dtps_suspend         = */ NULL,
    138     /* .dtps_resume          = */ NULL,
    139     /* .dtps_getargdesc      = */ supdrvDTracePOps_GetArgDesc,
    140 #ifdef RT_OS_SOLARIS
    141     /* .dtps_getargval       = */ supdrvDTracePOps_GetArgVal,
    142 #else
    143     /* .dtps_getargval       = */ NULL/*supdrvDTracePOps_GetArgVal*/,
    144 #endif
    145     /* .dtps_usermode        = */ NULL,
    146     /* .dtps_destroy         = */ supdrvDTracePOps_Destroy
    147 };
    14895
    14996
     
    366313
    367314/**
    368  * Converts an attribute from VTG description speak to DTrace.
    369  *
    370  * @param   pDtAttr             The DTrace attribute (dst).
    371  * @param   pVtgAttr            The VTG attribute descriptor (src).
    372  */
    373 static void supdrvVtgConvAttr(dtrace_attribute_t *pDtAttr, PCVTGDESCATTR pVtgAttr)
    374 {
    375     pDtAttr->dtat_name  = pVtgAttr->u8Code - 1;
    376     pDtAttr->dtat_data  = pVtgAttr->u8Data - 1;
    377     pDtAttr->dtat_class = pVtgAttr->u8DataDep - 1;
    378 }
    379 
    380 /**
    381315 * Gets a string from the string table.
    382316 *
     
    393327
    394328/**
    395  * Frees the provider structure and associated resources. 
    396  * 
     329 * Frees the provider structure and associated resources.
     330 *
    397331 * @param   pProv               The provider to free.
    398332 */
    399 static void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv)
    400 {
    401     LOG_DTRACE(("Freeing DTrace provider '%s' / %p\n", pProv->szName, pProv->idDtProv));
     333static void supdrvTracerFreeProvider(PSUPDRVTPPROVIDER pProv)
     334{
     335    LOG_TRACER(("Freeing DTrace provider '%s' / %p\n", pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
     336    pProv->fRegistered = false;
     337    pProv->fZombie     = true;
     338    pProv->Core.pDesc  = NULL;
     339    pProv->Core.pHdr   = NULL;
     340    RT_ZERO(pProv->Core.TracerData);
     341    RTMemFree(pProv);
     342}
     343
     344
     345/**
     346 * Deregisters a provider.
     347 *
     348 * If the provider is still busy, it will be put in the zombie list.
     349 *
     350 * @param   pDevExt             The device extension.
     351 * @param   pProv               The provider.
     352 *
     353 * @remarks The caller owns mtxTracer.
     354 */
     355static void supdrvTracerDeregisterVtgObj(PSUPDRVDEVEXT pDevExt, PSUPDRVTPPROVIDER pProv)
     356{
     357    int rc;
     358    if (!pProv->fRegistered || !pDevExt->pTracerOps)
     359        rc = VINF_SUCCESS;
     360    else
     361        rc = pDevExt->pTracerOps->pfnDeregisterProvider(pDevExt->pTracerOps, &pProv->Core);
     362    if (RT_SUCCESS(rc))
     363    {
     364        supdrvTracerFreeProvider(pProv);
     365        return;
     366    }
     367
    402368    pProv->fZombie = true;
    403     pProv->pDesc   = NULL;
    404     pProv->pHdr    = NULL;
    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  * 
     369    RTListAppend(&pDevExt->TracerProviderZombieList, &pProv->ListEntry);
     370    LOG_TRACER(("Invalidated provider '%s' / %p and put it on the zombie list (rc=%Rrc)\n",
     371                pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
     372}
     373
     374
     375/**
     376 * Processes the zombie list.
     377 *
    414378 * @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  * 
     379 */
     380static void supdrvTracerProcessZombies(PSUPDRVDEVEXT pDevExt)
     381{
     382    PSUPDRVTPPROVIDER pProv, pProvNext;
     383
     384    RTSemFastMutexRequest(pDevExt->mtxTracer);
     385    RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
     386    {
     387        int rc = pDevExt->pTracerOps->pfnDeregisterZombieProvider(pDevExt->pTracerOps, &pProv->Core);
     388        if (RT_SUCCESS(rc))
     389        {
     390            RTListNodeRemove(&pProv->ListEntry);
     391            supdrvTracerFreeProvider(pProv);
     392        }
     393    }
     394    RTSemFastMutexRelease(pDevExt->mtxTracer);
     395}
     396
     397
     398/**
     399 * Unregisters all providers, including zombies, waiting for busy providers to
     400 * go idle and unregister smoothly.
     401 *
     402 * This may block.
     403 *
    440404 * @param   pDevExt             The device extension.
    441405 */
    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);
     406static void supdrvTracerRemoveAllProviders(PSUPDRVDEVEXT pDevExt)
     407{
     408    uint32_t            i;
     409    PSUPDRVTPPROVIDER   pProv;
     410    PSUPDRVTPPROVIDER   pProvNext;
     411
     412    /*
     413     * Unregister all probes (there should only be one).
     414     */
     415    RTSemFastMutexRequest(pDevExt->mtxTracer);
     416    RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
     417    {
     418        RTListNodeRemove(&pProv->ListEntry);
     419        supdrvTracerDeregisterVtgObj(pDevExt, pProv);
     420    }
     421    RTSemFastMutexRelease(pDevExt->mtxTracer);
     422
     423    /*
     424     * Try unregister zombies now, sleep on busy ones.
     425     */
     426    for (i = 0; ; i++)
     427    {
     428        bool fEmpty;
     429
     430        RTSemFastMutexRequest(pDevExt->mtxTracer);
     431        RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
     432        {
     433            int rc;
     434            LOG_TRACER(("supdrvTracerRemoveAllProviders: Attemting to unregister '%s' / %p...\n",
     435                        pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
     436
     437            if (pDevExt->pTracerOps)
     438                rc = pDevExt->pTracerOps->pfnDeregisterZombieProvider(pDevExt->pTracerOps, &pProv->Core);
     439            else
     440                rc = VINF_SUCCESS;
     441            if (!rc)
     442            {
     443                RTListNodeRemove(&pProv->ListEntry);
     444                supdrvTracerFreeProvider(pProv);
     445            }
     446            else if (!(i & 0xf))
     447                SUPR0Printf("supdrvTracerRemoveAllProviders: Waiting on busy provider '%s' / %p (rc=%d)\n",
     448                            pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc);
     449            else
     450                LOG_TRACER(("supdrvTracerRemoveAllProviders: Failed to unregister provider '%s' / %p - rc=%d\n",
     451                            pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
     452        }
     453
     454        fEmpty = RTListIsEmpty(&pDevExt->TracerProviderZombieList);
     455        RTSemFastMutexRelease(pDevExt->mtxTracer);
     456        if (fEmpty)
     457            break;
     458
     459        /* Delay...*/
     460        RTThreadSleep(1000);
     461    }
    457462}
    458463
     
    469474 * @param   pszModName          The module name.
    470475 */
    471 static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
    472                              PSUPDRVSESSION pSession, const char *pszModName)
     476static int supdrvTracerRegisterVtgObj(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
     477                                      PSUPDRVSESSION pSession, const char *pszModName)
    473478{
    474479    int                 rc;
    475480    unsigned            i;
    476     PSUPDRVDTPROVIDER   pProv;
     481    PSUPDRVTPPROVIDER   pProv;
    477482
    478483    /*
     
    492497        return rc;
    493498
    494     rc = RTSemFastMutexRequest(pDevExt->mtxDTrace);
     499    rc = RTSemFastMutexRequest(pDevExt->mtxTracer);
    495500    if (RT_FAILURE(rc))
    496501        return rc;
    497     RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry)
    498     {
    499         if (pProv->pHdr == pVtgHdr)
     502    RTListForEach(&pDevExt->TracerProviderList, pProv, SUPDRVTPPROVIDER, ListEntry)
     503    {
     504        if (pProv->Core.pHdr == pVtgHdr)
    500505        {
    501506            rc = VERR_SUPDRV_VTG_ALREADY_REGISTERED;
    502507            break;
    503508        }
    504         if (   pProv->pSession == pSession 
     509        if (   pProv->pSession == pSession
    505510            && pProv->pImage   == pImage)
    506511        {
     
    509514        }
    510515    }
    511     RTSemFastMutexRelease(pDevExt->mtxDTrace);
     516    RTSemFastMutexRelease(pDevExt->mtxTracer);
    512517    if (RT_FAILURE(rc))
    513518        return rc;
     
    522527        const char      *pszName = supdrvVtgGetString(pVtgHdr, pDesc->offName);
    523528        size_t const     cchName = strlen(pszName);
    524         pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVDTPROVIDER, szName[cchName + 1]));
     529        pProv = (PSUPDRVTPPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVTPPROVIDER, szName[cchName + 1]));
    525530        if (pProv)
    526531        {
    527             pProv->pDesc            = pDesc;
    528             pProv->pHdr             = pVtgHdr;
     532            pProv->Core.pDesc       = pDesc;
     533            pProv->Core.pHdr        = pVtgHdr;
     534            pProv->Core.pszName     = &pProv->szName[0];
    529535            pProv->pImage           = pImage;
    530536            pProv->pSession         = pSession;
    531537            pProv->pszModName       = pszModName;
    532             pProv->idDtProv         = 0;
    533             pProv->cProvidedProbes  = 0;
    534538            pProv->fZombie          = false;
    535             memcpy(pProv->szName, pszName, cchName + 1);
    536             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf);
    537             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod,      &pDesc->AttrModules);
    538             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_func,     &pDesc->AttrFunctions);
    539             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_name,     &pDesc->AttrNames);
    540             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_args,     &pDesc->AttrArguments);
    541 
    542             rc = dtrace_register(pProv->szName,
    543                                  &pProv->DtAttrs,
    544                                  DTRACE_PRIV_KERNEL,
    545                                  NULL /* cred */,
    546                                  &g_SupDrvDTraceProvOps,
    547                                  pProv,
    548                                  &pProv->idDtProv);
    549             if (!rc)
     539            pProv->fRegistered      = true;
     540            memcpy(&pProv->szName[0], pszName, cchName + 1);
     541
     542            rc = RTSemFastMutexRequest(pDevExt->mtxTracer);
     543            if (RT_SUCCESS(rc))
    550544            {
    551                 rc = RTSemFastMutexRequest(pDevExt->mtxDTrace);
     545                if (pDevExt->pTracerOps)
     546                    rc = pDevExt->pTracerOps->pfnRegisterProvider(pDevExt->pTracerOps, &pProv->Core);
     547                else
     548                {
     549                    pProv->fRegistered = false;
     550                    rc = VINF_SUCCESS;
     551                }
    552552                if (RT_SUCCESS(rc))
    553553                {
    554                     RTListAppend(&pDevExt->DtProviderList, &pProv->ListEntry);
    555                     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    556                     LOG_DTRACE(("Registered DTrace provider '%s' in '%s' -> %p\n", pProv->szName, pszModName, pProv->idDtProv));
     554                    RTListAppend(&pDevExt->TracerProviderList, &pProv->ListEntry);
     555                    RTSemFastMutexRelease(pDevExt->mtxTracer);
     556                    LOG_TRACER(("Registered DTrace provider '%s' in '%s' -> %p\n",
     557                                pProv->szName, pszModName, pProv->Core.TracerData.DTrace.idProvider));
    557558                }
    558559                else
    559                     dtrace_unregister(pProv->idDtProv);
     560                {
     561                    RTSemFastMutexRelease(pDevExt->mtxTracer);
     562                    RTMemFree(pProv);
     563                }
    560564            }
    561             else
    562                 rc = RTErrConvertFromErrno(rc);
    563565        }
    564566        else
     
    567569        if (RT_FAILURE(rc))
    568570        {
    569             PSUPDRVDTPROVIDER   pProvNext;
    570             supdrvVtgFreeProvider(pProv);
    571 
    572             RTSemFastMutexRequest(pDevExt->mtxDTrace);
    573             RTListForEachReverseSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
     571            PSUPDRVTPPROVIDER   pProvNext;
     572            supdrvTracerFreeProvider(pProv);
     573
     574            RTSemFastMutexRequest(pDevExt->mtxTracer);
     575            RTListForEachReverseSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
    574576            {
    575                 if (pProv->pHdr == pVtgHdr)
     577                if (pProv->Core.pHdr == pVtgHdr)
    576578                {
    577579                    RTListNodeRemove(&pProv->ListEntry);
    578                     supdrvVtgDeregister(pDevExt, pProv);
     580                    supdrvTracerDeregisterVtgObj(pDevExt, pProv);
    579581                }
    580582            }
    581             RTSemFastMutexRelease(pDevExt->mtxDTrace);
     583            RTSemFastMutexRelease(pDevExt->mtxTracer);
    582584            return rc;
    583585        }
     
    605607    AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
    606608
    607     rc = supdrvVtgRegister(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
     609    rc = supdrvTracerRegisterVtgObj(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
    608610
    609611    /*
    610612     * Try unregister zombies while we have a chance.
    611613     */
    612     supdrvVtgProcessZombies(pSession->pDevExt);
     614    supdrvTracerProcessZombies(pSession->pDevExt);
    613615
    614616    return rc;
     
    624626SUPR0DECL(void) SUPR0VtgDeregisterDrv(PSUPDRVSESSION pSession)
    625627{
    626     PSUPDRVDTPROVIDER pProv, pProvNext;
     628    PSUPDRVTPPROVIDER pProv, pProvNext;
    627629    PSUPDRVDEVEXT     pDevExt;
    628630    AssertReturnVoid(SUP_IS_SESSION_VALID(pSession));
     
    634636     * Search for providers belonging to this driver session.
    635637     */
    636     RTSemFastMutexRequest(pDevExt->mtxDTrace);
    637     RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
     638    RTSemFastMutexRequest(pDevExt->mtxTracer);
     639    RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
    638640    {
    639641        if (pProv->pSession == pSession)
    640642        {
    641643            RTListNodeRemove(&pProv->ListEntry);
    642             supdrvVtgDeregister(pDevExt, pProv);
    643         }
    644     }
    645     RTSemFastMutexRelease(pDevExt->mtxDTrace);
     644            supdrvTracerDeregisterVtgObj(pDevExt, pProv);
     645        }
     646    }
     647    RTSemFastMutexRelease(pDevExt->mtxTracer);
    646648
    647649    /*
    648650     * Try unregister zombies while we have a chance.
    649651     */
    650     supdrvVtgProcessZombies(pDevExt);
    651 }
    652 
    653 
    654 /**
    655  * Registers the VTG tracepoint providers of a module loaded by 
    656  * the support driver. 
    657  * 
     652    supdrvTracerProcessZombies(pDevExt);
     653}
     654
     655
     656/**
     657 * Registers the VTG tracepoint providers of a module loaded by
     658 * the support driver.
     659 *
    658660 * This should be called from the ModuleInit code.
    659661 *
     
    669671    int             rc;
    670672
    671     /* 
     673    /*
    672674     * Validate input and context.
    673675     */
     
    675677    AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
    676678
     679    AssertPtrReturn(pImage, VERR_INVALID_POINTER);
    677680    pDevExt = pImage->pDevExt;
    678681    AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
     
    684687     */
    685688    cbVtgObj = (uintptr_t)pVtgHdr - (uintptr_t)pImage->pvImage;
    686     AssertMsgReturn(cbVtgObj /*off*/ < pImage->cbImageBits, 
     689    AssertMsgReturn(cbVtgObj /*off*/ < pImage->cbImageBits,
    687690                    ("pVtgHdr=%p offVtgObj=%p cbImageBits=%p\n", pVtgHdr, cbVtgObj, pImage->cbImageBits),
    688691                    VERR_INVALID_PARAMETER);
    689692    cbVtgObj = pImage->cbImageBits - cbVtgObj;
    690693
    691     rc = supdrvVtgRegister(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
     694    rc = supdrvTracerRegisterVtgObj(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
    692695
    693696    /*
    694697     * Try unregister zombies while we have a chance.
    695698     */
    696     supdrvVtgProcessZombies(pDevExt);
     699    supdrvTracerProcessZombies(pDevExt);
    697700
    698701    return rc;
     
    701704
    702705/**
    703  * Module unloading hook, called after execution in the module have ceased.
    704  *
    705  * @param   pDevExt             The device extension structure.
    706  * @param   pImage              The image being unloaded.
    707  */
    708 void VBOXCALL supdrvVtgModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
    709 {
    710     PSUPDRVDTPROVIDER pProv, pProvNext;
    711 
    712     /*
    713      * Unregister all providers belonging to this image.
    714      */
    715     RTSemFastMutexRequest(pDevExt->mtxDTrace);
    716     RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    717     {
    718         if (pProv->pImage == pImage)
    719         {
    720             RTListNodeRemove(&pProv->ListEntry);
    721             supdrvVtgDeregister(pDevExt, pProv);
    722         }
    723     }
    724     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    725 
    726     /*
    727      * Try unregister zombies while we have a chance.
    728      */
    729     supdrvVtgProcessZombies(pDevExt);
     706 * Registers the tracer.
     707 *
     708 * This should be called from the ModuleInit code or from a ring-0 session.
     709 *
     710 * @returns VBox status code.
     711 * @param   hMod                The module handle.
     712 * @param   pSession            Ring-0 session handle.
     713 * @param   pReg                Pointer to the tracer registration structure.
     714 * @param   ppHlp               Where to return the tracer helper method table.
     715 */
     716SUPR0DECL(int) SUPR0TracerRegister(void *hMod, PSUPDRVSESSION pSession, PCSUPDRVTRACERREG pReg, PCSUPDRVTRACERHLP *ppHlp)
     717{
     718    PSUPDRVLDRIMAGE pImage = (PSUPDRVLDRIMAGE)hMod;
     719    PSUPDRVDEVEXT   pDevExt;
     720    int             rc;
     721
     722    /*
     723     * Validate input and context.
     724     */
     725    AssertPtrReturn(ppHlp, VERR_INVALID_POINTER);
     726    *ppHlp = NULL;
     727    AssertPtrReturn(pReg,  VERR_INVALID_HANDLE);
     728
     729    if (pImage)
     730    {
     731        AssertPtrReturn(pImage, VERR_INVALID_POINTER);
     732        AssertReturn(pSession == NULL, VERR_INVALID_PARAMETER);
     733        pDevExt = pImage->pDevExt;
     734        AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
     735        AssertReturn(pDevExt->pLdrInitImage  == pImage, VERR_WRONG_ORDER);
     736        AssertReturn(pDevExt->hLdrInitThread == RTThreadNativeSelf(), VERR_WRONG_ORDER);
     737    }
     738    else
     739    {
     740        AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
     741        AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
     742        pDevExt = pSession->pDevExt;
     743        AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
     744    }
     745
     746    AssertPtrReturn(pReg->pfnRegisterProvider, VERR_INVALID_POINTER);
     747    AssertPtrReturn(pReg->pfnDeregisterProvider, VERR_INVALID_POINTER);
     748    AssertPtrReturn(pReg->pfnDeregisterZombieProvider, VERR_INVALID_POINTER);
     749
     750    /*
     751     * Do the job.
     752     */
     753    rc = RTSemFastMutexRequest(pDevExt->mtxTracer);
     754    if (RT_SUCCESS(rc))
     755    {
     756        if (!pDevExt->pTracerOps)
     757        {
     758            pDevExt->pTracerOps     = pReg;
     759            pDevExt->pTracerSession = pSession;
     760            pDevExt->pTracerImage   = pImage;
     761
     762            *ppHlp = &pDevExt->TracerHlp;
     763            rc = VINF_SUCCESS;
     764        }
     765        else
     766            rc = VERR_SUPDRV_TRACER_ALREADY_REGISTERED;
     767        RTSemFastMutexRelease(pDevExt->mtxTracer);
     768    }
     769
     770    return rc;
     771
     772}
     773
     774
     775/**
     776 * Deregister a tracer associated with a ring-0 session.
     777 *
     778 * @returns VBox status code.
     779 * @param   pSession            Ring-0 session handle.
     780 */
     781SUPR0DECL(int) SUPR0TracerDeregister(PSUPDRVSESSION pSession)
     782{
     783    PSUPDRVDEVEXT   pDevExt;
     784    int             rc;
     785
     786    /*
     787     * Validate input and context.
     788     */
     789    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
     790    AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
     791    pDevExt = pSession->pDevExt;
     792    AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
     793
     794    /*
     795     * Do the job.
     796     */
     797    rc = RTSemFastMutexRequest(pDevExt->mtxTracer);
     798    if (RT_SUCCESS(rc))
     799    {
     800        if (pDevExt->pTracerSession == pSession)
     801        {
     802            pDevExt->fTracerUnloading = true;
     803            RTSemFastMutexRelease(pDevExt->mtxTracer);
     804
     805            supdrvTracerRemoveAllProviders(pDevExt);
     806
     807            RTSemFastMutexRequest(pDevExt->mtxTracer);
     808            pDevExt->pTracerImage     = NULL;
     809            pDevExt->pTracerSession   = NULL;
     810            pDevExt->pTracerOps       = NULL;
     811            pDevExt->fTracerUnloading = false;
     812        }
     813        else
     814            rc = VERR_SUPDRV_TRACER_NOT_REGISTERED;
     815        RTSemFastMutexRelease(pDevExt->mtxTracer);
     816    }
     817
     818    return rc;
     819}
     820
     821
     822/**
     823 * Module unloading hook, called after execution in the module have ceased.
     824 *
     825 * @param   pDevExt             The device extension structure.
     826 * @param   pImage              The image being unloaded.
     827 */
     828void VBOXCALL supdrvTracerModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
     829{
     830    PSUPDRVTPPROVIDER pProv, pProvNext;
     831    AssertPtrReturnVoid(pImage);        /* paranoia */
     832
     833    RTSemFastMutexRequest(pDevExt->mtxTracer);
     834
     835    /*
     836     * If it is the tracer image, we have to unload all the providers.
     837     */
     838    if (pDevExt->pTracerImage == pImage)
     839    {
     840        pDevExt->fTracerUnloading = true;
     841        RTSemFastMutexRelease(pDevExt->mtxTracer);
     842
     843        supdrvTracerRemoveAllProviders(pDevExt);
     844
     845        RTSemFastMutexRequest(pDevExt->mtxTracer);
     846        pDevExt->pTracerImage     = NULL;
     847        pDevExt->pTracerSession   = NULL;
     848        pDevExt->pTracerOps       = NULL;
     849        pDevExt->fTracerUnloading = false;
     850        RTSemFastMutexRelease(pDevExt->mtxTracer);
     851    }
     852    else
     853    {
     854        /*
     855         * Unregister all providers belonging to this image.
     856         */
     857        RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
     858        {
     859            if (pProv->pImage == pImage)
     860            {
     861                RTListNodeRemove(&pProv->ListEntry);
     862                supdrvTracerDeregisterVtgObj(pDevExt, pProv);
     863            }
     864        }
     865
     866        RTSemFastMutexRelease(pDevExt->mtxTracer);
     867
     868        /*
     869         * Try unregister zombies while we have a chance.
     870         */
     871        supdrvTracerProcessZombies(pDevExt);
     872    }
    730873}
    731874
     
    735878 *
    736879 * @returns VBox status code.
    737  * @param   pDevExt             The device extension structure.
    738  * @param   pVtgFireProbe       Pointer to the SUPR0VtgFireProbe entry.
    739  */
    740 int VBOXCALL supdrvVtgInit(PSUPDRVDEVEXT pDevExt, PSUPFUNC pVtgFireProbe)
    741 {
    742     Assert(!strcmp(pVtgFireProbe->szName, "SUPR0VtgFireProbe"));
    743 
     880 * @param   pDevExt             The device extension structure.
     881 */
     882int VBOXCALL supdrvTracerInit(PSUPDRVDEVEXT pDevExt)
     883{
    744884    /*
    745885     * Register a provider for this module.
    746886     */
    747     int rc = RTSemFastMutexCreate(&pDevExt->mtxDTrace);
     887    int rc = RTSemFastMutexCreate(&pDevExt->mtxTracer);
    748888    if (RT_SUCCESS(rc))
    749889    {
    750 #ifdef RT_OS_SOLARIS
    751         pVtgFireProbe->pfn = (void *)(uintptr_t)dtrace_probe;
    752 #endif
    753         RTListInit(&pDevExt->DtProviderList);
    754         RTListInit(&pDevExt->DtProviderZombieList);
    755         rc = supdrvVtgRegister(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
     890        pDevExt->TracerHlp.uVersion    = SUPDRVTRACERHLP_VERSION;
     891        /** @todo  */
     892        pDevExt->TracerHlp.uEndVersion = SUPDRVTRACERHLP_VERSION;
     893
     894        RTListInit(&pDevExt->TracerProviderList);
     895        RTListInit(&pDevExt->TracerProviderZombieList);
     896        rc = supdrvTracerRegisterVtgObj(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
    756897        if (RT_SUCCESS(rc))
    757898            return rc;
    758         RTSemFastMutexDestroy(pDevExt->mtxDTrace);
    759     }
    760     pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
     899        RTSemFastMutexDestroy(pDevExt->mtxTracer);
     900    }
     901    pDevExt->mtxTracer = NIL_RTSEMFASTMUTEX;
    761902    return rc;
    762903}
     
    769910 * @param   pDevExt             The device extension structure.
    770911 */
    771 void VBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt)
    772 {
    773     PSUPDRVDTPROVIDER pProv, pProvNext;
    774     uint32_t i;
    775     LOG_DTRACE(("supdrvVtgTerm\n"));
    776 
    777     /*
    778      * Unregister all probes (there should only be one).
    779      */
    780     RTSemFastMutexRequest(pDevExt->mtxDTrace);
    781     RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    782     {
    783         RTListNodeRemove(&pProv->ListEntry);
    784         supdrvVtgDeregister(pDevExt, pProv);
    785     }
    786     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    787 
    788     /*
    789      * Try unregister zombies now, sleep on busy ones.
    790      */
    791     for (i = 0; ; i++)
    792     {
    793         bool fEmpty;
    794 
    795         RTSemFastMutexRequest(pDevExt->mtxDTrace);
    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);
    801             if (!rc)
    802             {
    803                 RTListNodeRemove(&pProv->ListEntry);
    804                 supdrvVtgFreeProvider(pProv);
    805             }
    806             else if (!(i & 0xf))
    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));
    810         }
    811 
    812         fEmpty = RTListIsEmpty(&pDevExt->DtProviderZombieList);
    813         RTSemFastMutexRelease(pDevExt->mtxDTrace);
    814         if (fEmpty)
    815             break;
    816 
    817         /* Delay...*/
    818         RTThreadSleep(1000);
    819     }
    820 
    821     RTSemFastMutexDestroy(pDevExt->mtxDTrace);
    822     pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
    823     LOG_DTRACE(("supdrvVtgTerm: Done\n"));
    824 }
    825 
    826 
    827 /**
    828  * @callback_method_impl{dtrace_pops_t,dtps_provide}
    829  */
    830 static void     supdrvDTracePOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc)
    831 {
    832     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    833     uint16_t            idxProv;
    834     PVTGPROBELOC        pProbeLoc;
    835     PVTGPROBELOC        pProbeLocEnd;
    836     char               *pszFnNmBuf;
    837     size_t const        cbFnNmBuf = _4K + _1K;
    838 
    839     if (pDtProbeDesc)
    840         return;  /* We don't generate probes, so never mind these requests. */
    841 
    842     if (pProv->fZombie)
    843         return;
    844 
    845     if (pProv->cProvidedProbes >= pProv->pDesc->cProbes)
    846         return;
    847 
    848      /* Need a buffer for extracting the function names and mangling them in
    849         case of collision. */
    850      pszFnNmBuf = (char *)RTMemAlloc(cbFnNmBuf);
    851      if (!pszFnNmBuf)
    852          return;
    853 
    854      /*
    855       * Itereate the probe location list and register all probes related to
    856       * this provider.
    857       */
    858      idxProv      = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc);
    859      pProbeLoc    = pProv->pHdr->paProbLocs;
    860      pProbeLocEnd = pProv->pHdr->paProbLocsEnd;
    861      while ((uintptr_t)pProbeLoc < (uintptr_t)pProbeLocEnd)
    862      {
    863          PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
    864          if (   pProbeDesc->idxProvider == idxProv
    865              && pProbeLoc->idProbe      == UINT32_MAX)
    866          {
    867              /* The function name normally needs to be stripped since we're
    868                 using C++ compilers for most of the code.  ASSUMES nobody are
    869                 brave/stupid enough to use function pointer returns without
    870                 typedef'ing properly them. */
    871              const char *pszPrbName = supdrvVtgGetString(pProv->pHdr, pProbeDesc->offName);
    872              const char *pszFunc    = pProbeLoc->pszFunction;
    873              const char *psz        = strchr(pProbeLoc->pszFunction, '(');
    874              size_t      cch;
    875              if (psz)
    876              {
    877                  /* skip blanks preceeding the parameter parenthesis. */
    878                  while (   (uintptr_t)psz > (uintptr_t)pProbeLoc->pszFunction
    879                         && RT_C_IS_BLANK(psz[-1]))
    880                      psz--;
    881 
    882                  /* Find the start of the function name. */
    883                  pszFunc = psz - 1;
    884                  while ((uintptr_t)pszFunc > (uintptr_t)pProbeLoc->pszFunction)
    885                  {
    886                      char ch = pszFunc[-1];
    887                      if (!RT_C_IS_ALNUM(ch) && ch != '_' && ch != ':')
    888                          break;
    889                      pszFunc--;
    890                  }
    891                  cch = psz - pszFunc;
    892              }
    893              else
    894                  cch = strlen(pszFunc);
    895              RTStrCopyEx(pszFnNmBuf, cbFnNmBuf, pszFunc, cch);
    896 
    897              /* Look up the probe, if we have one in the same function, mangle
    898                 the function name a little to avoid having to deal with having
    899                 multiple location entries with the same probe ID. (lazy bird) */
    900              Assert(pProbeLoc->idProbe == UINT32_MAX);
    901              if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
    902              {
    903                  RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u",  pProbeLoc->uLine);
    904                  if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
    905                  {
    906                      unsigned iOrd = 2;
    907                      while (iOrd < 128)
    908                      {
    909                          RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u-%u",  pProbeLoc->uLine, iOrd);
    910                          if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) == DTRACE_IDNONE)
    911                              break;
    912                          iOrd++;
    913                      }
    914                      if (iOrd >= 128)
    915                      {
    916                          LogRel(("VBoxDrv: More than 128 duplicate probe location instances in file %s at line %u, function %s [%s], probe %s\n",
    917                                  pProbeLoc->pszFile, pProbeLoc->uLine, pProbeLoc->pszFunction, pszFnNmBuf, pszPrbName));
    918                          continue;
    919                      }
    920                  }
    921              }
    922 
    923              /* Create the probe. */
    924              AssertCompile(sizeof(pProbeLoc->idProbe) == sizeof(dtrace_id_t));
    925              pProbeLoc->idProbe = dtrace_probe_create(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName,
    926                                                       0 /*aframes*/, pProbeLoc);
    927              pProv->cProvidedProbes++;
    928          }
    929 
    930          pProbeLoc++;
    931      }
    932 
    933      RTMemFree(pszFnNmBuf);
    934 }
    935 
    936 
    937 /**
    938  * @callback_method_impl{dtrace_pops_t,dtps_enable}
    939  */
    940 static int      supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
    941 {
    942     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    943     if (!pProv->fZombie)
    944     {
    945         PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
    946         PVTGDESCPROBE   pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
    947 
    948         if (!pProbeLoc->fEnabled)
    949         {
    950             pProbeLoc->fEnabled = 1;
    951             if (ASMAtomicIncU32(&pProbeDesc->u32User) == 1)
    952                 pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
    953         }
    954     }
    955 
    956     return 0;
    957 }
    958 
    959 
    960 /**
    961  * @callback_method_impl{dtrace_pops_t,dtps_disable}
    962  */
    963 static void     supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
    964 {
    965     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    966     if (!pProv->fZombie)
    967     {
    968         PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
    969         PVTGDESCPROBE   pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
    970 
    971         if (pProbeLoc->fEnabled)
    972         {
    973             pProbeLoc->fEnabled = 0;
    974             if (ASMAtomicDecU32(&pProbeDesc->u32User) == 0)
    975                 pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
    976         }
    977     }
    978 }
    979 
    980 
    981 /**
    982  * @callback_method_impl{dtrace_pops_t,dtps_getargdesc}
    983  */
    984 static void     supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    985                                             dtrace_argdesc_t *pArgDesc)
    986 {
    987     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    988     unsigned            uArg       = pArgDesc->dtargd_ndx;
    989 
    990     if (!pProv->fZombie)
    991     {
    992         PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
    993         PVTGDESCPROBE   pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
    994         PVTGDESCARGLIST pArgList   = (PVTGDESCARGLIST)((uintptr_t)pProv->pHdr->paArgLists + pProbeDesc->offArgList);
    995 
    996         Assert(pProbeDesc->offArgList < pProv->pHdr->cbArgLists);
    997         if (pArgList->cArgs > uArg)
    998         {
    999             const char *pszType = supdrvVtgGetString(pProv->pHdr, pArgList->aArgs[uArg].offType);
    1000             size_t      cchType = strlen(pszType);
    1001             if (cchType < sizeof(pArgDesc->dtargd_native))
    1002             {
    1003                 memcpy(pArgDesc->dtargd_native, pszType, cchType + 1);
    1004                 /** @todo mapping */
    1005                 return;
    1006             }
    1007         }
    1008     }
    1009 
    1010     pArgDesc->dtargd_ndx = DTRACE_ARGNONE;
    1011 }
    1012 
    1013 
    1014 #ifdef RT_OS_SOLARIS
    1015 
    1016 # ifdef __cplusplus
    1017 extern "C"
    1018 #endif
    1019 uint64_t dtrace_getarg(int iArg, int cFrames);
    1020 
    1021 /**
    1022  * @callback_method_impl{dtrace_pops_t,dtps_getargval}
    1023  */
    1024 static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    1025                                            int iArg, int cFrames)
    1026 {
    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 */
    1045 
    1046 
    1047 /**
    1048  * @callback_method_impl{dtrace_pops_t,dtps_destroy}
    1049  */
    1050 static void    supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
    1051 {
    1052     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    1053     if (!pProv->fZombie)
    1054     {
    1055         PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
    1056         Assert(!pProbeLoc->fEnabled);
    1057         Assert(pProbeLoc->idProbe == idProbe); NOREF(idProbe);
    1058         pProbeLoc->idProbe = UINT32_MAX;
    1059     }
    1060     pProv->cProvidedProbes--;
    1061 }
    1062 
     912void VBOXCALL supdrvTracerTerm(PSUPDRVDEVEXT pDevExt)
     913{
     914    LOG_TRACER(("supdrvTracerTerm\n"));
     915
     916    supdrvTracerRemoveAllProviders(pDevExt);
     917
     918    RTSemFastMutexDestroy(pDevExt->mtxTracer);
     919    pDevExt->mtxTracer = NIL_RTSEMFASTMUTEX;
     920    LOG_TRACER(("supdrvTracerTerm: Done\n"));
     921}
     922
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