Index: /trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp	(revision 40703)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp	(revision 40704)
@@ -83,4 +83,6 @@
     /** Set when the module is unloaded or the driver deregisters its probes. */
     bool                fZombie;
+    /** The provider name (for logging purposes). */
+    char                szName[1];
 } SUPDRVDTPROVIDER;
 /** Pointer to the data for a provider. */
@@ -95,4 +97,13 @@
 #endif
 
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+#if 0
+# define LOG_DTRACE(a_Args)  SUPR0Printf a_Args
+#else
+# define LOG_DTRACE(a_Args)  do { } while (0)
+#endif
 
 /*******************************************************************************
@@ -104,6 +115,8 @@
 static void     supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
                                             dtrace_argdesc_t *pArgDesc);
-/*static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
-                                           int iArg, int cFrames);*/
+#ifdef RT_OS_SOLARIS
+static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
+                                           int iArg, int cFrames);
+#endif
 static void     supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
 
@@ -125,5 +138,9 @@
     /* .dtps_resume          = */ NULL,
     /* .dtps_getargdesc      = */ supdrvDTracePOps_GetArgDesc,
+#ifdef RT_OS_SOLARIS
+    /* .dtps_getargval       = */ supdrvDTracePOps_GetArgVal,
+#else
     /* .dtps_getargval       = */ NULL/*supdrvDTracePOps_GetArgVal*/,
+#endif
     /* .dtps_usermode        = */ NULL,
     /* .dtps_destroy         = */ supdrvDTracePOps_Destroy
@@ -382,8 +399,60 @@
 static void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv)
 {
+    LOG_DTRACE(("Freeing DTrace provider '%s' / %p\n", pProv->szName, pProv->idDtProv));
     pProv->fZombie = true;
     pProv->pDesc   = NULL;
     pProv->pHdr    = NULL;
     RTMemFree(pProv);
+}
+
+
+/**
+ * Deregisters a provider. 
+ *  
+ * If the provider is still busy, it will be put in the zombie list.
+ *  
+ * @param   pDevExt             The device extension.
+ * @param   pProv               The provider. 
+ *  
+ * @remarks The caller owns mtxDTrace. 
+ */
+static void supdrvVtgDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVDTPROVIDER pProv)
+{
+    int rc;
+
+    dtrace_invalidate(pProv->idDtProv);
+    rc = dtrace_unregister(pProv->idDtProv);
+    if (!rc)
+    {
+        supdrvVtgFreeProvider(pProv);
+        return;
+    }
+
+    pProv->fZombie = true;
+    RTListAppend(&pDevExt->DtProviderZombieList, &pProv->ListEntry);
+    LOG_DTRACE(("Invalidate DTrace provider '%s' / %p and put it on the zombie list\n", pProv->szName, pProv->idDtProv));
+}
+
+
+/**
+ * Processes the zombie list. 
+ *  
+ * @param   pDevExt             The device extension.
+ */
+static void supdrvVtgProcessZombies(PSUPDRVDEVEXT pDevExt)
+{
+    PSUPDRVDTPROVIDER pProv, pProvNext;
+
+    RTSemFastMutexRequest(pDevExt->mtxDTrace);
+    RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
+    {
+        int rc = dtrace_unregister(pProv->idDtProv);
+        if (!rc)
+        {
+            RTListNodeRemove(&pProv->ListEntry);
+            supdrvVtgFreeProvider(pProv);
+        }
+    }
+    RTSemFastMutexRelease(pDevExt->mtxDTrace);
 }
 
@@ -400,6 +469,6 @@
  * @param   pszModName          The module name.
  */
-static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage, PSUPDRVSESSION pSession,
-                             const char *pszModName)
+static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage, 
+                             PSUPDRVSESSION pSession, const char *pszModName)
 {
     int                 rc;
@@ -424,22 +493,23 @@
 
     rc = RTSemFastMutexRequest(pDevExt->mtxDTrace);
-    if (RT_SUCCESS(rc))
-    {
-        RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry)
-        {
-            if (pProv->pHdr == pVtgHdr)
-            {
-                RTSemFastMutexRelease(pDevExt->mtxDTrace);
-                return VERR_SUPDRV_VTG_ALREADY_REGISTERED;
-            }
-            if (   pProv->pSession == pSession 
-                && pProv->pImage   == pImage)
-            {
-                RTSemFastMutexRelease(pDevExt->mtxDTrace);
-                return VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION;
-            }
-        }
-        RTSemFastMutexRelease(pDevExt->mtxDTrace);
-    }
+    if (RT_FAILURE(rc))
+        return rc;
+    RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry)
+    {
+        if (pProv->pHdr == pVtgHdr)
+        {
+            rc = VERR_SUPDRV_VTG_ALREADY_REGISTERED;
+            break;
+        }
+        if (   pProv->pSession == pSession 
+            && pProv->pImage   == pImage)
+        {
+            rc = VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION;
+            break;
+        }
+    }
+    RTSemFastMutexRelease(pDevExt->mtxDTrace);
+    if (RT_FAILURE(rc))
+        return rc;
 
     /*
@@ -449,6 +519,8 @@
     while (i-- > 0)
     {
-        PVTGDESCPROVIDER pDesc  = &pVtgHdr->paProviders[i];
-        pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(sizeof(*pProv));
+        PVTGDESCPROVIDER pDesc   = &pVtgHdr->paProviders[i];
+        const char      *pszName = supdrvVtgGetString(pVtgHdr, pDesc->offName);
+        size_t const     cchName = strlen(pszName);
+        pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVDTPROVIDER, szName[cchName + 1]));
         if (pProv)
         {
@@ -461,4 +533,5 @@
             pProv->cProvidedProbes  = 0;
             pProv->fZombie          = false;
+            memcpy(pProv->szName, pszName, cchName + 1);
             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf);
             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod,      &pDesc->AttrModules);
@@ -467,5 +540,5 @@
             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_args,     &pDesc->AttrArguments);
 
-            rc = dtrace_register(supdrvVtgGetString(pVtgHdr, pDesc->offName),
+            rc = dtrace_register(pProv->szName,
                                  &pProv->DtAttrs,
                                  DTRACE_PRIV_KERNEL,
@@ -481,4 +554,5 @@
                     RTListAppend(&pDevExt->DtProviderList, &pProv->ListEntry);
                     RTSemFastMutexRelease(pDevExt->mtxDTrace);
+                    LOG_DTRACE(("Registered DTrace provider '%s' in '%s' -> %p\n", pProv->szName, pszModName, pProv->idDtProv));
                 }
                 else
@@ -502,10 +576,5 @@
                 {
                     RTListNodeRemove(&pProv->ListEntry);
-                    RTSemFastMutexRelease(pDevExt->mtxDTrace);
-
-                    dtrace_unregister(pProv->idDtProv);
-                    RTMemFree(pProv);
-
-                    RTSemFastMutexRequest(pDevExt->mtxDTrace);
+                    supdrvVtgDeregister(pDevExt, pProv);
                 }
             }
@@ -516,54 +585,4 @@
 
     return VINF_SUCCESS;
-}
-
-
-/**
- * Deregisters a provider. 
- *  
- * If the provider is still busy, it will be put in the zombie list.
- *  
- * @param   pDevExt             The device extension.
- * @param   pProv               The provider. 
- *  
- * @remarks The caller owns mtxDTrace. 
- */
-static void supdrvVtgDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVDTPROVIDER pProv)
-{
-    int rc;
-
-    dtrace_invalidate(pProv->idDtProv);
-    rc = dtrace_unregister(pProv->idDtProv);
-    if (!rc)
-    {
-        supdrvVtgFreeProvider(pProv);
-        return;
-    }
-
-    pProv->fZombie = true;
-    RTListAppend(&pDevExt->DtProviderZombieList, &pProv->ListEntry);
-}
-
-
-/**
- * Processes the zombie list. 
- *  
- * @param   pDevExt             The device extension.
- */
-static void supdrvVtgProcessZombies(PSUPDRVDEVEXT pDevExt)
-{
-    PSUPDRVDTPROVIDER pProv, pProvNext;
-
-    RTSemFastMutexRequest(pDevExt->mtxDTrace);
-    RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
-    {
-        int rc = dtrace_unregister(pProv->idDtProv);
-        if (!rc)
-        {
-            RTListNodeRemove(&pProv->ListEntry);
-            supdrvVtgFreeProvider(pProv);
-        }
-    }
-    RTSemFastMutexRelease(pDevExt->mtxDTrace);
 }
 
@@ -754,4 +773,5 @@
     PSUPDRVDTPROVIDER pProv, pProvNext;
     uint32_t i;
+    LOG_DTRACE(("supdrvVtgTerm\n"));
 
     /*
@@ -774,7 +794,9 @@
 
         RTSemFastMutexRequest(pDevExt->mtxDTrace);
-        RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
-        {
-            int rc = dtrace_unregister(pProv->idDtProv);
+        RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
+        {
+            int rc;
+            LOG_DTRACE(("supdrvVtgTerm: Attemting to unregister '%s' / %p...\n", pProv->szName, pProv->idDtProv));
+            rc = dtrace_unregister(pProv->idDtProv);
             if (!rc)
             {
@@ -783,5 +805,7 @@
             }
             else if (!(i & 0xf))
-                SUPR0Printf("supdrvVtgTerm: Waiting on busy provider %p\n", pProv->idDtProv);
+                SUPR0Printf("supdrvVtgTerm: Waiting on busy provider '%s' / %p (rc=%d)\n", pProv->szName, pProv->idDtProv, rc);
+            else
+                LOG_DTRACE(("supdrvVtgTerm: Failed to unregister provider '%s' / %p - rc=%d\n", pProv->szName, pProv->idDtProv, rc));
         }
 
@@ -797,4 +821,5 @@
     RTSemFastMutexDestroy(pDevExt->mtxDTrace);
     pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
+    LOG_DTRACE(("supdrvVtgTerm: Done\n"));
 }
 
@@ -987,5 +1012,11 @@
 
 
-#if 0
+#ifdef RT_OS_SOLARIS
+
+# ifdef __cplusplus
+extern "C" 
+#endif
+uint64_t dtrace_getarg(int iArg, int cFrames);
+
 /**
  * @callback_method_impl{dtrace_pops_t,dtps_getargval}
@@ -994,7 +1025,22 @@
                                            int iArg, int cFrames)
 {
-    return 0xbeef;
-}
-#endif
+    /* dtrace_getarg on AMD64 has a different opinion about how to use the
+       cFrames argument than dtrace_caller() and/or dtrace_getpcstack(), at
+       least when the probe is fired by dtrace_probe() the way we do.
+     
+       Setting aframes to 1 when calling dtrace_probe_create gives me the right
+       arguments, but the wrong 'caller'.  Since I cannot do anything about
+       'caller', the only solution is this hack.
+     
+       Not sure why the Solaris guys hasn't seen this issue before, but maybe
+       there isn't anyone using the default argument getter path for ring-0
+       dtrace_probe() calls, SDT surely isn't.
+     
+       WARNING! This code is subject to dtrace_getarg interface unstability! */
+    /** @todo File a solaris bug on dtrace_probe() + dtrace_getarg(). */
+    return dtrace_getarg(iArg, cFrames + 1);
+}
+
+#endif /* RT_OS_SOLARIS */
 
 
