RFC: Assert on probable deadlocks if the second lock isnt try_lock #5515

pull TheBlueMatt wants to merge 1 commits into bitcoin:master from TheBlueMatt:probable_assert changing 1 files +39 −10
  1. TheBlueMatt commented at 10:48 AM on December 20, 2014: member

    Just for travis

  2. TheBlueMatt force-pushed on Dec 20, 2014
  3. TheBlueMatt renamed this:
    TRAVIS_TEST: Assert on probable deadlocks if the second lock isnt try_lock
    RFC: Assert on probable deadlocks if the second lock isnt try_lock
    on Dec 20, 2014
  4. TheBlueMatt commented at 9:15 PM on December 20, 2014: member

    Since travis passes, I figured we might actually consider this...essentially, it asserts that we dont have deadlocks assuming: (a) no locking-conditions are based on data other than the current set of locked locks and (b) if we do a TRY_LOCK, and it fails, we will immediately bail out and just skip that section of code. Since DEBUG_LOCKORDER is pretty much travis-only, if it might crash in cases that regular bitcoind might not, I dont really mind.

  5. TheBlueMatt commented at 9:16 PM on December 20, 2014: member

    Mostly, the DEBUG_LOCKORDER warnings arent even shown by travis anymore (they're just hidden behind the debug.log, so the only thing that flag does is check the lock assertions), so I figure we should have some semi-automated screeching if common-path code has lock inversions.

  6. laanwj added the label Tests on Jan 8, 2015
  7. laanwj added the label Improvement on Jan 8, 2015
  8. laanwj commented at 12:00 PM on April 1, 2015: member

    Concept ACK, but this makes the deadlock detection code kind of complex. I can't immediately see whether it's correct or wrong.

  9. gavinandresen commented at 2:19 PM on April 1, 2015: contributor

    Hmmm....

    Would this work instead? Modify sync.h CMutexLock::TryEnter to only call EnterCritical() if the lock is successfully acquired?

        bool TryEnter(const char* pszName, const char* pszFile, int nLine)
        {
            lock.try_lock();
            if (lock.owns_lock()
                  EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
            return lock.owns_lock();
        }
    

    (or, in other words: just ignore TRY_LOCKS that don't acquire the lock)

  10. TheBlueMatt commented at 5:30 PM on April 3, 2015: member

    @gavinandresen No, because often you see warnings because you have a lock(B) followed by a try_lock(A) and a lock(A) followed by a lock(B) at different times, you'll get a warning, but your suggestion would ignore it because you didnt actually see a deadlock.

    Also, you cant just ignore try_locks entirely because it is very easy to create a deadlock with a try_lock.

  11. gavinandresen commented at 5:56 PM on April 3, 2015: contributor

    @TheBlueMatt : maybe I'm being dense... but:

    If we get: lock(B) then a successful (lock-acquired) try_lock(A), then the lockorders map will contain "B then A". If at any point in the future lock(A) is followed by lock(B), a warning will be triggered -- my suggestion doesn't require that there be an actual deadlock.

    I'm not suggesting that try_lock be ignored entirely....

  12. TheBlueMatt commented at 4:06 AM on April 4, 2015: member

    @gavinandresen Yes, and if a warning were triggered in that (beningn) case, then you'd see things crash on the new assert?

  13. sipa commented at 4:31 AM on April 8, 2015: member

    Haven't spent too much time thinking about this, but having (A, B) in one place and (B, try A) in another place can never cause a deadlock. I believe that the correct checking behaviour is to add any acquired lock to the table, but never do a deadlock check when entering a try_lock.

  14. TheBlueMatt commented at 1:25 PM on April 8, 2015: member

    @sipa: Consider the case A, tryB, C and C, tryB, A. This is actually not a deadlock, but if you simply skip the deadlock check for B, you'll get an error.

  15. TheBlueMatt commented at 1:26 PM on April 8, 2015: member

    IIRC, there was a similar case that I saw that prompted this pull.

  16. gavinandresen commented at 1:43 PM on April 8, 2015: contributor

    @TheBlueMatt : sorry, I WAS just being dense.

    I'm with @laanwj -- ACK on the concept, but I'm having trouble convincing myself the code is correct (I may just need more caffeine before thinking about it some more). It feels like there should be a simpler solution.

  17. sipa commented at 2:45 PM on April 8, 2015: member

    Interesting. I agree (a,try b,c),(c,try b,a)) is not a deadlock, but it is not something any code should be doing - it looks extremely fragile (remove a lock, and turn it into a deadlock). So I'd rather trigger deadlock warnings for it too.

  18. TheBlueMatt commented at 4:07 PM on April 8, 2015: member

    IIRC we (used to) do something like that. We may not anymore, but some of the network processing stuff is a mess.

    On April 8, 2015 3:46:03 PM GMT+01:00, Pieter Wuille notifications@github.com wrote:

    Interesting. I agree (a,try b,c),(c,try b,a)) is not a deadlock, but it is not something any code should be doing - it looks extremely fragile (remove a lock, and turn it into a deadlock). So I'd rather trigger deadlock warnings for it too.


    Reply to this email directly or view it on GitHub: #5515 (comment)

  19. Assert on probable deadlocks if the second lock isnt try_lock 0fcc4e1e04
  20. TheBlueMatt force-pushed on Jul 22, 2015
  21. TheBlueMatt commented at 11:53 PM on July 22, 2015: member

    @sipa checked, turns out the deadlock detection code never called potential_deadlock_detected for TRY_LOCKs so we definitely still do require the code in this pull before we can assert on deadlocks. Also rebased and added a comment so that this is more readable.

  22. laanwj merged this on Jul 23, 2015
  23. laanwj closed this on Jul 23, 2015

  24. laanwj referenced this in commit d946e9a848 on Jul 23, 2015
  25. TheBlueMatt deleted the branch on Jul 24, 2015
  26. laanwj referenced this in commit a4fe57da62 on Aug 6, 2015
  27. zkbot referenced this in commit 57d420e2f8 on Feb 15, 2017
  28. zkbot referenced this in commit 88c209dba6 on Feb 20, 2017
  29. zkbot referenced this in commit dadb1ab74c on Mar 3, 2017
  30. MarcoFalke locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-22 06:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me