Tuesday, January 20, 2009

ASSERT() does not fix crashes

Windwos BSoD

A problem has been detected because coders always say, "this should never happen".

The problem seems to be caused by the use of: ASSERT()

#if DEBUG
#define ASSERT(x) assert(x)
#endif
#if RELEASE
#define ASSERT(x)
#endif

If this is the first time you have this stop error screen, restart your computer. If this screen appears again follow these steps:

Check to make sure you've bullet proof the code. If this is a new application, ask your fellow coders why you are stupid to only use asserts instead of writing the code to gracefully handle the error condition.

If problems continue, also check for other piss poor lines of code giving lazy programmers a bad name. If you need to use a Safe Mode like try{}, throw() and catch(), you're an idiot. The end user doesn't care about your error codes. Restart your computer and DEL all of your files because crashes aren't useful.

Tech information:

*** STOP: 0x00000050 (0xDEADBEEF, 0x0000001, 0xBAADF00D, 0x00000000)

*** ASSERT() - Address 1F0CED17 base at F0C17F0C, DateStamp 80fca82


first a few articles to get my point across. the following are error messages made by microsoft engineers.
Best Windows Error Ever May Rip Time-Space Continuum, Destroy Reality
Dec 6 2007

Windows Vista Error?
Jun 3 2007
and i'm pretty sure everyone on the planet (who's a nerd) has seen this great PR shot:
Blue Screen of Death Strikes Bird's Nest During Opening Ceremonies Torch Lighting
Aug 11 2008
first, a sad program just pooped out. the second one a funny accidental icon enumeration selection. and that last BSod could have been a microsoft bug. but then again, maybe not.

with what it is essentially equivalent to a kernel panic -- it pretty much rests on the lowest level of the OS where everyone can point and laugh at the main player. not the application or program.

was it a driver? or the video playback program? who else is responsible for these?
when people start to make fun of spectacular crashes on a giant projector, it's hard to remember that it's sometimes the idealistic coder that broke the application and that windows had nothing to do with it. take the following articles:
Microsoft Arcade Fail
Jan 18 2009

We Interrupt This Program With a Windows Error
Jan 1 2009

Jesus Tries to Save Your Soul But Windows Stops Him
Aug 28 2008
that isn't to say that microsoft should be absolved from all of their own problems. patch tuesdays, red ring of death and zunes freezing at new years to name a few examples.
Cause of ZUNE leapyear problem - Freescale date routine
Dec 31, 2008
now, what basically happened here was that a coder probably had a brain fart and just didn't think through of all of the permutations. it happens to every coder.
this is when i was reminded of the absolute absent mindedness of using ASSERTS();

normally, asserts and exception conditions are pretty useful for developers to announce (NOT TEST FOR) those "this should never happen" situations. to this day, i still see coders do something equivalent to the following:
my_data_block = get_some_piece_of_data();

ASSERT( my_data_block, "data block is empty" );

my_data_block->do_something_with_it();
for those who do not know what the assert() function normally does, is this:
test the first parameter and see if it is valid.
if it is OK, continue on with the next line.
if it is NOT valid, halt the program here.
sometimes, coders will have a second parameter to "provide more information" on what just happened. and sometimes, these ASSERTs are macros that get compiled out during a RELEASE build (versus a DEBUG build). in other words, they are "scrubbed out" of the code automatically when making a version of the application/program for public deployment.

here's why i can't believe people still code just like the example above. if my_data_block did not receive a valid chunk, the program will continue (in a public release build) and crash when we try to do_something_with_it... this is when you'll see one of those error message box.
like i said before, the end user doesn't really care about (let alone know what to do with) your error codes or exception messages you happen to catch. you should NEVER code like that. here's one example to code it properly:
my_data_block = get_some_piece_of_data();

ASSERT( my_data_block, "data block is empty" );

if ( my_data_block )
my_data_block->do_something_with_it();
else
tell_user_whats_going_on();
// instead of terminating the application
// all of the sudden
there are other ways to do this. but essentially, you need to make sure your code will not just die on you. any time you see an application freeze or see an error message box -- it's the mark of a n00b coder.

if you see your CPU usage spike outta control - then the coder is mediocre. something got locked in an infinite loop. these are sometimes a surprise to find. but that's when testing will make you a good coder. (yes, i still see people submitting stuff in with out testing their work. we normally call them artists. but once in a while, coders do this too.)

what's an expert coder, you ask? that's someone who stopped reading this article right after my little BSoD sample at the top of this article.

courtesy of XKCD

the only time you should terminate a process is a user supplied add-on/plug-in. keep your application running. i'm always surprised to find piles of CRAP javascript code, but am extremely impressed that web browsers will ignore malformed code. too bad not all applications are designed like this.

time and time again, i see high end applications that costs $#!t loads of $ $ $ such as Maya and 3DStudio Max -- crash. the artist constantly complaining, stOOpid editor... when i am willing to bet 95% of the crash is because of a plug-in "one of our" coder wrote to extend the exporter, importer, utility, attach-this, or do-whatever to the 3D editor. if those "scripts" were validated as well as the results they generate - i bet applications would seem much more "stable" to the end users even when shotty (or absent-mindedness) programming are applied to them.

yeah, there'll be a trade off in speed - but if it comes down to the stability of the application - this is something that might need to be considered. otherwise, it's pretty much planned, "let's ruin the user's experience..."

PLEASE DO NOTE: to the independent / individual / or just starting off developer(s); i completely understand that there is a difference with a handful versus a team of 10, 20 or 100 people that might be physically impossible to code every possibility and know all the permutations with little time (or encounter the occasional brain fart). but if your project is a rockin, and you get piles of people to work on it - please take out the "temporary" assert reminders (or use an alternative "messaging" mechanism), keep your application running and put in actual functions to gracefully handle those unfortunate cases.

No comments: