Index: /trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp	(revision 25693)
+++ /trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp	(revision 25694)
@@ -382,5 +382,9 @@
 static void rtLockValComplainAboutClass(const char *pszPrefix, RTLOCKVALCLASSINT *pClass, uint32_t uSubClass, bool fVerbose)
 {
-
+    if (   VALID_PTR(pClass)
+        && pClass->u32Magic == RTLOCKVALCLASS_MAGIC)
+    {
+
+    }
 }
 
Index: /trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp	(revision 25693)
+++ /trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp	(revision 25694)
@@ -68,4 +68,5 @@
 static uint32_t             g_iDeadlockThread;
 static RTTHREAD             g_ahThreads[32];
+static RTLOCKVALCLASS       g_ahClasses[32];
 static RTCRITSECT           g_aCritSects[32];
 static RTSEMRW              g_ahSemRWs[32];
@@ -340,5 +341,6 @@
     for (uint32_t i = 0; i < cThreads; i++)
     {
-        RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectInit(&g_aCritSects[i]), VINF_SUCCESS);
+        RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectInitEx(&g_aCritSects[i], 0 /*fFlags*/, NIL_RTLOCKVALCLASS,
+                                                       RTLOCKVAL_SUB_CLASS_ANY, "RTCritSect"), VINF_SUCCESS);
         RTTEST_CHECK_RC_RETV(g_hTest, RTSemRWCreate(&g_ahSemRWs[i]), VINF_SUCCESS);
         RTTEST_CHECK_RC_RETV(g_hTest, RTSemMutexCreate(&g_ahSemMtxes[i]), VINF_SUCCESS);
