[Qt-interest] QMutex deadlock without using QMutex

K. Frank kfrank29.c at gmail.com
Wed Apr 28 16:25:09 CEST 2010


Hello Andre, Gabriel, & al. -

I would like to ask a question -- not entirely off topic -- mostly for my
education about useful debugging tools for these sorts of threading things.

On Wed, Apr 28, 2010 at 8:41 AM, Gabriel M. Beddingfield
<gabrbedd at gmail.com> wrote:
>
> On Wed, 28 Apr 2010, Andre Somers wrote:
>
>> I protected each of the relevant functions with a mutex...
>> deadlock continues to appear.
> ...
> I love puzzles and am very tempted to compile the code and snuggle up
> to my debugger... but my schedule won't permit it.  :-)
> ...

It's possible for a single thread to deadlock itself (if you're using a
non-recursive mutex):

   acquire_mutex (mutex_1);
   // ...
   acquire_mutex (mutex_1);  // self-deadlock

but this error is not that pernicious because the situation is fairly simple
and you're not that likely to make the error, and if you do, you're likely to
spot the error and fix it.

(And, if you have a recursive mutex, it won't deadlock, although I believe
someone (Andre?) said earlier that the relevant Qt mutex is non-recursive.)

More common and troublesome is when two (or more) threads deadlock
with one another, the classic example being:

   thread A:

   acquire_mutex (mutex_1);
   // ...
   acquire_mutex (mutex_2);  // potential deadlock

   thread B:

   acquire_mutex (mutex_2);
   // ...
   acquire_mutex (mutex_1);  // potential deadlock

In the case where (usually a race condition) thread A acquires mutex_1
before thread B attempts to acquire mutex_1, and thread B acquires
mutex_2 before thread A attempts to acquire mutex_2, you get your
classic deadlock.

If you have a bunch of threads running around acquiring various mutexes
at various times, it's not always obvious which threads are candidates for
deadlocking with one another, and debugging this situation can be difficult.
It can be very helpful to have a debugging tool that shows you both "sides"
of the deadlock.  Often, merely knowing which two threads deadlocked
with one another, and which pair of mutexes participated in the deadlock
is enough to make the logic error in the code apparent, and lead to a fix.

My question is what are good debugging tools to get this kind of information?
Obviously this is platform dependent, but for the sake of argument, what tools
are available (and how best do you use them) on linux / gcc and/or windows / vs
and/or windows / mingw?

By way of comparison java (the java virtual machine) provides an api that
will give you stack traces for all of the threads, their running /
waiting states,
and the locks they hold and are waiting to acquire.  (Thread synchronization
is "built into" java, so sometimes you get more support for this kind of
debugging "out of the box".)

Thus java would give you thread stack traces for the classic deadlock example
above that looks like something along the lines of:

   thread A:

   waiting to acquire lock mutex_2
   acquire_mutex(): line 123
   foo(): line 456
   // ...
   acquired lock mutex_1
   acquire_mutex(): line 123
   bar(): line 789
   // ...
   run(): line10

   thread B:

   waiting to acquire lock mutex_1
   acquire_mutex(): line 123
   boo(): line 654
   // ...
   acquired lock mutex_2
   acquire_mutex(): line 123
   far(): line 987
   // ...
   run(): line10

As you can imagine, these stack traces can be very informative and often
lead you directly to the bug that caused the deadlock.

Are there equivalent debugging tools for some of the various Qt platforms (or
maybe Qt-specific tools)?

Thanks.


K. Frank




More information about the Qt-interest-old mailing list