views:

203

answers:

6

I use a Windows OS library to manipulate image files. Sometimes it crashes deep inside it for no apparent reason—all the inputs are reasonable and its not a threading issue. The crash is memory A/V.

So, what are the down sides to something like this:

try {
  pFoo = OsAPIThatCrashes();
} catch {
  pFoo = NULL;
}

Will that even work? We don't use exceptions anywhere else in our code.

+2  A: 

Chances are that this won't do any good -- it would only help if the OS API threw an exception that you could catch. If it was doing that, and you weren't catching the exception, you'd normally get an exit from the application, with an error message to the effect that it had exited by throwing an exception that wasn't caught. Unless you're seeing something on that general order, there's very little chance that wrapping the call in a try block will do any good.

Depending on the OS, you might be able to use a native exception handling mechanism to accomplish a bit more -- for example, under Windows, you can catch things like page faults using structured exception handling. Again, it's not entirely clear whether this will do any good though -- if an unhandled exception is the source of the problem, it may help, but if the code has a bug where (for example) value X==10 and value Y == 20 leads to an infinite loop, or something on that order, you're probably going to have to pin down when the code crashes, and assure that never arises.

Jerry Coffin
A: 

While the win32 API is a C library and doesn't use exceptions, MSVC can implement certain things as exceptions (such as division by zero) that aren't required to be done that way (by the C++ standard). So: it depends.

Your best bet is finding out what's causing the problem and fixing that.

Roger Pate
+1  A: 

The internal state of the library is probably bad at this point, so continuing to use it is risky. Best to fix it, crash, or use a different library. Sometimes life just sucks.

jeffamaphone
A: 

You may like to explore Structured Exception Handling. The structured exception handling and termination handling mechanisms are integral parts of the Windows operating system. MSDN reference

Shailesh Kumar
+2  A: 

For one, while we all like to bash MS for the flaws in their software, IME in 99 out of 100 cases the problem wasn't a bug in the OS, the compiler, or the standard library, but in the code calling it. Whatever Win API you're using - it's tested a lot more thoroughly than most (if not all) code ever using it.

Further, try/catch catches C++ exceptions, not OS exceptions. (Earlier versions of VC did this wrong, but later ones have the right default.) So try/catch won't catch an AV. That said, VC provides ways to catch OS exceptions. I think it's called structured exception handling and centered around __try/__catch, but I'm not sure since I have never used it. However:

Once your application ran into an AV, all bets are off. An AV is just one way for undefined behavior to manifest itself and once you (or the API code, however unlikely that might be) invoked undefined behavior, there's nothing you can assume about the state of your application. You should not continue.

To sum it up: You should try to find out what you did wrong. A good way to do this is trying to boil the problem down to a small piece of example code that reproduces the problem. In 90% of all cases, this will reveal the error. If even a small piece of code reproduced the problem and you still don't know what the problem is, you have a nice repro case to come back with (or to throw at MS support). IME, in 9 of those 10% someone else points out your error, and only the remaining 1% will reveal a bug you didn't make yourself.

sbi
A: 

try/catch is for C++ exceptions what you need to use is

__try {
} __except(EXCEPTION_EXECUTE_HANDLER) {
}

But all that will do is eat the exception, it won't fix the problem and could leave the library (or your app!) in an inconsistent state. If the exception is a floating point exception, then you have a good chance of ignoring it an moving on, but if it's an access violation, then you may be just delaying the crash.

If you can nail it down to a specific type of exception, you can catch and eat only that type

long WINAPI filter(EXCEPTION_POINTERS * pex)
{
   EXCEPTION_RECORD * per = pex->ExceptionRecord;
   DWORD dwCode = per->ExceptionCode;

   if (EXCEPTION_DATATYPE_MISALIGNMENT == dwCode)
      return EXCEPTION_CONTINUE_SEARCH; // let a handler above us deal with it.
   else if (EXCEPTION_FLT_DIVIDE_BY_ZERO == dwCode)
      return EXCEPTION_EXECUTE_HANDLER; // Eat this one

   return EXCEPTION_CONTINUE_SEARCH; // let all the rest on through...
}

__try {
 ...
} __except(filter(GetExceptionInformation())) {
}
John Knoeller