I myself mostly do it the old-fashionable way: gdb, debugging printfs, and as a more recent thing valgrind. :-) Some debugging techniques are mentioned in the book, such as the versions of libraries with deadlock detections, lock hierarchies and such.
Another technique that I've found useful when the debugging printouts are too slow and alter the program execution logic a lot is to have in-memory buffers where the debugging information can be written fast, without upsetting the timing, and then read later after the problem has occured. A sort of a "black box" trace for the program that can be used to restore the sequence of events. And for debugging it gets useful to add the artificial delays in the suspicious places, and then hammering the program with a stress test.
I haven't looked that much at the static analyzers, and what I've seen did not make a particularly big impression.