@@ -418,5 +420,5 @@
 
 
-static DECLCALLBACK(int) test1Thread(RTTHREAD ThreadSelf, void *pvUser)
+static DECLCALLBACK(int) testDd1Thread(RTTHREAD ThreadSelf, void *pvUser)
 {
     uintptr_t       i     = (uintptr_t)pvUser;
@@ -452,11 +454,11 @@
 
 
-static void test1(uint32_t cThreads, uint32_t cSecs)
-{
-    testIt(cThreads, cSecs, false, test1Thread, "critsect");
-}
-
-
-static DECLCALLBACK(int) test2Thread(RTTHREAD ThreadSelf, void *pvUser)
+static void testDd1(uint32_t cThreads, uint32_t cSecs)
+{
+    testIt(cThreads, cSecs, false, testDd1Thread, "critsect");
+}
+
+
+static DECLCALLBACK(int) testDd2Thread(RTTHREAD ThreadSelf, void *pvUser)
 {
     uintptr_t       i     = (uintptr_t)pvUser;
@@ -508,11 +510,11 @@
 
 
-static void test2(uint32_t cThreads, uint32_t cSecs)
-{
-    testIt(cThreads, cSecs, false, test2Thread, "read-write");
-}
-
-
-static DECLCALLBACK(int) test3Thread(RTTHREAD ThreadSelf, void *pvUser)
+static void testDd2(uint32_t cThreads, uint32_t cSecs)
+{
+    testIt(cThreads, cSecs, false, testDd2Thread, "read-write");
+}
+
+
+static DECLCALLBACK(int) testDd3Thread(RTTHREAD ThreadSelf, void *pvUser)
 {
     uintptr_t       i     = (uintptr_t)pvUser;
@@ -555,11 +557,11 @@
 
 
-static void test3(uint32_t cThreads, uint32_t cSecs)
-{
-    testIt(cThreads, cSecs, true, test3Thread, "read-write race");
-}
-
-
-static DECLCALLBACK(int) test4Thread(RTTHREAD ThreadSelf, void *pvUser)
+static void testDd3(uint32_t cThreads, uint32_t cSecs)
+{
+    testIt(cThreads, cSecs, true, testDd3Thread, "read-write race");
+}
+
+
+static DECLCALLBACK(int) testDd4Thread(RTTHREAD ThreadSelf, void *pvUser)
 {
     uintptr_t       i     = (uintptr_t)pvUser;
@@ -611,11 +613,11 @@
 
 
-static void test4(uint32_t cThreads, uint32_t cSecs)
-{
-    testIt(cThreads, cSecs, true, test4Thread, "read-write race v2");
-}
-
-
-static DECLCALLBACK(int) test5Thread(RTTHREAD ThreadSelf, void *pvUser)
+static void testDd4(uint32_t cThreads, uint32_t cSecs)
+{
+    testIt(cThreads, cSecs, true, testDd4Thread, "read-write race v2");
+}
+
+
+static DECLCALLBACK(int) testDd5Thread(RTTHREAD ThreadSelf, void *pvUser)
 {
     uintptr_t       i     = (uintptr_t)pvUser;
@@ -651,11 +653,11 @@
 
 
-static void test5(uint32_t cThreads, uint32_t cSecs)
-{
-    testIt(cThreads, cSecs, false, test5Thread, "mutex");
-}
-
-
-static DECLCALLBACK(int) test6Thread(RTTHREAD ThreadSelf, void *pvUser)
+static void testDd5(uint32_t cThreads, uint32_t cSecs)
+{
+    testIt(cThreads, cSecs, false, testDd5Thread, "mutex");
+}
+
+
+static DECLCALLBACK(int) testDd6Thread(RTTHREAD ThreadSelf, void *pvUser)
 {
     uintptr_t       i     = (uintptr_t)pvUser;
@@ -704,11 +706,11 @@
 
 
-static void test6(uint32_t cThreads, uint32_t cSecs)
-{
-    testIt(cThreads, cSecs, false, test6Thread, "event");
-}
-
-
-static DECLCALLBACK(int) test7Thread(RTTHREAD ThreadSelf, void *pvUser)
+static void testDd6(uint32_t cThreads, uint32_t cSecs)
+{
+    testIt(cThreads, cSecs, false, testDd6Thread, "event");
+}
+
+
+static DECLCALLBACK(int) testDd7Thread(RTTHREAD ThreadSelf, void *pvUser)
 {
     uintptr_t       i     = (uintptr_t)pvUser;
@@ -758,9 +760,65 @@
 
 
-static void test7(uint32_t cThreads, uint32_t cSecs)
-{
-    testIt(cThreads, cSecs, false, test7Thread, "event multi");
-}
-
+static void testDd7(uint32_t cThreads, uint32_t cSecs)
+{
+    testIt(cThreads, cSecs, false, testDd7Thread, "event multi");
+}
+
+
+static void testLo1(void)
+{
+    RTTestSub(g_hTest, "locking order, automatic");
+
+    /* init, each critsect has its own class now. */
+    for (unsigned i = 0; i < RT_ELEMENTS(g_ahClasses); i++)
+    {
+        RTTEST_CHECK_RC_RETV(g_hTest, RTLockValidatorClassCreate(&g_ahClasses[i], true /*fAutodidact*/, RT_SRC_POS), VINF_SUCCESS);
+        RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectInitEx(&g_aCritSects[i], 0, g_ahClasses[i], RTLOCKVAL_SUB_CLASS_NONE, "RTCritSectLO"), VINF_SUCCESS);
+        RTTEST_CHECK_RETV(g_hTest, RTLockValidatorClassRetain(g_ahClasses[i]) == 3);
+        RTTEST_CHECK_RETV(g_hTest, RTLockValidatorClassRelease(g_ahClasses[i]) == 2);
+    }
+
+    /* Enter the first 4 critsects in ascending order and thereby definining
+       this as a valid lock order.  */
+    RTTEST_CHECK_RC(g_hTest, RTCritSectEnter(&g_aCritSects[0]), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, RTCritSectEnter(&g_aCritSects[1]), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, RTCritSectEnter(&g_aCritSects[2]), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, RTCritSectEnter(&g_aCritSects[3]), VINF_SUCCESS);
+
+    /* Now, leave and re-enter the critsects in a way that should break the
+       order and check that we get the appropriate response. */
+    int rc;
+    RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(&g_aCritSects[0]), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, rc = RTCritSectEnter(&g_aCritSects[0]), VERR_SEM_LV_WRONG_ORDER);
+    if (RT_SUCCESS(rc))
+        RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(&g_aCritSects[0]), VINF_SUCCESS);
+
+    RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(&g_aCritSects[1]), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, rc = RTCritSectEnter(&g_aCritSects[1]), VERR_SEM_LV_WRONG_ORDER);
+    if (RT_SUCCESS(rc))
+        RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(&g_aCritSects[1]), VINF_SUCCESS);
+
+    RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(&g_aCritSects[2]), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, rc= RTCritSectEnter(&g_aCritSects[2]), VERR_SEM_LV_WRONG_ORDER);
+    if (RT_SUCCESS(rc))
+        RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(&g_aCritSects[2]), VINF_SUCCESS);
+
+    RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(&g_aCritSects[3]), VINF_SUCCESS);
+
+    /* Check that recursion isn't subject to order checks. */
+
+
+    /* Enable strict release order for class 2 and check that violations
+       are caught. */
+
+
+    /* clean up */
+    for (unsigned i = 0; i < RT_ELEMENTS(g_ahClasses); i++)
+    {
+        RTTEST_CHECK(g_hTest, RTLockValidatorClassRelease(g_ahClasses[i]) == 1);
+        g_ahClasses[i] = NIL_RTLOCKVALCLASS;
+        RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectDelete(&g_aCritSects[i]), VINF_SUCCESS);
+    }
+}
 
 static bool testIsLockValidationCompiledIn(void)
@@ -837,13 +895,24 @@
     RTLockValidatorSetQuiet(false);
 
+    bool fTestDd = false;//true;
+    bool fTestLo = true;
+
     /*
      * Some initial tests with verbose output (all single pass).
      */
