views:

274

answers:

5

When an unhandled exception happens while debugging some code in any procedure/function/method, the debugger stops there and shows the message.

If I now continue debugging step by step, the execution jumps directly from the line that created the exception to the end of the current procedure (if there is no finally block).

Woulnd't it be just as good to continue with the next line of the current procedure?

Why jump to the end of the proc and continue with the calling procedure? Is this just by design or is there a good reason for it?

+7  A: 

An exception is a unexpected situation, that why processings is stopped.

The jump to the end of the procedure is an invisible finally statement to release any locally "allocated" memory, like strings, interfaces, records etc.

If you want to handle a exception the you have to incapsulate the call that can give an exception with try .. except statement, and use an "on" clause to only handle that particular exception that you want to handle.

In the except you can inspect variables in the debugger and in code you can raise the exception again if needed.

BennyBechDk
+2  A: 

I would expect it to jump to the end of the proc, and then jump to the except or finally block of the calling proc. Does it really continue in the calling proc as if nothing had happened? What does it use as the return value (if it's a function call)?

Continuing with the next line in the original proc/function would be a very bad thing - it would mean the code executing radically differently in a debugger to in release (where the exception would indeed cause execution to exit that proc/function unless there's an except/finally block). Why should debugging let you ignore exceptions completely?

Jon Skeet
It executes a hidden "finally" at the end of the proc to clean up some local variables
Lars Truijens
Jon: Debugger and Release must behave the same, of course. I was referring to the debugger because there you see where code execution is. A hidden "finally" to clean up the proc causing the exception makes sense.
Holgerwa
@Holgerwa: But then I don't understand why you suggest it should just skip to the next line of the current procedure. Why would it ever do that? That suggests *ignoring* the exception.
Jon Skeet
Jon: I didn't want to suggest this as a better way, I was merely wondering why it would jump to the end of the proc and without knowing of a hidden finally statement couldn't find a reason. Knowing this of course it's clear now. I just didn't see a "mechanism" that would cause it to do so.
Holgerwa
@Holgerwa: Okay, that makes sense then :)
Jon Skeet
+3  A: 

Throwing an exception is a way of saying "Something unexpected happening. I don't know how to handle this". In such case it it better not to do anything (other than throwing the exception) than to try to continue, not knowing if what you're doing is correct.

In real life you have the same kind of thing: If someone asks you to count to 10 in Hebrew (or some language you don't know), you just say you don't know. You don't go ahead and try anyway.

tehvan
+5  A: 

In general, an uncaught exception will execute a hidden "finally" in each function on the stack, as it "unwinds" up to an exception handler. This cleans up local variables in each stackframe. In languages like C++ with the Resource Acquisition Is Initialization paradigm, it will also cause destructors to run.

Eventually, somewhere up the callstack, the exception will be caught by a handler. If there's no explicit one, the system-provided one will kill the process, because what else can it reasonably do?

George V. Reilly
That's EXACTLY what happens in Delphi. The "end" line is what the debugger highlights to represent the function's epilogue, where strings and other compiler-managed types get destroyed. It's implemented as a try-finally block.
Rob Kennedy
A: 

It has to unwind the stack to find a handler.

I do agree it's very annoying behavior. Continuing isn't an option but it sure would make life easier if the debugger was pointing to the spot that threw it with the local variables still intact. Obviously, the next step would be to the hidden finally, not to the next line.

I just want to be able to examine everything I can about what caused it. I was just fighting this not very long ago. Text parsing, I KNEW the offending string contained no non-numeric characters (sanity limits mean the overflow case should never happen, it's my data file, all I'm worried about is oopses) and so I didn't put an exception handler around the StrToInt--what's this nonsense about it not being a valid number????? Yup--the routine wouldn't call it with anything non-numeric in the buffer--but an empty string has nothing non-numeric in it!

Loren Pechtel