- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Set the flag to make the world explode! Fun, fun, fun...
Admin
It took some time for me to find out that System.Diagnostics.Debugger.Break() is for C# what a simple Stop is for VB.NET .
Admin
Sometimes though, you want to do something like:
So you only call that expensive step if you really have to.
Admin
Sometimes though, you want to do something like:
So you only call that expensive step if you really have to.
Admin
Just use #define to create a macro that hides the extra layer of
if()
in there...Oh. Wait. If you're not using a language with a proper macro preprocessor, then you'll have to lump it.
Addendum 2022-07-13 07:44: But equally, that's not really the WTF in Remy's complaint. The real WTF, in my opinion, is displaying the message by printf() or similar.
Admin
Bingo. If you have to do some expensive string formatting (like, say, formatting a massive byte array into hex characters) in your Log.debug() call, you will really appreciate having a quick if-check disabling that in production so your app doesn't get brought to it's knees doing work that the logging framework cheerfully throws out.
No, this has never happened to me, why do you ask?
Admin
You forget to set isPost to false before posting for a secnod time.
Admin
Hard to make the argument that C (and C++, and other child languages) have a "proper macro preprocessor." But YMMV.
Admin
I'll disagree with Remy here. I haven't yet found an acceptable "logging framework" -- perhaps I should look harder. And such frameworks as I have found tend to be easy to use (with some sort of logging hierarchy implied) but difficult to use in a meaningful way (because nobody can quite figure out a consistent use of the logging hierarchy).
And that most definitely does not look like a compile-time flag to me. It might be a debug-friendly flag. It might even be a nasty global scope flag. But a compile-time flag it is not: otherwise it would use, you know, compiler directives.
Logging is a surprisingly difficult thing to get right. Other than throwing empty base exceptions, I'm in favour of anybody trying to make their own sense out of it.
Admin
I call it a "compile time flag" because the value can't change at runtime. The flag is set at compile time. The behavior executes at runtime.
Admin
You mean a framework like the disaster known as log4j https://logging.apache.org/log4j/2.x/security.html
Admin
I take it you don't work in embedded systems that don't allow for anything else... /sigh
Admin
The one time I saw something like this in production code... it was to avoid a bug in the compiler. (Or might have been in the preprocessor. Was a good while ago.)
Fortunately there was also a comment that explained it.
Admin
I guess the exception is the rule.
Admin
All the embedded systems I ever worked on, except the TI Sensor Signal Processor, were programmed in C or C++. (There's a fuzzy line somewhere where it stops being embedded-with-a-real-OS and starts being an actual computer, but I've worked on plenty of things on the embedded side of that line.
Unless you meant the thing about "printf" or similar, which I would agree with for deep-juju embedded systems. (When it's getting into that fuzzy line, somewhere along the way "printf" becomes a WTF...)
Admin
The word "proper" in there was somewhat of a joke, of course, making fun of my comparison of programming languages based on whether they have a macro preprocessor.
Admin
I would for sure flag this code for review.
Admin
...This feels like someone wanted to stop execution to inspect variables, but didn't know what breakpoints are.
Admin
...This feels like someone wanted to stop execution to inspect variables, but didn't know what breakpoints are.
Admin
Admin
I agree with the perception in the article - one or two of these, "Whoops! How did that slip into my commit?!"; many of these, "Hi, I don't know about logging!"
Admin
That is partially what I mean, yes. Although as your link points out (and as we all know), that particular framework is the Emperor Framework of WTFs.
Admin
Fair enough
Admin
And also didn't know about dedicated functions or statements for breaking into the debugger. if(condition()) { DebugBreak(); } has its uses: sometimes it's much faster than conditional breakpoints.
Admin
@Steve - What no logging over the I2C Bus??? [yes, I have....]
Admin
A pattern I've started to use recently for this problem is to pass a lambda function to the logger, something like this (depending on your language's syntax):
So the logger can call it only if necessary and the caller doesn't have to worry about it.
Admin
I would have said that unless the condition is something very simple like
x > 5
, and probably even then, it's always much faster than conditional breakpoints. Mostly, that's because conditional breakpoints fire out to the debugger every time you pass by the point, so the program is interrupted every time. To say nothing of how it's probably very slow (compared to if the program does it) for the debugger to evaluate the condition.Admin
No, but I did one time, while testing a codebase after porting it to a new compiler, add a "set this output pin high when we begin this calculation, and low again when the calculation finishes" followed by attaching an oscilloscope to the pin to measure how long the calculation took.
Admin
Having a local flag allows enabling logging (or whatever you want to enable) for just that portion of code, rather than globally, which will just generate a ton of useless noise you're not interested in. Maybe there are logging frameworks that provide that functionality, but I haven't seen one yet.
Admin
Or it might be a language where the debugger has no useful way of changing control flow (like in Java 1.2 or earlier without force return or drop frames). Set a breakpoint on the if statement, and if you reached some state where you don't want to continue into the following code (as it may have side effects outside of your debugged process), flip the flag so the thread will die. Still I would not throw Exception but ThreadDeath in that case, since that is what it should be (a ThreadDeath does not inherit from Exception and therefore usually is not caught, and when thrown up to the thread's entry point it will not print a stack trace).
Admin
Speaking of logging in languages with good macro preprocessors, the logging ecosystem in Rust is pretty good about this. There's plenty of options, seeing as it's Rust and they can't decide on anything, but the logging calls themselves are macros. The code they expand to does the logging check before the string formatting or any expensive operations you have embedded in your statement. It's hard to read if you're not familiar with Rust but: https://docs.rs/log/latest/src/log/macros.rs.html#31-60
Admin
At the very least if you're going to do this use an assert instead of an if. There are still better ways to do it, but at the very least everyone looking at it will know that it's intended to be debugging code and also you can give a proper debugging message instead of just a generic exception...
Admin
I'm thinking of all the catch blocks and destructors that get tested, possibly for the first time, when that flag is set. Aborting is one thing--it makes the program stop, then you can see a stack trace or poke around memory in the debugger, find and fix a bug, or let the program go on its merry way. An exception doesn't stop, it makes the program do different and unusual things.
We've run code coverage with fault injection on mature code trees and found decades-old bugs in error and exception handlers. Usually the bugs cause a crash (those are the lucky ones, the ones that die quickly), sometimes an out-of-memory handler leaks memory or tries to allocate its own (those suffer longer before they die)...but a few times, the error is "handled" but something is wrong, so the program survives to the end and gives completely wrong output (or worse, "harmlessly incorrect" output that can become "incorrect with consequences" under unknown conditions). If we hadn't performed a brute force search for these bugs, we wouldn't have any way to know where they come from--we only know because we can match up the test run with the list of injected faults to see which moving pebble triggered the landslide. If these bugs are observed in production, they're impossible to fix from the information in a case report, so they do survive for decades.
A switch that randomly starts firing exceptions in the code seems like someone had heard of both debugging approaches and decided to combine them in a way that negates the benefit of either.
Admin
Yes, I meant the printf dumping to a console port over RS-232... and good luck finding a computer that has one of those. Or even can use one of those USB/232 converters reliably.