-    test1(3, 0);
-    test2(1, 0);
-    test2(3, 0);
-    test5(3, 0);
-    test6(3, 0);
-    test7(3, 0);
+    if (fTestDd)
+    {
+        testDd1(3, 0);
+        testDd2(1, 0);
+        testDd2(3, 0);
+        testDd5(3, 0);
+        testDd6(3, 0);
+        testDd7(3, 0);
+    }
+    if (fTestLo)
+    {
+        testLo1();
+    }
+
 
     /*
@@ -854,47 +923,50 @@
         RTLockValidatorSetQuiet(true);
 
-        test1( 2, SECS_SIMPLE_TEST);
-        test1( 3, SECS_SIMPLE_TEST);
-        test1( 7, SECS_SIMPLE_TEST);
-        test1(10, SECS_SIMPLE_TEST);
-        test1(15, SECS_SIMPLE_TEST);
-        test1(30, SECS_SIMPLE_TEST);
-
-        test2( 1, SECS_SIMPLE_TEST);
-        test2( 2, SECS_SIMPLE_TEST);
-        test2( 3, SECS_SIMPLE_TEST);
-        test2( 7, SECS_SIMPLE_TEST);
-        test2(10, SECS_SIMPLE_TEST);
-        test2(15, SECS_SIMPLE_TEST);
-        test2(30, SECS_SIMPLE_TEST);
-
-        test3( 2, SECS_SIMPLE_TEST);
-        test3(10, SECS_SIMPLE_TEST);
-
-        test4( 2, SECS_RACE_TEST);
-        test4( 6, SECS_RACE_TEST);
-        test4(10, SECS_RACE_TEST);
-        test4(30, SECS_RACE_TEST);
-
-        test5( 2, SECS_RACE_TEST);
-        test5( 3, SECS_RACE_TEST);
-        test5( 7, SECS_RACE_TEST);
-        test5(10, SECS_RACE_TEST);
-        test5(15, SECS_RACE_TEST);
-        test5(30, SECS_RACE_TEST);
-
-        test6( 2, SECS_SIMPLE_TEST);
-        test6( 3, SECS_SIMPLE_TEST);
-        test6( 7, SECS_SIMPLE_TEST);
-        test6(10, SECS_SIMPLE_TEST);
-        test6(15, SECS_SIMPLE_TEST);
-        test6(30, SECS_SIMPLE_TEST);
-
-        test7( 2, SECS_SIMPLE_TEST);
-        test7( 3, SECS_SIMPLE_TEST);
-        test7( 7, SECS_SIMPLE_TEST);
-        test7(10, SECS_SIMPLE_TEST);
-        test7(15, SECS_SIMPLE_TEST);
-        test7(30, SECS_SIMPLE_TEST);
+        if (fTestDd)
+        {
+            testDd1( 2, SECS_SIMPLE_TEST);
+            testDd1( 3, SECS_SIMPLE_TEST);
+            testDd1( 7, SECS_SIMPLE_TEST);
+            testDd1(10, SECS_SIMPLE_TEST);
+            testDd1(15, SECS_SIMPLE_TEST);
+            testDd1(30, SECS_SIMPLE_TEST);
+
+            testDd2( 1, SECS_SIMPLE_TEST);
+            testDd2( 2, SECS_SIMPLE_TEST);
+            testDd2( 3, SECS_SIMPLE_TEST);
+            testDd2( 7, SECS_SIMPLE_TEST);
+            testDd2(10, SECS_SIMPLE_TEST);
+            testDd2(15, SECS_SIMPLE_TEST);
+            testDd2(30, SECS_SIMPLE_TEST);
+
+            testDd3( 2, SECS_SIMPLE_TEST);
+            testDd3(10, SECS_SIMPLE_TEST);
+
+            testDd4( 2, SECS_RACE_TEST);
+            testDd4( 6, SECS_RACE_TEST);
+            testDd4(10, SECS_RACE_TEST);
+            testDd4(30, SECS_RACE_TEST);
+
+            testDd5( 2, SECS_RACE_TEST);
+            testDd5( 3, SECS_RACE_TEST);
+            testDd5( 7, SECS_RACE_TEST);
+            testDd5(10, SECS_RACE_TEST);
+            testDd5(15, SECS_RACE_TEST);
+            testDd5(30, SECS_RACE_TEST);
+
+            testDd6( 2, SECS_SIMPLE_TEST);
+            testDd6( 3, SECS_SIMPLE_TEST);
+            testDd6( 7, SECS_SIMPLE_TEST);
+            testDd6(10, SECS_SIMPLE_TEST);
+            testDd6(15, SECS_SIMPLE_TEST);
+            testDd6(30, SECS_SIMPLE_TEST);
+
+            testDd7( 2, SECS_SIMPLE_TEST);
+            testDd7( 3, SECS_SIMPLE_TEST);
+            testDd7( 7, SECS_SIMPLE_TEST);
+            testDd7(10, SECS_SIMPLE_TEST);
+            testDd7(15, SECS_SIMPLE_TEST);
+            testDd7(30, SECS_SIMPLE_TEST);
+        }
     }
 
