Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

To be fair though: printing also will likely impact timing and can change concurrent behaviour as well.

Still agree that print debugging is more useful in such situations (and I prefer it in general).



Yes, but you can repeat your print-debug-loop once a second, maybe even faster. Hit play and look at the output. Hit play again and see if it changed. It may or may not turn up the concurrency issue.

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.


I think in this case, because everyone brings up multithreaded examples when saying a debugger isn’t useful, maybe print debugging can lead you towards the path of where to use a debugger efficiently.

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.


You can make your breakpoint conditional on the conditons you're looking for, then it'll run full speed until you hit the timing edge case.

Best of both worlds.


>printing also will likely impact timing and can change concurrent behaviour as well.

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 appended (...) traces into (...) memory. (...) An unrelated process would read (...) at opportune time and hand over to the developer.

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...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: