1

In Visual C++ 2008, I want to "catch" an exception generated as shown here:

try {
    int foo = 20;
    ::fgetpos(0, (fpos_t*)&foo);
}
//...

Here are adjustments I've made to attempt a successful catch:

  1. SEH is activated (/eha)
  2. I've added a catch(...)
  3. I've added a _set_se_translator vector.
  4. I've added/adjusted to SEH syntax: __try / __except(EXCEPTION_EXECUTE_HANDLER)

In short, I've tried "everything in the book" and I still can't catch the exception. If I replace the call to ::fgetpos with int hey = foo / 0 then suddenly all of the above techniques work as expected. So the exception I'm dealing with from ::fgetpos is somehow "extra special."

Can someone explain why this ::fgetpos error seems uncatchable, and how to work around it?

update When executed in the VS IDE, the output window doesn't name an exception. All it says is this:

Microsoft Visual Studio C Runtime Library has detected a fatal error in MyProgram.exe.

Not very helpful. When I run the console app from the command line, I get a crash dialogue. The "problem details" section of the dialogue includes this information:

Problem Event Name: BEX
Exception Offset:0002fd30
Exception Code: c0000417
Exception Data: 00000000
Additional Information 1:69ad
Additional Information 2:69addfb19767b2221c8e3e7a5cd2f4ae
Additional Information 3:b1ff
Additional Information 4:b1ffca30cadddc78c19f19b6d150997f

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
Brent Arias
  • 29,277
  • 40
  • 133
  • 234
  • Do try to not keep the exception type a secret. Look in the Output window. – Hans Passant Feb 19 '11 at 22:39
  • 1
    What exception? Note that calling `::TerminateProcess()` is not an exception, even though both cause your program to quit. – Ben Voigt Feb 19 '11 at 22:44
  • @Ben: I did not know that ::TerminateProcess might be called by CRT routines without an attempt to seek an exception filter. – Brent Arias Feb 19 '11 at 22:52
  • Can you step into the function with the debugger? – GManNickG Feb 19 '11 at 22:53
  • Exactly which error are you hoping to detect? The one coming from passing in a null stream pointer? Or the one coming from passing an `int*` to a function that expects a pointer to an `fpos_t` instead? – Rob Kennedy Feb 19 '11 at 23:06
  • 1
    I think you can get a better grasp of the problem by enabling first-chance exception catch in Visual Studio, so you can see in the CRT code the line where the exception is generate and (stepping) the exception handler that catches it. – Matteo Italia Feb 19 '11 at 23:18
  • @Brent: While `fgetpos` is probably not calling `::TerminateProcess` directly, if it detects an error it's not going to generate an exception. That's not the C way of doing things. To handle errors in CRT functions, try http://msdn.microsoft.com/en-us/library/a9yf33zb.aspx – Ben Voigt Feb 19 '11 at 23:21
  • 2
    Have you considered the better solution: just don't pass invalid arguments to the library function? :-| – James McNellis Feb 19 '11 at 23:26
  • @Matteo: Unfortunately, activating the "first-chance" code breaks did not change the outcome. I always receive a dialogue box instead of something I can capture. – Brent Arias Feb 20 '11 at 02:27
  • @Brent Arias: then maybe there's an assertion in the CRT for that invalid value, that, if it fails, doesn't raise an exception but just terminates the application. – Matteo Italia Feb 20 '11 at 17:25

2 Answers2

3

Since the code in your dump corresponds to STATUS_INVALID_CRUNTIME_PARAMETER, try _set_invalid_parameter_handler

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Hey!!! How did you lookup that error code? The "error lookup" in visual studio didn't do the trick for me. – Brent Arias Feb 20 '11 at 00:45
  • It seems this handler let's me do logging, but does not allow me to recover from the failure. :( – Brent Arias Feb 21 '11 at 20:16
  • I spoke too soon. When this handler is 'set', it causes fgetpos to return an error code rather than causing my whole app to crash. Ok, I guess I got what I wanted - even if it is stranger than I'd like. – Brent Arias Feb 21 '11 at 20:26
2

Most likely, the runtime catches it for you and issues a debug dialog without returning or propagating the exception- that is a CRT call and they may add whatever exception catching code in there they like. It's well within Visual Studio's rights to catch a hardware exception inside a library function, especially if you are running from within the IDE or in debug mode, then it is expected of the runtime.

Of course, when you divide by zero, then there is no library call here to write that extra catching code.

Puppy
  • 144,682
  • 38
  • 256
  • 465