2

Usually an access violation terminates the program and I cannot catch a Win32 exception using try and catch. Is there a way I can keep my program running, even in case of an access violation? Preferably I would like to handle the exception and show to the user an access violation occurred.

EDIT: I want my program to be really robust, even against programming errors. The thing I really want to avoid is a program termination even at the cost of some corrupted state.

Ralph Tandetzky
  • 22,780
  • 11
  • 73
  • 120
  • 1
    possible duplicate of [C++, \_\_try and try/catch/finally](http://stackoverflow.com/questions/7049502/c-try-and-try-catch-finally) – Hans Passant Jan 30 '13 at 18:16
  • 1
    What? A memory access violation? You should write your program to avoid memory access violations. Maybe a little more context would be useful to anyone trying to help you with this. – Void Star Jan 30 '13 at 18:18
  • Why show it to a user, what are they going to do with it? If the a/v is in your code, fix it, it's it's in 3rd part code you can't touch, the find some way to detect it, and show some suitable message, Like sorry I couldn't do waht you wanted. Put in in a log file and swallow it, but don't show it to a user. – Tony Hopkinson Jan 30 '13 at 18:20
  • yes, I wouldn't scream at the user, "ACCESS VIOLATION". It's clearly something to be logged. – Ralph Tandetzky Jan 30 '13 at 18:22
  • 5
    actually, there is an advantage to this that people seem to miss. what if you want to gracefully exit? what if you want to send a bug report back to the sever? what if you want to pop a message up saying.. something went wrong, do you want to save the state and send data back to us so we can fix it for future releases? note that in a large organization, there are good and bad programmers. no reasonably large program is entirely bug free. – thang Jan 30 '13 at 18:35
  • BTW, it is possible to convert SEH events into C++ exceptions, and route them through the standard C++ exception handling machinery. – Mordachai Jan 30 '13 at 19:00

2 Answers2

4

In Windows, this is called Structured Exception Handling (SEH). For details, see here:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657%28v=vs.85%29.aspx

In effect, you can register to get a callback when an exception happens. You can't do this to every exception for obvious reasons.

Using SEH, you can detect a lot of exceptions, access violations included, but not all (e.g. double stack fault). Even with the exceptions that are detectable, there is no way to ensure 100% stability after the exception. However, it may be enough to inform the user, log the error, send a message back to the server, and gracefully exit.

thang
  • 3,466
  • 1
  • 19
  • 31
  • 1
    It is certainly possible to keep your program running the face of an access violation. As you yourself mentioned, saving state (even doing a mini-dump of the process) for postmortem debugging is possible, or sending a bug report, or asking the user for "what were you doing when this occurred" are all possibilities... – Mordachai Jan 30 '13 at 18:58
  • that doesn't necessarily mean keeping it running. that's usually making last minute cleanup before exiting... and there are exceptions for which you can't catch at all. – thang Jan 30 '13 at 19:01
  • It's possible to do a number of things in response to this. You could potentially restart your application in order to give yourself a fresh memory layout and initialization sequence and then reload your previous context (or task-start-context) and resume from there... – Mordachai Jan 30 '13 at 19:13
  • i don't see how you can reconstruct the state of your program when you don't know the bug that causes the problem. if you knew the bug, then why have it in shipping code? and restarting is in effect not keeping your programming running. that aside, things like double stack fault can't even be handled at all, but i guess that is more severe than access violation. – thang Jan 30 '13 at 19:15
  • Maybe change from "There is no way to detect and keep your program running" to "there is no way to ensure that your process is 100% stable after trapping such an error or of backing out of all possible errors that ensued due to whatever bug caused the access violation" – Mordachai Jan 30 '13 at 19:15
  • Thanks. changed it a little to clarify. – thang Jan 30 '13 at 19:19
  • Cool. Just FYI, I have a stack overflow handler that is recoverable. One simply must unwind the current stack back to the exception handler, then rebuild the watch-dog page at the end of the stack so that a future stack overflow will be correctly trapped. Again, such code is "use at own risk" - it is certainly true that whatever bug caused the runaway stack use is still there, and it's not impossible that some side-effects have destabilized your code. However, it is possible. At least on 32 bit Windows on x86. Other systems would have to have a handler that was OS/hardware specific. – Mordachai Jan 30 '13 at 19:23
  • did you post the code? what i have experienced in the past is when an exception handler puts more stuff on the stack. this causes a stack fault inside the exception handler. i've noticed that in this case, the program just exits completely. – thang Jan 30 '13 at 19:27
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/23657/discussion-between-mordachai-and-thang) – Mordachai Jan 30 '13 at 19:59
3

I will start by saying that your question contains a contradiction:

EDIT: I want my program to be really robust, ... The thing I really want to avoid is a program termination even at the cost of some corrupted state.

A program that keeps on limpin' in case of corrupted state isn't robust, it's a liability.


Second, an opinion of sorts. Regarding:

EDIT: I want my program to be really robust, even against programming errors. ...

When, by programming errors you mean all bugs, then this is impossible.

If by programming errors you mean: "programmer misused some API and I want error messages instead of a crash, then write all code with double checks built in: For example, always check all pointers for NULL before usage, even if "they cannot be NULL if the programmer didn't make a mistake", etc. (Oh, you might also consider not using C++ ;-)

But IMHO, some amount of program-crashing-no-matter-what bugs will have to be accepted in any C++ application. (Unless it's trivial or you test the hell out of it for military or medical use (even then ...).)


Others already mentioned SEH -- it's a "simple" matter of __try / __catch.

Maybe instead of trying to catch bugs inside the program, you could try to become friends with Windows Error Reporting (WER) -- I never pulled this, but as far as I understand, you can completely customize it via the OutOfProcessException... callback functions.

Martin Ba
  • 37,187
  • 33
  • 183
  • 337