6

Possible Duplicate:
What is the easiest way to make a C++ program crash?

There's a construct I see frequently in our codebase, where the program gets into an invalid state somehow, the code will do something intentionally wrong, just to force a crash. It usually goes something like this:

if(<something is wrong>)
{
    int *ptr = NULL;
    *ptr = 0;
}

This of course causes a null reference exception and crashes the program in an unrecoverable manner. I'm just wondering if this is really the best way to do this? First of all, it doesn't read well. Without a comment, you might not realize that the crash that occurs here is intended. Secondly, there's pretty much no way to recover from this. It doesn't throw an exception, so it can't be handled by other code. It just kills the program dead with no way of backtracking. It also doesn't give much of a clue as to why it had to crash here. And it will crash in all builds, unlike, say, an assert. (We do have a pretty robust assert system available, but it isn't always used in cases like this.)

It's the style we're using all over the place, and I'm in no position to try and convince anyone otherwise. I'm just curious how common this is in the industry.

Community
  • 1
  • 1
Darrel Hoffman
  • 4,436
  • 6
  • 29
  • 41
  • 4
    Why not just use [`abort()`](http://www.kernel.org/doc/man-pages/online/pages/man3/abort.3.html)? – Fred Larson Nov 21 '12 at 21:24
  • 6
  • I *suspect* the intent of the original programmer is to cause the program to fail "unrecoverably" when running in a production situation, or to cause a break to the debugger (if one is present). I don't like this construct, but I've seen people argue that this is the only "reliable" cross-platform way to achieve this effect. I personally would not use it. – Nik Bougalis Nov 21 '12 at 21:28
  • 2
    That is horrific. If you know the program is in error but you're not sure why, you should be dumping anything and everything that you think will help resolve the issue. Making the program crash out without any clues as to what went off is cowboy programming IMHO... – Robbie Dee Nov 21 '12 at 21:28
  • There is no such thing as a "null reference exception" in C++. – Kerrek SB Nov 21 '12 at 21:28
  • @RobbieDee: Is "cowboy programming" the same as "offensive programming"? :-) – Kerrek SB Nov 21 '12 at 21:31
  • it sounds like the question is more "how to I teach my colleges how to code?" (because I think everyone can agree they are doing it wrong) – Shep Nov 21 '12 at 21:33
  • Nobody wants code to go over in live but making it silently crash is just not on. Imagine some poor support bod trying to explain this to a customer: "Sorry, it just crashes sometimes but we don't know why". My guess is that customer would eventually walk... – Robbie Dee Nov 21 '12 at 21:34
  • I should add that this runs on several different platforms (all the current game consoles), so it's possible certain features like `abort()` might not be cross-platform compatible on all systems. We're a large well-known company and I'm new here, so I tend to take their word for it that things are the way they are for a reason. But I haven't heard a good explanation for this one yet. – Darrel Hoffman Nov 21 '12 at 21:55
  • @KerrekSB: Or whatever it's called. I come from a Java background, so "null reference exception" is what I'm used to calling it. I guess technically it's not an "exception", or else I could catch it and there wouldn't be a problem... – Darrel Hoffman Nov 21 '12 at 22:26

3 Answers3

4

You can't "crash" a program in a deliberate way, because by its very definition a crash is when a program goes wrong and fails to behave deterministically.

The standard way to terminate execution is via std::terminate; the usual way to achieve this is to call std::abort, which raises an unblockable signal against the process (leading to std::terminate automatically) and also causing many operating systems to produce a core dump.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    Isn't it the other way around? `std::terminate` calls `std::abort`, which in turn raises a signal, etc. – Danilo Piazzalunga Nov 21 '12 at 21:33
  • @DaniloPiazzalunga: No, I don't think so. However, I found some additional information in the standard: It's generally unspecified whether uncaught signals cause stack unwinding or not, but calling `std::abort` specifically does *not* cause any unwinding. (I.e. it's precisely the thing the OP needs.) – Kerrek SB Nov 21 '12 at 21:57
  • We actually don't use the C++ STL (or Boost or any other outside libraries) here - we've got our own in-house STL, so you won't see `std::anything` in this codebase. Not even for strings. I don't know if it has an `abort` or `terminate` available... – Darrel Hoffman Nov 21 '12 at 22:13
2

You should throw an exception, which is basically causing a crash deliberately and in a controlled manner. Here is an example with help from this question.

throw string("something_went_wrong");

Better yet is that the error is caught or fixed. Assert would also be a fine choice.

Community
  • 1
  • 1
PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142
  • I've been programming too much java recently... Anyways, changed the example to something better. – PearsonArtPhoto Nov 21 '12 at 21:28
  • 2
    No, an exception is a completely different thing. The purpose of an exception is to trigger an uncommon error from which the application can recover, in this case the intention is *killing* the application when it cannot recover. – David Rodríguez - dribeas Nov 21 '12 at 21:30
  • An uncaught exception will behave similar to the current behavior, with the added bonus that it is easier to spot, can give a more meaningful stack trace, and at a later time could be fixed by catching the error. – PearsonArtPhoto Nov 21 '12 at 21:31
  • 1
    I upvoted this specifically because the OP mentioned his code "... doesn't throw an exception, so it can't be handled by other code." – Fred Larson Nov 21 '12 at 21:36
1

I guess that this is the way to trigger a core dump in the situations where you are not debugging. Core dump then gives you enough information to analyze the problem. In case of "programmer errors" (or bugs) this is better than throwing an exception because stack unwinding would not allow you to build a reasonable core dump. A similar effect could be achieved in a more elegant way by calling std::terminate having previously registered (with std::set_terminate) a function that generates a core dump or something similar. See this article for more detailed explanation.

Andrzej
  • 5,027
  • 27
  • 36