Multithreading + Debugging = Difficulties

Let's assume that you decided to go multithread, I told you to choose a simple implementation but you decided to go the hard way: As a real programmer, you preferred the long and complex implementation

With bad luck, loads of colleagues and many work on your project: entropy helps and it is now a big mess…

And of course, things go wrong, it is surely one of the following :

  1. the program crash accessing a shared structure
  2. the program is frozen (dead lock)
  3. the program is not really frozen, but never do what it is supposed to do

And even more funny, it does not crash all the time, it sometimes crashes, it can crash in an hour, it can crash in few hours

Wtf ? How can I make sure that my program is 100% bug free

Err, unless you resort to model checking, you cant predict easily if, in every execution, in every possible state, your program verify some predicates (like it will terminate)

I presume that you don't have the material time to add: "Understand Model Checking" + "Conceptualize the system" + "Encode the concept and run the model checker (and pray it does not run out of memory or it executes for years)" to your task list…

If the program crash while manipulating structures shared among threads…

When it crash, you can see which structure was inconsistent. If not, try to trace back to the source of error.
It is a strong spot that the program lack mutual exclusion over this code/structure.

Isolate components: make sure that individually they work correct

This is a golden rule, if you can, try to isolate a component and then run tests over it. Make a small application that use the component in it's ideal situation and then start to stress test it.

Make trace of your program execution

Okay, log every action in the selected order. Particularly, log every mutex request/acquire/release. This is very helpful for detecting dead locks.

But there's a performance drawback of logging, your logging procedure might use a Mutex (OutputDebugString in example uses a Mutex) which can overkill performances. Make sure you can disable logging easily so they do not even show up in the compiled code.

Known technique: Avoid acquisition of multiple resources at the same time

Does your application need threads that allocate many mutexes/locks/anything ?
Most of the time, it just need to quickly write on a structure then continue its processing.

Then limits your application to one mutual exclusion at a time.

Known technique II: If you really need to allocate multiple resources, give numbers to each resources and allocates them in incremental order

This was called "Avender" technique at University… I could not find back the article describing it but it is proven that any system working on this predicate will *always* avoid deadlocks

And finally, yes there exists even more advanced techniques that detect/avoid deadlocks

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License