VirtualBox

Ignore:
Timestamp:
Jan 8, 2010 1:20:15 PM (15 years ago)
Author:
vboxsync
Message:

iprt/lockvalidator: Record recursion on the lock stack.

Location:
trunk/src/VBox/Runtime/common/misc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp

    r25689 r25690  
    194194
    195195/** The max value for RTLOCKVALCLASSINT::cRefs. */
    196 #define RTLOCKVALCLASS_MAX_REFS             UINT32_C(0xffff0000)
     196#define RTLOCKVALCLASS_MAX_REFS                 UINT32_C(0xffff0000)
    197197/** The max value for RTLOCKVALCLASSREF::cLookups. */
    198 #define RTLOCKVALCLASSREF_MAX_LOOKUPS       UINT32_C(0xfffe0000)
     198#define RTLOCKVALCLASSREF_MAX_LOOKUPS           UINT32_C(0xfffe0000)
    199199/** The absolute max value for RTLOCKVALCLASSREF::cLookups at which it will
    200200 *  be set back to RTLOCKVALCLASSREF_MAX_LOOKUPS. */
    201 #define RTLOCKVALCLASSREF_MAX_LOOKUPS_FIX   UINT32_C(0xffff0000)
     201#define RTLOCKVALCLASSREF_MAX_LOOKUPS_FIX       UINT32_C(0xffff0000)
     202
     203
     204/** @def RTLOCKVAL_WITH_RECURSION_RECORDS
     205 *  Enable recursion records.  */
     206#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
     207# define RTLOCKVAL_WITH_RECURSION_RECORDS  1
     208#endif
     209
     210/** @def RTLOCKVAL_WITH_VERBOSE_DUMPS
     211 * Enables some extra verbosity in the lock dumping.  */
     212#if defined(DOXYGEN_RUNNING)
     213# define RTLOCKVAL_WITH_VERBOSE_DUMPS
     214#endif
    202215
    203216
     
    359372
    360373/**
     374 * Helper for rtLockValComplainAboutLock.
     375 */
     376DECL_FORCE_INLINE(void) rtLockValComplainAboutLockHlp(const char *pszPrefix, PRTLOCKVALRECUNION pRec, const char *pszSuffix,
     377                                                      uint32_t u32Magic, PCRTLOCKVALSRCPOS pSrcPos, uint32_t cRecursion,
     378                                                      const char *pszSuffix2)
     379{
     380    switch (u32Magic)
     381    {
     382        case RTLOCKVALRECEXCL_MAGIC:
     383#ifdef RTLOCKVAL_WITH_VERBOSE_DUMPS
     384            RTAssertMsg2AddWeak("%s%p %s xrec=%p own=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix,
     385                                pRec->Excl.hLock, pRec->Excl.pszName, pRec,
     386                                rtLockValidatorNameThreadHandle(&pRec->Excl.hThread), cRecursion,
     387                                pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId,
     388                                pszSuffix2, pszSuffix);
     389#else
     390            RTAssertMsg2AddWeak("%s%p %s own=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix,
     391                                pRec->Excl.hLock, pRec->Excl.pszName,
     392                                rtLockValidatorNameThreadHandle(&pRec->Excl.hThread), cRecursion,
     393                                pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId,
     394                                pszSuffix2, pszSuffix);
     395#endif
     396            break;
     397
     398        case RTLOCKVALRECSHRD_MAGIC:
     399            RTAssertMsg2AddWeak("%s%p %s srec=%p%s", pszPrefix,
     400                                pRec->Shared.hLock, pRec->Shared.pszName, pRec,
     401                                pszSuffix);
     402            break;
     403
     404        case RTLOCKVALRECSHRDOWN_MAGIC:
     405        {
     406            PRTLOCKVALRECSHRD pShared = pRec->ShrdOwner.pSharedRec;
     407            if (    VALID_PTR(pShared)
     408                &&  pShared->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC)
     409#ifdef RTLOCKVAL_WITH_VERBOSE_DUMPS
     410                RTAssertMsg2AddWeak("%s%p %s srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix,
     411                                    pShared->hLock, pShared->pszName, pShared,
     412                                    pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), cRecursion,
     413                                    pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId,
     414                                    pszSuffix2, pszSuffix);
     415#else
     416                RTAssertMsg2AddWeak("%s%p %s thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix,
     417                                    pShared->hLock, pShared->pszName,
     418                                    rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), cRecursion,
     419                                    pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId,
     420                                    pszSuffix2, pszSuffix);
     421#endif
     422            else
     423                RTAssertMsg2AddWeak("%sbad srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix,
     424                                    pShared,
     425                                    pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), cRecursion,
     426                                    pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId,
     427                                    pszSuffix2, pszSuffix);
     428            break;
     429        }
     430
     431        default:
     432            AssertMsgFailed(("%#x\n", u32Magic));
     433    }
     434}
     435
     436
     437/**
    361438 * Describes the lock.
    362439 *
     
    373450        {
    374451            case RTLOCKVALRECEXCL_MAGIC:
    375                 RTAssertMsg2AddWeak("%s%p %s xrec=%p own=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix,
    376                                     pRec->Excl.hLock, pRec->Excl.pszName, pRec,
    377                                     rtLockValidatorNameThreadHandle(&pRec->Excl.hThread), pRec->Excl.cRecursion,
    378                                     pRec->Excl.SrcPos.pszFile, pRec->Excl.SrcPos.uLine, pRec->Excl.SrcPos.pszFunction, pRec->Excl.SrcPos.uId,
    379                                     pszSuffix);
     452                rtLockValComplainAboutLockHlp(pszPrefix, pRec, pszSuffix, RTLOCKVALRECEXCL_MAGIC,
     453                                              &pRec->Excl.SrcPos, pRec->Excl.cRecursion, "");
    380454                break;
    381455
    382456            case RTLOCKVALRECSHRD_MAGIC:
    383                 RTAssertMsg2AddWeak("%s%p %s srec=%p%s", pszPrefix,
    384                                     pRec->Shared.hLock, pRec->Shared.pszName, pRec,
    385                                     pszSuffix);
     457                rtLockValComplainAboutLockHlp(pszPrefix, pRec, pszSuffix, RTLOCKVALRECSHRD_MAGIC, NULL, 0, "");
    386458                break;
    387459
    388460            case RTLOCKVALRECSHRDOWN_MAGIC:
     461                rtLockValComplainAboutLockHlp(pszPrefix, pRec, pszSuffix, RTLOCKVALRECSHRDOWN_MAGIC,
     462                                              &pRec->ShrdOwner.SrcPos, pRec->ShrdOwner.cRecursion, "");
     463                break;
     464
     465            case RTLOCKVALRECNEST_MAGIC:
    389466            {
    390                 PRTLOCKVALRECSHRD pShared = pRec->ShrdOwner.pSharedRec;
    391                 if (    VALID_PTR(pShared)
    392                     &&  pShared->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC)
    393                     RTAssertMsg2AddWeak("%s%p %s srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix,
    394                                         pShared->hLock, pShared->pszName, pShared,
    395                                         pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), pRec->ShrdOwner.cRecursion,
    396                                         pRec->ShrdOwner.SrcPos.pszFile, pRec->ShrdOwner.SrcPos.uLine, pRec->ShrdOwner.SrcPos.pszFunction, pRec->ShrdOwner.SrcPos.uId,
    397                                         pszSuffix);
     467                PRTLOCKVALRECUNION  pRealRec = pRec->Nest.pRec;
     468                uint32_t            u32Magic;
     469                if (   VALID_PTR(pRealRec)
     470                    && (   (u32Magic = pRealRec->Core.u32Magic) == RTLOCKVALRECEXCL_MAGIC
     471                        || u32Magic == RTLOCKVALRECSHRD_MAGIC
     472                        || u32Magic == RTLOCKVALRECSHRDOWN_MAGIC)
     473                    )
     474                    rtLockValComplainAboutLockHlp(pszPrefix, pRealRec, pszSuffix, u32Magic,
     475                                                  &pRec->Nest.SrcPos, pRec->Nest.cRecursion, " [recursion]");
    398476                else
    399                     RTAssertMsg2AddWeak("%sbad srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix,
    400                                         pShared,
    401                                         pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), pRec->ShrdOwner.cRecursion,
    402                                         pRec->ShrdOwner.SrcPos.pszFile, pRec->ShrdOwner.SrcPos.uLine, pRec->ShrdOwner.SrcPos.pszFunction, pRec->ShrdOwner.SrcPos.uId,
     477                    RTAssertMsg2AddWeak("%sbad rrec=%p nrec=%p nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix,
     478                                        pRealRec, pRec, pRec->Nest.cRecursion,
     479                                        pRec->Nest.SrcPos.pszFile, pRec->Nest.SrcPos.uLine, pRec->Nest.SrcPos.pszFunction, pRec->Nest.SrcPos.uId,
    403480                                        pszSuffix);
    404481                break;
     
    431508        if (cEntries >= cMinFrames)
    432509        {
    433             RTAssertMsg2AddWeak("%*s---- start of lock stack - %u entr%s ----\n", cchIndent, "", cEntries,
    434                                 cEntries == 1 ? "y" : "ies");
     510            RTAssertMsg2AddWeak("%*s---- start of lock stack for %p %s - %u entr%s ----\n", cchIndent, "",
     511                                pThread, pThread->szName, cEntries, cEntries == 1 ? "y" : "ies");
    435512            PRTLOCKVALRECUNION pCur = rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pStackTop);
    436             for (uint32_t i = 0; pCur; i++)
     513            for (uint32_t i = 0; VALID_PTR(pCur); i++)
    437514            {
    438515                char szPrefix[80];
     
    443520                    case RTLOCKVALRECEXCL_MAGIC:    pCur = rtLockValidatorReadRecUnionPtr(&pCur->Excl.pDown);      break;
    444521                    case RTLOCKVALRECSHRDOWN_MAGIC: pCur = rtLockValidatorReadRecUnionPtr(&pCur->ShrdOwner.pDown); break;
     522                    case RTLOCKVALRECNEST_MAGIC:    pCur = rtLockValidatorReadRecUnionPtr(&pCur->Nest.pDown);      break;
    445523                    default:
    446524                        RTAssertMsg2AddWeak("%*s<bad stack frame>\n", cchIndent, "");
     
    690768    Assert(pPerThread->fInValidator == false);
    691769    Assert(pPerThread->pStackTop == NULL);
     770}
     771
     772
     773/**
     774 * Delete the per thread lock validator data.
     775 *
     776 * @param   pPerThread      The data.
     777 */
     778DECLHIDDEN(void) rtLockValidatorDeletePerThread(RTLOCKVALPERTHREAD *pPerThread)
     779{
     780    /*
     781     * Check that the thread doesn't own any locks at this time.
     782     */
     783    if (pPerThread->pStackTop)
     784    {
     785        rtLockValComplainFirst("Thread terminating owning locks!", NULL,
     786                               RT_FROM_MEMBER(pPerThread, RTTHREADINT, LockValidator),
     787                               pPerThread->pStackTop);
     788        rtLockValComplainPanic();
     789    }
     790
     791    /*
     792     * Free the recursion records.
     793     */
     794    PRTLOCKVALRECNEST pCur = pPerThread->pFreeNestRecs;
     795    pPerThread->pFreeNestRecs = NULL;
     796    while (pCur)
     797    {
     798        PRTLOCKVALRECNEST pNext = pCur->pNextFree;
     799        RTMemFree(pNext);
     800        pCur = pNext;
     801    }
    692802}
    693803
     
    10841194    uint32_t            cEntries = 0;
    10851195    PRTLOCKVALRECUNION  pCur = rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pStackTop);
    1086     while (pCur)
     1196    while (VALID_PTR(pCur))
    10871197    {
    10881198        switch (pCur->Core.u32Magic)
     
    10961206                break;
    10971207
     1208            case RTLOCKVALRECNEST_MAGIC:
     1209                pCur = rtLockValidatorReadRecUnionPtr(&pCur->Nest.pDown);
     1210                break;
     1211
    10981212            default:
    10991213                AssertMsgFailedReturn(("%#x\n", pCur->Core.u32Magic), cEntries);
     
    11171231    while (pCur)
    11181232    {
     1233        AssertPtrReturn(pCur, false);
     1234        if (pCur == pRec)
     1235            return true;
    11191236        switch (pCur->Core.u32Magic)
    11201237        {
    11211238            case RTLOCKVALRECEXCL_MAGIC:
    11221239                Assert(pRec->Excl.cRecursion >= 1);
    1123                 if (pCur->Excl.pDown == pRec)
    1124                     return true;
    11251240                pCur = pCur->Excl.pDown;
    11261241                break;
     
    11281243            case RTLOCKVALRECSHRDOWN_MAGIC:
    11291244                Assert(pCur->ShrdOwner.cRecursion >= 1);
    1130                 if (pCur->ShrdOwner.pDown == pRec)
    1131                     return true;
    11321245                pCur = pCur->ShrdOwner.pDown;
    11331246                break;
    11341247
     1248            case RTLOCKVALRECNEST_MAGIC:
     1249                Assert(pCur->Nest.cRecursion > 1);
     1250                pCur = pCur->Nest.pDown;
     1251                break;
     1252
    11351253            default:
    11361254                AssertMsgFailedReturn(("%#x\n", pCur->Core.u32Magic), false);
     
    11421260
    11431261/**
    1144  * Pushes a lock onto the stack.
     1262 * Pushes a lock record onto the stack.
    11451263 *
    11461264 * @param   pThreadSelf         The current thread.
     
    11571275            Assert(pRec->Excl.cRecursion == 1);
    11581276            Assert(pRec->Excl.pDown == NULL);
    1159             pRec->Excl.pDown = pThreadSelf->LockValidator.pStackTop;
     1277            rtLockValidatorWriteRecUnionPtr(&pRec->Excl.pDown, pThreadSelf->LockValidator.pStackTop);
    11601278            break;
    11611279
     
    11631281            Assert(pRec->ShrdOwner.cRecursion == 1);
    11641282            Assert(pRec->ShrdOwner.pDown == NULL);
    1165             pRec->ShrdOwner.pDown = pThreadSelf->LockValidator.pStackTop;
     1283            rtLockValidatorWriteRecUnionPtr(&pRec->ShrdOwner.pDown, pThreadSelf->LockValidator.pStackTop);
    11661284            break;
    11671285
    1168         case RTLOCKVALRECSHRD_MAGIC:
    11691286        default:
    11701287            AssertMsgFailedReturnVoid(("%#x\n",  pRec->Core.u32Magic));
    11711288    }
    1172     pThreadSelf->LockValidator.pStackTop = pRec;
    1173 }
    1174 
    1175 
    1176 /**
    1177  * Pops a lock off the stack.
     1289    rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, pRec);
     1290}
     1291
     1292
     1293/**
     1294 * Pops a lock record off the stack.
    11781295 *
    11791296 * @param   pThreadSelf         The current thread.
     
    11901307            Assert(pRec->Excl.cRecursion == 0);
    11911308            pDown = pRec->Excl.pDown;
    1192             pRec->Excl.pDown = NULL;
     1309            rtLockValidatorWriteRecUnionPtr(&pRec->Excl.pDown, NULL); /* lazy bird */
    11931310            break;
    11941311
     
    11961313            Assert(pRec->ShrdOwner.cRecursion == 0);
    11971314            pDown = pRec->ShrdOwner.pDown;
    1198             pRec->ShrdOwner.pDown = NULL;
     1315            rtLockValidatorWriteRecUnionPtr(&pRec->ShrdOwner.pDown, NULL);
    11991316            break;
    12001317
     
    12031320    }
    12041321    if (pThreadSelf->LockValidator.pStackTop == pRec)
    1205         pThreadSelf->LockValidator.pStackTop = pDown;
     1322        rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, pDown);
    12061323    else
    12071324    {
    1208         /* find the record on top of ours */
     1325        /* Find the record above ours. */
    12091326        PRTLOCKVALRECUNION pAbove = pThreadSelf->LockValidator.pStackTop;
    12101327        while (pAbove)
     
    12161333                    if (pAbove->Excl.pDown == pRec)
    12171334                    {
    1218                         pAbove->Excl.pDown = pDown;
     1335                        rtLockValidatorWriteRecUnionPtr(&pAbove->Excl.pDown, pDown);
    12191336                        return;
    12201337                    }
     
    12261343                    if (pAbove->ShrdOwner.pDown == pRec)
    12271344                    {
    1228                         pAbove->ShrdOwner.pDown = pDown;
     1345                        rtLockValidatorWriteRecUnionPtr(&pAbove->ShrdOwner.pDown, pDown);
    12291346                        return;
    12301347                    }
     
    12321349                    break;
    12331350
     1351                case RTLOCKVALRECNEST_MAGIC:
     1352                    Assert(pAbove->Nest.cRecursion >= 1);
     1353                    if (pAbove->Nest.pDown == pRec)
     1354                    {
     1355                        rtLockValidatorWriteRecUnionPtr(&pAbove->Nest.pDown, pDown);
     1356                        return;
     1357                    }
     1358                    pAbove = pAbove->Nest.pDown;
     1359                    break;
     1360
    12341361                default:
    12351362                    AssertMsgFailedReturnVoid(("%#x\n", pAbove->Core.u32Magic));
     
    12411368
    12421369
     1370/**
     1371 * Creates and pushes lock recursion record onto the stack.
     1372 *
     1373 * @param   pThreadSelf         The current thread.
     1374 * @param   pRec                The lock record.
     1375 * @param   pSrcPos             Where the recursion occured.
     1376 */
    12431377static void rtLockValidatorStackPushRecursion(PRTTHREADINT pThreadSelf, PRTLOCKVALRECUNION pRec, PCRTLOCKVALSRCPOS pSrcPos)
    12441378{
    12451379    Assert(pThreadSelf == RTThreadSelf());
    1246     /** @todo insert a recursion record onto the stack.  Keep a reasonally big pool
    1247      *        of them associated with each thread. */
     1380    Assert(rtLockValidatorStackContainsRec(pThreadSelf, pRec));
     1381
     1382#ifdef RTLOCKVAL_WITH_RECURSION_RECORDS
     1383    /*
     1384     * Allocate a new recursion record
     1385     */
     1386    PRTLOCKVALRECNEST pRecursionRec = pThreadSelf->LockValidator.pFreeNestRecs;
     1387    if (pRecursionRec)
     1388        pThreadSelf->LockValidator.pFreeNestRecs = pRecursionRec->pNextFree;
     1389    else
     1390    {
     1391        pRecursionRec = (PRTLOCKVALRECNEST)RTMemAlloc(sizeof(*pRecursionRec));
     1392        if (!pRecursionRec)
     1393            return;
     1394    }
     1395
     1396    /*
     1397     * Initialize it.
     1398     */
    12481399    switch (pRec->Core.u32Magic)
    12491400    {
    12501401        case RTLOCKVALRECEXCL_MAGIC:
    1251             Assert(pRec->Excl.cRecursion > 1);
     1402            pRecursionRec->cRecursion = pRec->Excl.cRecursion;
    12521403            break;
    12531404
    12541405        case RTLOCKVALRECSHRDOWN_MAGIC:
    1255             Assert(pRec->ShrdOwner.cRecursion > 1);
     1406            pRecursionRec->cRecursion = pRec->ShrdOwner.cRecursion;
    12561407            break;
    12571408
    12581409        default:
    1259             AssertMsgFailedReturnVoid(("%#x\n",  pRec->Core.u32Magic));
    1260     }
    1261 }
    1262 
    1263 
     1410            AssertMsgFailed(("%#x\n",  pRec->Core.u32Magic));
     1411            rtLockValidatorSerializeDestructEnter();
     1412            rtLockValidatorSerializeDestructLeave();
     1413            RTMemFree(pRecursionRec);
     1414            return;
     1415    }
     1416    Assert(pRecursionRec->cRecursion > 1);
     1417    pRecursionRec->pRec          = pRec;
     1418    pRecursionRec->pDown         = NULL;
     1419    pRecursionRec->pNextFree     = NULL;
     1420    rtLockValidatorSrcPosCopy(&pRecursionRec->SrcPos, pSrcPos);
     1421    pRecursionRec->Core.u32Magic = RTLOCKVALRECNEST_MAGIC;
     1422
     1423    /*
     1424     * Link it.
     1425     */
     1426    pRecursionRec->pDown = pThreadSelf->LockValidator.pStackTop;
     1427    rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, (PRTLOCKVALRECUNION)pRecursionRec);
     1428#endif /* RTLOCKVAL_WITH_RECURSION_RECORDS */
     1429}
     1430
     1431
     1432/**
     1433 * Pops a lock recursion record off the stack.
     1434 *
     1435 * @param   pThreadSelf         The current thread.
     1436 * @param   pRec                The lock record.
     1437 */
    12641438static void rtLockValidatorStackPopRecursion(PRTTHREADINT pThreadSelf, PRTLOCKVALRECUNION pRec)
    12651439{
    12661440    Assert(pThreadSelf == RTThreadSelf());
     1441    Assert(rtLockValidatorStackContainsRec(pThreadSelf, pRec));
     1442
     1443    uint32_t cRecursion;
    12671444    switch (pRec->Core.u32Magic)
    12681445    {
    1269         case RTLOCKVALRECEXCL_MAGIC:
    1270             Assert(pRec->Excl.cRecursion >= 1);
    1271             break;
    1272 
    1273         case RTLOCKVALRECSHRDOWN_MAGIC:
    1274             Assert(pRec->ShrdOwner.cRecursion >= 1);
    1275             break;
    1276 
    1277         default:
    1278             AssertMsgFailedReturnVoid(("%#x\n",  pRec->Core.u32Magic));
    1279     }
     1446        case RTLOCKVALRECEXCL_MAGIC:    cRecursion = pRec->Excl.cRecursion; break;
     1447        case RTLOCKVALRECSHRDOWN_MAGIC: cRecursion = pRec->ShrdOwner.cRecursion; break;
     1448        default:                        AssertMsgFailedReturnVoid(("%#x\n",  pRec->Core.u32Magic));
     1449    }
     1450    Assert(cRecursion >= 1);
     1451
     1452#ifdef RTLOCKVAL_WITH_RECURSION_RECORDS
     1453    /*
     1454     * Pop the recursion record.
     1455     */
     1456    PRTLOCKVALRECUNION pNest = pThreadSelf->LockValidator.pStackTop;
     1457    if (   pNest != NULL
     1458        && pNest->Core.u32Magic == RTLOCKVALRECNEST_MAGIC
     1459        && pNest->Nest.pRec == pRec
     1460       )
     1461    {
     1462        Assert(pNest->Nest.cRecursion == cRecursion + 1);
     1463        rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, pNest->Nest.pDown);
     1464    }
     1465    else
     1466    {
     1467        /* Find the record above ours. */
     1468        PRTLOCKVALRECUNION pAbove = NULL;
     1469        while (pNest)
     1470        {
     1471            switch (pNest->Core.u32Magic)
     1472            {
     1473                case RTLOCKVALRECEXCL_MAGIC:
     1474                    pAbove  = pNest;
     1475                    pNest   = pNest->Excl.pDown;
     1476                    break;
     1477                case RTLOCKVALRECSHRDOWN_MAGIC:
     1478                    pAbove  = pNest;
     1479                    pNest   = pNest->ShrdOwner.pDown;
     1480                    break;
     1481                case RTLOCKVALRECNEST_MAGIC:
     1482                    if (pNest->Nest.pRec == pRec)
     1483                    {
     1484                        pNest = pNest;
     1485                        break;
     1486                    }
     1487                    pAbove  = pNest;
     1488                    pNest   = pNest->Nest.pDown;
     1489                    break;
     1490                default:
     1491                    AssertMsgFailedReturnVoid(("%#x\n", pNest->Core.u32Magic));
     1492            }
     1493        }
     1494        AssertMsg(pNest, ("%p %p\n", pRec, pThreadSelf));
     1495        AssertMsg(pAbove, ("%p %p\n", pRec, pThreadSelf));
     1496        Assert(pNest->Nest.cRecursion == cRecursion + 1);
     1497        switch (pAbove->Core.u32Magic)
     1498        {
     1499            case RTLOCKVALRECEXCL_MAGIC:
     1500                rtLockValidatorWriteRecUnionPtr(&pNest->Excl.pDown, pNest->Nest.pDown);
     1501                break;
     1502            case RTLOCKVALRECSHRDOWN_MAGIC:
     1503                rtLockValidatorWriteRecUnionPtr(&pNest->ShrdOwner.pDown, pNest->Nest.pDown);
     1504                break;
     1505            case RTLOCKVALRECNEST_MAGIC:
     1506                rtLockValidatorWriteRecUnionPtr(&pNest->Nest.pDown, pNest->Nest.pDown);
     1507                break;
     1508            default:
     1509                AssertMsgFailedReturnVoid(("%#x\n", pNest->Core.u32Magic));
     1510        }
     1511    }
     1512
     1513    /*
     1514     * Invalidate and free the record.
     1515     */
     1516    ASMAtomicWriteU32(&pNest->Core.u32Magic, RTLOCKVALRECNEST_MAGIC);
     1517    rtLockValidatorWriteRecUnionPtr(&pNest->Nest.pDown, NULL);
     1518    rtLockValidatorWriteRecUnionPtr(&pNest->Nest.pRec, NULL);
     1519    pNest->Nest.cRecursion = 0;
     1520    pNest->Nest.pNextFree  = pThreadSelf->LockValidator.pFreeNestRecs;
     1521    pThreadSelf->LockValidator.pFreeNestRecs = &pNest->Nest;
     1522#endif /* RTLOCKVAL_WITH_RECURSION_RECORDS */
    12801523}
    12811524
     
    17021945                pShrdOwner = pStack->a[i].pRec->Shared.papOwners[pStack->a[i].iEntry];
    17031946            if (VALID_PTR(pShrdOwner) && pShrdOwner->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC)
     1947            {
    17041948                rtLockValComplainAboutLock(szPrefix, (PRTLOCKVALRECUNION)pShrdOwner, "\n");
     1949                rtLockValComplainAboutLockStack(pShrdOwner->hThread, 5, 2);
     1950            }
    17051951            else
     1952            {
    17061953                rtLockValComplainAboutLock(szPrefix, pStack->a[i].pRec, "\n");
     1954                if (pStack->a[i].pRec->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC);
     1955                    rtLockValComplainAboutLockStack(pStack->a[i].pRec->Excl.hThread, 5, 2);
     1956            }
    17071957        }
    17081958        rtLockValComplainMore("---- end of deadlock chain ----\n");
     
    18522102        case RTLOCKVALRECSHRDOWN_MAGIC:
    18532103            return pRec->ShrdOwner.pSharedRec ? pRec->ShrdOwner.pSharedRec->pszName : "orphaned";
     2104        case RTLOCKVALRECNEST_MAGIC:
     2105            pRec = rtLockValidatorReadRecUnionPtr(&pRec->Nest.pRec);
     2106            if (VALID_PTR(pRec))
     2107            {
     2108                switch (pRec->Core.u32Magic)
     2109                {
     2110                    case RTLOCKVALRECEXCL_MAGIC:
     2111                        return pRec->Excl.pszName;
     2112                    case RTLOCKVALRECSHRD_MAGIC:
     2113                        return pRec->Shared.pszName;
     2114                    case RTLOCKVALRECSHRDOWN_MAGIC:
     2115                        return pRec->ShrdOwner.pSharedRec ? pRec->ShrdOwner.pSharedRec->pszName : "orphaned";
     2116                    default:
     2117                        return "unknown-nested";
     2118                }
     2119            }
     2120            return "orphaned-nested";
    18542121        default:
    18552122            return "unknown";
     
    20172284        && !pRecU->Excl.hClass->fRecursionOk)
    20182285    {
    2019         rtLockValComplainFirst("Recursion not allowed by the class",
    2020                                      pSrcPos, pRecU->Excl.hThread, (PRTLOCKVALRECUNION)pRec);
     2286        rtLockValComplainFirst("Recursion not allowed by the class!",
     2287                               pSrcPos, pRecU->Excl.hThread, (PRTLOCKVALRECUNION)pRec);
    20212288        rtLockValComplainPanic();
    20222289        return VERR_SEM_LV_NESTED;
     
    20612328        && !pRecU->Excl.hClass->fRecursionOk)
    20622329    {
    2063         rtLockValComplainFirst("Mixed recursion not allowed by the class",
    2064                                      pSrcPos, pRecU->Excl.hThread, (PRTLOCKVALRECUNION)pRec);
     2330        rtLockValComplainFirst("Mixed recursion not allowed by the class!",
     2331                               pSrcPos, pRecU->Excl.hThread, (PRTLOCKVALRECUNION)pRec);
    20652332        rtLockValComplainPanic();
    20662333        return VERR_SEM_LV_NESTED;
     
    21602427                && !pRecU->Excl.hClass->fRecursionOk))
    21612428        {
    2162             rtLockValComplainFirst("Recursion not allowed", pSrcPos, pThreadSelf, pRecU);
     2429            rtLockValComplainFirst("Recursion not allowed!", pSrcPos, pThreadSelf, pRecU);
    21632430            rtLockValComplainPanic();
    21642431            rc = VERR_SEM_LV_NESTED;
     
    23692636            )
    23702637        {
    2371             rtLockValComplainFirst("Recursion not allowed", pSrcPos, pThreadSelf, pRecU);
     2638            rtLockValComplainFirst("Recursion not allowed!", pSrcPos, pThreadSelf, pRecU);
    23722639            rtLockValComplainPanic();
    23732640            rc =  VERR_SEM_LV_NESTED;
     
    28093076    if (RT_UNLIKELY(!pEntry))
    28103077    {
    2811         rtLockValComplainFirst("Not owner (shared)", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);
     3078        rtLockValComplainFirst("Not owner (shared)!", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);
    28123079        rtLockValComplainPanic();
    28133080        return VERR_SEM_LV_NOT_OWNER;
     
    28623129    if (RT_UNLIKELY(!pEntry))
    28633130    {
    2864         rtLockValComplainFirst("Invalid signaller", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);
     3131        rtLockValComplainFirst("Invalid signaller!", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);
    28653132        rtLockValComplainPanic();
    28663133        return VERR_SEM_LV_NOT_SIGNALLER;
  • trunk/src/VBox/Runtime/common/misc/thread.cpp

    r25660 r25690  
    577577#ifdef IN_RING3
    578578    rtLockValidatorSerializeDestructEnter();
     579
     580    rtLockValidatorDeletePerThread(&pThread->LockValidator);
    579581#endif
    580 
    581582    ASMAtomicXchgU32(&pThread->u32Magic, RTTHREADINT_MAGIC_DEAD);
    582583    ASMAtomicWritePtr(&pThread->Core.Key, (void *)NIL_RTTHREAD);
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