Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Oh, that's why they need to unwind the stack!? These things are what some take for granted and others don't even know how to ask. Thanks.


Unwinding the stack isn't necessary to find the exception handler. The language runtime code that finds the correct exception handler could just as easily walk the return pointers stored on the stack without modifying the stack pointer, frame pointer, or current return pointer. The reasons for unwinding the stack are (1) avoiding running out of stack space, particularly if the exception handler might itself throw (2) simplifying/optimizing the very common case of wanting the exception handler to unwind the stack.

It's vastly simpler in languages where you have resources that must be freed in the correct order (C++ destructors, Java monitors being released, etc.) to ensure correctness. It's difficult to correctly reason about mutating sate to recover from an error while other pieces of code might actually be holding the mutexes/monitors keeping that data safe.

It's an optimization, because you already have to do much of the work of stack unwinding (in the absence of destructors, monitor releasing, and the like) in order to find the correct exception handler.


In .NET, at least, the stack is not unwound when searching for the exception handler. It's walked to determine the handler, and then unwound before running that handler.

(This is particularly visible when debugging, because in the debugger, you still see the original stack at which the exception occurred when it's reported as unhandled - but it had to walk the stack and observe that there's no matching handler to determine that it's unhandled!)

This has an interesting side effect - since .NET catch-blocks can have filters, which are just predicates. Those predicates have to be executed while searching for the handler. Thus, they can observe the original stack before unwinding.

Win32 SEH is similar, wrt filter expressions in __except blocks.

I'm pretty sure that most C++ implementations are similar, except that they don't have filters, and so the two-phase process is not observable from within the application itself (but is observable under debugger).

Python, on the other hand, really does unwind the frames to find the handler - every function only looks at its own handlers, and if it can't find one, then it re-raises the exception to the caller. Thus, you can't readily tell if an exception is handled or unhandled in Python at the point where it occurs.


For .NET, this behavior is actually visible in VB.NET if I remember correctly, it exposes user-specified exception filters instead of only relying on types like C#.

Not sure why that was considered useful in Visual Basic, of all languages :).


It's visible in both languages these days, since both have exception filters. The difference is that VB had them from the very beginning, and C# only got them 5 years ago in version 6.


Oh, I haven't followed C# for quite some time, didn't know they had gotten them.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: