Bug 259513 - hang/deadlock when enabling background parser
Summary: hang/deadlock when enabling background parser
Status: RESOLVED DUPLICATE of bug 252659
Alias: None
Product: kdevelop
Classification: Applications
Component: Language Support: CPP (old) (show other bugs)
Version: git master
Platform: Compiled Sources macOS
: NOR normal
Target Milestone: 4.2.0
Assignee: kdevelop-bugs-null
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-11 12:55 UTC by Till Adam
Modified: 2013-03-31 00:57 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
handle tryLock returning false with the lock held (2.97 KB, patch)
2010-12-13 08:58 UTC, Till Adam
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Till Adam 2010-12-11 12:55:02 UTC
Version:           SVN (using Devel) 
OS:                OS X

I'm running master on OSX, and when I enable the background parser on kdelibs as the project, the main thread seems to get stuck here:

(gdb) bt
#0  0x00007fff8459afca in __semwait_signal ()
#1  0x00007fff8459ede1 in _pthread_cond_wait ()
#2  0x000000010327317b in QMutexPrivate::wait ()
#3  0x0000000103270e8f in QMutex::lock ()
#4  0x000000010063c4cb in (anonymous namespace)::lockForegroundMutexInternal () at /Users/till/k/kde/src/kdevplatform/interfaces/foregroundlock.cpp:100
#5  0x000000010063ca52 in KDevelop::ForegroundLock::relock () at /Users/till/k/kde/src/kdevplatform/interfaces/foregroundlock.cpp:150
#6  0x000000010063ce88 in KDevelop::ForegroundLock::ForegroundLock (this=0x7fff5fbfba4f, lock=true) at /Users/till/k/kde/src/kdevplatform/interfaces/foregroundlock.cpp:141

The DU chain thread sits in:

(gdb) bt
#0  0x00007fff8459afca in __semwait_signal ()
#1  0x00007fff8459ede1 in _pthread_cond_wait ()
#2  0x00000001032738c0 in QWaitCondition::wait ()
#3  0x0000000103271277 in QReadWriteLock::lockForWrite ()
#4  0x0000000101aca522 in KDevelop::DUChainPrivate::doMoreCleanup (this=0x120273330, retries=1, needLockRepository=true) at /Users/till/k/kde/src/kdevplatform/language/duchain/duchain.cpp:723
#5  0x0000000101acb93d in KDevelop::DUChainPrivate::CleanupThread::run (this=0x1202757f0) at /Users/till/k/kde/src/kdevplatform/language/duchain/duchain.cpp:295

Another thread is sitting in:

(gdb) bt
#0  0x00007fff8459afca in __semwait_signal ()
#1  0x00007fff8459ede1 in _pthread_cond_wait ()
#2  0x0000000104534616 in QTWTF::TCMalloc_PageHeap::scavengerThread ()
#3  0x0000000104534659 in QTWTF::TCMalloc_PageHeap::runScavengerThread ()

The rest appear to be select()'ing, ThreadWeaver says it's waiting for jobs.

Reproducible: Always

Steps to Reproduce:
Import cmake based project, I did it with kdepim, start background parser, wait.

Actual Results:  
Hanging application, GUI thread frozen.

Expected Results:  
Background parsing should proceed, GUI should remain reponsive.
Comment 1 Milian Wolff 2010-12-11 16:42:53 UTC

*** This bug has been marked as a duplicate of bug 252659 ***
Comment 2 David Nolden 2010-12-11 19:10:54 UTC
Please use the debugger to print the "recursion" and "holderThread" parameters in foregroundlock.cpp.

This maybe not a duplicate, but some mac-specific problem in the way ForegroundLock is integrated into KDevelop (maybe the event-processing is done differently there).
Comment 3 Till Adam 2010-12-12 12:37:26 UTC
Things seem to end up in a state where the internalMutex is held by some thread, but the holderThread is 0, as is recursion. I'm plastering things with a few more asserts, as this clearly means some assumptions are being violated somewhere along the way.
Comment 4 David Nolden 2010-12-12 16:03:30 UTC
Well, look at lockInternalMutex, unlockInternalMutex, and relockInternalMutex. Those should contain enough assertions to make sure what you told doesn't happen..

Maybe it _is_ the same problem as on linux after all. Try enabling the pthread mutex, by replacing the "#if defined(USE_PTHREAD_MUTEX) && defined(Q_OS_LINUX)" with "#if defined(USE_PTHREAD_MUTEX)" in foregroundlock.cpp.
Comment 5 Till Adam 2010-12-13 08:56:34 UTC
Apparently QMutex::tryLock behaves unexpectedly in that it can return false, indicating that the try timed out, yet the lock has actually been acquired. This is the only way that I can see getting into the scenario that debugging shows, where the holderThread is 0, but attempting to acquire the lock fails. I'm attaching a patch which seems to work around the issue successfully here. It also uses QAtomicInt and QAtomicPointer, for a little bit more safety.
Comment 6 Till Adam 2010-12-13 08:58:31 UTC
Created attachment 54485 [details]
handle tryLock returning false with the lock held
Comment 7 David Nolden 2010-12-13 14:24:13 UTC
Ok. The workaround isn't safe, maybe it would be if it used something like QAtomic::testAndSet(..) instead of the if(holderThread == 0).

Anyway that would kind-of mean we're implementing our own mutex, which we don't want to. If it's true that tryLock can return true even the the lock was successful, then this is a big fat Qt bug. The only feasible workaround is using another mutex implementation for now (maybe from boost::threading).
Comment 8 David Nolden 2010-12-13 17:26:10 UTC
Oh sorry, actually I was doing the test with the pthread mutex enabled. :-)
Comment 9 David Nolden 2010-12-13 18:18:11 UTC
The last message was supposed for bug 252659.

*** This bug has been marked as a duplicate of bug 252659 ***
Comment 10 Aleix Pol 2013-03-31 00:57:34 UTC
Moving all the bugs from the CPP Parser. It was not well defined the difference between it and C++ Language Support and people kept reporting in both places indistinctively