- 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
You should note that running in a debug mode on a production server is a HUGE waste of resources. All sorts of code checks and debug methods are ADDED by whatever IDE you are using. If you are running debug modes on production clients you should be shot. Debuggers are for development purposes, not production bug tracking. Logging exists to help identify problems on production apps.
Now, logging is not meant to log every activity on production; that is why plug-ins such as Apache's log4j have different levels of logging. You have debug logging for development issues, then info/warn/error logging for production and live state tracking. Logging in production is supposed to give a general idea of the flow/state of production app and give as much clue as possible as where problems are arising. I am not talking about logging things that are used for business purposes of course, such as credit card transaction logging.
Admin
Are you declaring it publicly, publishingly, protectedly (does that word even exist ?) or privatly ? [:)] (ps: yes, I'm reaching a new low in lameness [:D])
Admin
Sounds kinda like a cat I know... Meow?
Admin
The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.
-- Brian W. Kernighan
Admin
Just replying because I want to see what happens to the box in the middle when the quoting depth gets really large. Sorry for the abuse. It's for scientific purposes.
Admin
That sounds like the S cat indeed, meow !
Admin
ummm.... I think it's the 26 case switch statement that could be replaced with a single line that is the wtf....
Admin
Delphi, at least, runs at about half the speed when there are conditional breakpoints nearby. I often stick code in my program like
if ID = 120314 then
ID := ID;
just so I can put a breakpoint on the condition and then step forward to see why the object with and ID of 120314 is making the program barf.
Admin
For me, it usually runs a L O T slower, as in orders of magnitude. I suspect this is because it repaints the editor window for each iteration.
I usually use "if ID = 123 then asm int 3 end;" cause I'm so good with forgetting to put the breakpoint on if I turn it off :)
Admin
This person is known as the 'user'. All he cares about is the fact that his program crashed because some half-arsed "programmer" though try-catch was beneath him.
Of course, like the one after, it's likely one of those unfinished things. Perhaps this app was halfway through development and the guy just hadn't got round to the error handlers yet. Like I've said before, you can't judge a code snippet without knowing the circumstances behind it. OTOH, if this was a released product....
As for the one after (the CSS one), are you lot really telling me that you've never made that kind of mistake? If so, then you're lying.
Admin
1. You should note that running in a debug mode on a production server is a HUGE waste of resources.
Who said anything about production? Production code shouldn't even be compiled in
2. All sorts of code checks and debug methods are ADDED by whatever IDE you are using.
Wrong, they're added by the compiler, which may or may not be bundled with your IDE.
javac -g MyClass.java
3. Now, logging is not meant to log every activity on production; that is why plug-ins such as Apache's log4j have different levels of logging. You have debug logging for development issues, then info/warn/error logging for production and live state tracking. Logging in production is supposed to give a general idea of the flow/state of production app and give as much clue as possible as where problems are arising. I am not talking about logging things that are used for business purposes of course, such as credit card transaction logging.
Is this supposed to be a tuorial on the Log4J "plugin"? I've been using Java and related libraries since the moment the name was changed from "Oak" and I'm well aware of what to log and what not to log.
-----------------
Sorry dude, you look like a nice guy in your avatar, but don't assume you know my skill level or experience.
Admin
[Asshat corrects/completes his post]
1. You should note that running in a debug mode on a production server is a HUGE waste of resources.
Who said anything about production? Production code shouldn't even be compiled with debug info
Admin
The documentation of VBA in Office97 state, that there is an IsNothing-function (like the IsNull function). But this is false information. I think this function just makes the documentation corrent. And in fact, I don't see why to intruduce a new language token set (is nothing) that is used in no other place of the language just for this one equality check.
Admin
Breakpoints may introduce timing issues that logging statements don't. I've seen it happen more than once. (Easy example: Your process is communicating with another process which expects responses with no more than a one-second delay. Sitting at a breakpoint for two seconds will change the overall system's behavior.)
Admin
If the comment's capitalization is correct, then there are multiple routes to improvement - the best one is a matter of taste, I suppose:
Chr(Index+97+(Index>=26)*(-58))
if Index<26 then Chr(Index+97) else Chr(Index+65)
Mid("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",Index+1,1)
Admin
Someone at my company found something like this...
bool bValue;
...
...
return( bValue == true ? true : false );
I really never get tired of those, but they burn at the same time.
Admin
I refer to this as a "Try / Catch / Drop". Seriously, looks like it was a TODO, but never got implemented. I like to use the comment "//TODO: Do stuff" and set Visual Studio to flag these as tasks so every build you can see where you need to revisit the code.
Admin
ahem ... guess i should get me a cat, too :)
Admin
Ah, from the "Throw-The-Baby-Out-With-The-Bath-Water" school of programming. It is sometimes useful to, say, call a logging or an e-mail notification routine after an exception; if either fails, its inconsequential to the error handling. However, if they succeed, you have valuable information that can help you correct the original exception. But all the time, you *do* want to catch exceptions on these functions, as you do not want them to superceed the one just called the handling routine in the first place.
I say try. If it works, great!, if not, oh well. Or as stated in pseudo-code:
try
{
exception_prone_function();
}
catch
{
handle_exception();
try
{
log_exception();
}
catch
{
// Ignore....
}
}
But I do admit that this is not the spirit of the original WTF posted. I'm just agreeing with the comment that this sort of error handling (or lack thereof) is sometimes useful.
dZ.
Admin
I am guilty as charged for writing such a code previous years...
I really thought that i was being thoughtful and making codes looking cleaner before... :)
Admin
<font size="2">#define TODO(msg) message(__FILE__ "(" _QUOTE(__LINE__) ") : TODO: " #msg)</font>
Chucks out the quoted message in the build spew window, and you can double click it to jump to the code location. Yeah, I still use VC6.
Admin
You really don't want to catch-and-drop something critical like an OutOfMemoryException, just to get around your foo() dividing by zero or something. You should only be dropping exceptions that won't affect the rest of the program.
(I don't know if whatever language we're in has a NonFatalException abstact exception class, but you get the picture.)
Admin
For the love of GOD, will you people quit swallowing your exceptions!?!??? This is NOT what try...catch was designed for! I hate how ridiculously common this WTF is!
Admin
You SHOULD at the very least, put some logging in there, as you said, and this definitely isn't the worst version of try...catch..WTFery.
However, the places where you would catch an exception and just let the application keep running are extremely rare. The WTFs like these are usually where the lazy developer thinks that by swallowing these exceptions, he's making his app more "stable" when what really happens, is that it fails in many places and noone knows that its failing until way later when some crucial data got lost or some important process doesn't seem to work. Also, the developer usually is trying to catch a very specific exception, but is lazy and just catches everything. So things fail without notice even though the code could easily be fixed if one saw the exception.
One might also argue, why is your mail server failing so often that you have to put a try...catch around it in the first place?
Admin
Admin
Sadly, I find this all the time, usually on programmers who were raised on Java. (I don't hire *anyone* with Java on their resume for C++ or C# work!)
You'll either see exception handling used to handle non-exceptional cases. Sort of like a structured goto, or you see try/catch blocks with the exceptions ignored all over the place.
Good programmers handle the exceptions explicitly and never use a catch-all exception handler. You should know what, how, and when exceptions are getting thrown and not try to sweep them under the rug.
Admin
If you are concerned about different character sets and wish a general solution, this would be the way to go.
Errr no. I just needed a letter of the alphabet. upper or lower. To little sleep, to much coffee.
Admin
Actually, this is very acceptable in certain situations you can find yourself in. The thing is, whatever goes wrong with sending a mail, all you ever get is "Could not access 'CDO.Message'". What we usually do is set up the server's IIS SMTP to point to the real mailserver. That way the errors get logged with more information by the IIS SMTP server.
Drak
Admin
Re: Debugger and Production
Speaking for Windows/VS C++ you can have both: In Release Build turn on all optimizations you want, also Create Debug Symbols in Database, your exe is about somme hundred KBytes larger, no performance penalties, no additional files to deploy. We have a custom crash handler, so every app crash writes a Dump File which gets sent automatically to us. You can then open this Dump like a project, the cursor blinking at the crash line and most variables available for inspection. I can't see how logging is better...
Admin
catch (...)
the most hideous form of catch in VC++, and, sadly, the most commonly used one in the projects I had the misfortune to maintain. Not only does it catch all "legitimate" C++ exceptions, it even catches system exceptions like access violation, stack overflow etc.
I don't know if this was the intent of the authors of C++ standard, or if Microsoft took the liberty to annoint this form of catch with such god-like healing powers.
In the huge project whose debugging I was tasked with, one subsystem was particularilly "catchy". Each and every function looked like this:
<FONT face="Courier New" size=2>bool foo()</FONT>
<FONT face="Courier New" size=2>{</FONT>
<FONT face="Courier New" size=2> try {</FONT>
<FONT face="Courier New" size=2> //...</FONT>
<FONT face="Courier New" size=2> return true;</FONT>
<FONT face="Courier New" size=2> }</FONT>
<FONT face="Courier New" size=2> catch (...)</FONT>
<FONT face="Courier New" size=2> {</FONT>
<FONT face="Courier New" size=2> print( "error" );</FONT>
<FONT face="Courier New" size=2> return false;</FONT>
<FONT face="Courier New" size=2>}</FONT>
<FONT face="Courier New" size=2>}</FONT>
In the beginning I was puzzled how sloppy code like that could produce so few crashes... But I assure you, the few crashes that managed to get through the catch(...) were real thermo-nuclear industrial standard crashes
Admin
<FONT color=#000000>The letter-of-alphabet code snippet seems wrong. It looks like traditional VB (i.e. pre-.NET), but it has a bunch of "Return" statements, whereas in traditional VB you *have* to assign to the function name to return a value.</FONT>
<FONT color=#000000>Also, the one that sets a variable to its own value on a certain date (if nobody else has worked it out) is most probably a placeholder for setting a breakpoint.</FONT>
Admin
ROFL!
Admin
I have to find a defense for the first (even though the author has said enough that this cannot be correct)
An old mainframe programmer used to working in EBCDIC has moved to VB because nobody is hiring mainframe guys anymore. She (I know it is he, but it you work with a female program in my experience she is old and has a beard, so I'm changing the gender for the fun of it) never considers any form of 'a' + Index, because that doesn't work in EBCDIC. A lookup table would work, but a compiler (it hasn't occurred to her that VB isn't compiled so this wouldn't apply) would store the table in a different location, and she know just enough about modern CPUs to know that this can cause many 'cache misses' which would slow her program down. Since she started on computers slower than modern calculators she always looks for the fastest speed. (She has gotten used to modern systems having lots of memory, but mainframes are still expensive enough that you keep them 100% busy, so she hasn't figured that this optimization isn't significant on a system where the processor is mostly idle.
There, I knew I could come up with a 'reasonable' defense for this.
I do this all the time. When I know I want to send email, but I have never done it yet, it is much easier to write just the code that sends email, and then test that. Once I can send email (System.Web.Meil.SmtpMail.Send ... correct spelling [Mail not Meil]... Is myMail a struct of some sort or a string....) I go back and fill in details like exception handling. Once in a while I forget to go back before I check the code in. Getting the details correct the first time takes time, working on the error handling gets in the way, particularly if I'm sending email half way through a long process - I don't want bugs in my email to kill my test of the second part, if the part before the email takes half an hour.
I don't miss too many cases in the long run though - I review my own code from time to time. (particularly after seeing something here... speaking of which, I have to go fix a few places where I haven't done error handling yet)
Admin
More likely they just needed to set a breakpoint
Admin
In all fairness, you should TryCatch any point of failure, and external resources are a best case example of a point of failure. I'm not defending the exact implementation of his TryCatch, but I am defending the coder's underlining intention. Anybody who doesn't TryCatch an external resource is writing WTF code, that should be in a coder's 10 Commandments imho.
Admin
FYI:
There are Conditional Statements in C#, they are called Preprocessor Directives. The following snippet is a Directive that will only be included in the code when compiled in the debug mode. (Who gives a crap about performance when debugging)
#define DEBUG
#if (DEBUG) {
//Include this code when compiled in Debug mode
}
the "#region" statement is also a Conditional... that does not get compiled into IL code either. I hope this answers your question YTram, and it should correct Oliver's misleading/incorrect information.
Also for the guy who doesn't use "Debuggers" because he writes multi-threaded apps... VS2003 debugger lets you switch / step into different threads. Try reading the Visual Studio documentation. By the way, Logging and Debugging are completely separate issues, and its scary that a 'developer' would be fuzzy on that point.
Admin
Or at the very least, indicate that you don't care if it fails. That's what I do.
Admin
The real WTF in this thread is that real programmers don't debug. They write code that works right the first time. Debugging is for wimps.
Admin
LOG, LOG, LOG!!!! I have exactly the same scenario you describe. I don't care if you catch, but you better log if you aren't rethrowing. And as this WTF points out, at some point somone is likely to care.
Admin
<font size="2">
{</font>
<font size="2">
exception_prone_function();</font>
<font size="2">
}</font>
<font size="2">
</font>
<font size="2">
catch</font>
<font size="2">
{</font>
<font size="2">
handle_exception();</font>
<font size="2">
</font>
<font size="2">
try</font>
<font size="2">
{</font>
<font size="2">
log_exception();</font>
<font size="2">
}</font>
<font size="2">
catch</font>
<font size="2">
{</font>
<font size="2">
// Ignore....</font>
<font size="2">
}</font>
<font size="2">
}
</font><font size="2"></font>
At a previous company I worked for, that code sample was the VB equvalent of something I used to see (and cringe at)...
Option Explicit
Public Function SomethingThatIsComplicated As String
On Error Goto KeepGoing
SomethingThatIsComplicated = DoSomethingWonderful(1)
Exit Function
KeepGoing:
'Do some more useless stuff
SomethingThatIsComplicated = "Error: " & Err.Description
Exit Function
End Function
Then, at the firm I work for now... I see a LOT of C++ and VB code that resembles this pattern
Public Function SomethingInvolvedAndComplex( [anywhere between 9 and 30 parameters here, with a shitload of OPTIONAL ones just for fun] ) As Integer
On Error Resume Next
Dim bContinue As Boolean
bContinue = True
'Do something error prone
If Len(strSomethingThatCameBack) > 0
bContinue = False
End If
'9,000 more conditional statements that look for bContinue follow...
Exit Function
SeriousError:
'Log something
Exit Function
End Function
Admin
If this were true then there'd be no use for QA right? Every piece of software would be bug free and we wouldn't need Windows Update. Ahhhhh, a computer user's nirvana. But alas, welcome to reality.
Admin
Anonymous,
You're completely off-point. Conditional compilation is not the same as conditional breakpoints. Conditional breakpoints are used within the IDE to stop at a breakpoint when a certain condition is met, and they most surely slow down execution (the condition is evaluated on each pass when the breakpoint is reached, in order to see if there should be a break in execution).
Admin
VS2003 has Conditional Break points: Debug -> New Break Point and Click the Condition Button
Admin
Agreed.
The reason why conditional compilation and conditional breakpoints exist are for two seperate reasons. They are still both tools which are very useful at resolving issues with debugging feature problems in your code (code which compiles, but does not function as expected).
Conditional Compilation is useful when you want to create a special build based on certain criteria. This may not just be because of a "DEBUG" or "RELEASE" version of your code, it could very well be platform-based compilation. C programmers rely on this compiler feature in order to avoid forking their code for multiple release targets... say one compilation of code is meant to be executed on Win95, another version on Win2000, another on OS/2... (etc).
Conditional compilation is also useful when you are adding alpha/beta or other untested features to your main code, and you need a way to exclude that functionality from making it in your release version. You could simply tag all your questionable sections with #BETA to prevent accidental release of code that is not-yet intended to go to production, but seperately compile the #BETA version which is intended for its target audience.
Conditional Breakpoints are a seperate tool. This debugging tool is a must-have feature when debugging long-running tasks... particularly nested loops. Consider this example:
0: int x = 0;
1: int y = category.Products.Count;
2:
3: foreach (Product item in category.Products)
4: {
5: foo(item);
6: x++;
7:
8: UpdateProgressBar((x/y) * 100); //for simplicity
9:
10:}
Let's say while you are running your code, you notice that within this loop, the program dies when processing item #15235 when you are running > 100 items through this loop. Obviously, this is a pain to set your breakpoint at line #3 and run until you reach item #15235 and you aren't always going to meet this condition. But, based on trace information, it's obvious the problem begins in this loop, and there is possibly a data issue with item number 15235. So, how best to debug this quickly?
Well, you can set a conditional breakpoint which will get you at the source of the crash much more quickly! You set a breakpoint at line 3, but only stop execution [WHEN item.Number == 15235]. On your next run, your debugger will pause when that condition is met so that you can debug into foo() (where the problem probably is) and diagnose the issue.
Prior to conditional breakpoints, you had to do something like this:
0: int itemNumber = GetNextItemNumber(criteria);
1: // <program farts after his call...debug code here>
2: if (itemNumber == 15235)
3: {
4: itemNumber = itemNumber;
5: }
And of course, you set the breakpoint on line 4 which would only be reached if the item number got to the item in question. Both techniques are doing the same work. Each pass through this code, an evaluation occurs which slows down your code (conditional breakpoints make that implicit).
Admin
IMO that is very, very bad practice. " I don't miss too many cases in the long run"??? With that kind of approach to software quality I certainly wouldn't want to hire you.
I'm not saying you need detailed error handling right from the beginning, but you should never, never EVER!!!!!!!!! just silently discard an exception. At the very least it should be dumped to the console or a logfile.
To be exact, there is ONE case where silently discarding exceptions is OK, and that is in unit tests, where the exception is the expected result and the test case should only fail if it doesn't occur.
Admin
Geez, I hate those. One of my pet peevs. Someone too strongly wedded to the "only one return" rule.
tekra
Admin
What if you're a dog person?
tekra
Admin
It is useful at times. If the closeout code is complex enough, I like to have it in one place. I could write a subroutine for the closeout code, but I prefer to keep one level of abstraction at the same level of code as I find it makes debugging easier. (If singlestepping through code, I know that I can usually just step over any subroutine calls.)
Sincerely,
Gene Wirchenko
Admin
$ alias dog cat
Admin
Tekra,
I agree completely. I've got about half-a-million lines of code I inherited from a coworker who left; every subroutine is written using that kind of logic.