Still agree that print debugging is more useful in such situations (and I prefer it in general).
Still agree that print debugging is more useful in such situations (and I prefer it in general).
Stepping through with a debugger will take you at least a minute per cycle, won't turn up the concurrency issue, and will spend a great deal of your daily concentration budget.
Best of both worlds.
I personally think if you can’t use a debugger in a multithreaded codebase, the architecture is bad or one doesn’t understand the code. So yeah, full circle, if print debugging helps one learn the code better, that is only a positive.
I’m so amused about how debuggers have become a debate around here. “Printf vs debugger” is like “emacs vs vi” right now, and it really shouldn’t be. Sometimes I put a breakpoint AT my printf statement.
I've had a bug like that and the intuitive way to handle it turned out to be entirely sufficient.
The bug (deep in networking stack, linux kernel on embedded device) was timing sensitive enough that printk() introduced unsuitable shifts. Instead I appended single-character traces into pre-allocated ring buffer memory. The overhead was down to one memory read and two memory writes, plus associated TLB misses if any; not even a function call. Very little infra was needed, and the naive, intuitive implementation sufficed.
An unrelated process would read the ring buffer (exposed as /proc/ file) at opportune time and hand over to the developer.
tl;dr know which steps introduce significant processing, timing delays, or synchronization events and push them out of critical path
I did something similar to debug concurrent treatments in Java, that allows to accumulate log statements in thread-local or instance-local collections and then publish them with possibly just a lazySet():
https://github.com/jeffhain/jolikit/blob/master/src/main/jav...