Creating NonContinuable exception in delphi - delphi

I have an exception which its raise command causes stack overflow. I read this article in order to know what should I do: http://www.debuggingexperts.com/modeling-exception-handling
What I understood is the exception 0xc0000025 means attempt to catch an exception which is forbidden to be caught (EXCEPTION_NONCONTINUABLE_EXCEPTION). Am I right?
If so, I wish to know what cause the exception to be defined as non-continuable. The exception is defined in Pascal and derived from Exception object.
In addition, I failed to found where this exception is handled, and added by myself a try-catch block. The exception caught successfully. Why?
EDIT
I want to explain the specific situation I need help:
There is a C++ code which calls Pascal code, which has the exception definition, and raise command happens in it.
Before I put the try-catch block in the C++ code, the raise in Pascal causes 1000 times exception of EXCEPTION_NONCONTINUABLE_EXCEPTION until stack overflowed.
After I added the try-catch block in the C++ code, the raise in Pascal code returned to the catch block in the C++ code.
Now I have 2 questions:
Why process didn't stop on the first NONCONTINUABLE exception?
Why the catch block in C++ code didn't cause this exception?

You are correct that EXCEPTION_NONCONTINUABLE_EXCEPTION means the program attempted to continue from an exception that isn't continuable. However, it's not possible to define such an exception in Delphi, so the source of your problem is elsewhere.
Consider debugging the creation, raising, catching, and destruction of your custom exception type. If there are external libraries involved in your program, particularly any written in something other than Delphi, make sure they either know what to do with external exceptions, or are shielded entirely from exceptions.

Related

How does Delphi's try...except work for sub-procedures? Does exceptions handling work for sub-procedure?

I do not quite understand and I could not find the answer to the question bothering me. Can the try..except block catch and pass the sub-procedure exception?
Let's say that i have code:
try
ProcedureA;
except
on E : Exception do
...
end;
and code for ProcedureA
procedure ProcedureA;
begin
SubProcedureA;
SubProcedureB;
SubProcedureC;
...
end;
If SubProcedureB raises exception, will the exception be handled at the main ProcedureA level? Will SubProcedureC be performed? Will the exception be forwarded to procedure A unchanged? Or maybe there is a restriction on sub-procedures, for example, Sub-sub-sub-procedure will no longer pass an exception to the higher-level procedure?
Thank you for the information and I apologize if this is a beginner question (which I am). :)
If SubProcedureB raises exception, will the exception be handled at the main ProcedureA level?
Yes. When an exception is raised, it propagates up the call stack until a matching handler catches it. If no handler catches it, then the process will usually terminate.
Will SubProcedureC be performed?
Usually no, however on Windows at least, it is possible (but not with Delphi's except syntax) for an exception handler to instruct the system to return back to the original call site that raised the exception. This is useful in rare cases where an exception handler can actually fix the condition that caused the exception to be raised in the first place, allowing execution to continue from where it left off. But again, this is very rare.
Will the exception be forwarded to procedure A unchanged?
Usually yes. There is only 1 Exception object in memory, and it is passed to each exception handler on the call stack until a matching handler is found. That being said, it is possible for an exception handler to catch an exception, modify it (it is just an object in memory, after all), and then re-raise it to continue the search up the call stack for another handler. That is not the case in your example, but it is allowed.
Or maybe there is a restriction on sub-procedures, for example, Sub-sub-sub-procedure will no longer pass an exception to the higher-level procedure?
There is no such restriction.
Try except block catches the exception at any level. The exception is thrown up until it is processed.
Top level is Application.OnException event.

In the integrated debugger is there an implicit variable for exceptions

I would like to examine the exception in the debugger.
When I have
except on e:exception do
This is trivial, I can just examine the e variable
But, many exception handlers do not have an on e:exception clause.
Is there a special variable such as $exception that can be inspected, or some other method to inspect the exception that does not require changing the source.
I remember doing this (though memory can be faulty), but have not been able find a way to do this.
In the System unit there is a function named ExceptObject which returns the exception object that is currently active, or nil if no exception is active. The debugger is able to evaluate this function and so give you the information you need.

Transitioning from VB6 On Error to .Net Try...Catch

Our company has recently transitioned from VB6 to VB.NET. Unfortunately all the error handling remains as On Error GoTo. This has not made it easy to track down errors that customers send back to tech support. As of now, the blocks of code that the On Error surrounds is entire subroutines, not uncommonly hundreds of lines of code for one sub, and possibly making calls to other routines. My question is how to best go about converting to Try...Catch blocks. I assume I can just substitute On Error GoTo Errorline for try and Errorline for catch. But this seems like too much for one try...catch block to encompass.
VB6's big weakness with error-handling is that the runtime does not provide a way for your code to get at the execution stack (method A called method B called method C, etc.) when an exception occurs; even if your On Error block catches the exception, you code doesn't know "where it is". To get around that deficiency, VB6 programmers have learned to enclose every method, in every module, with a catch-all On Error block, sometimes so that their own code can keep track of the execution stack for logging purposes. There were even third-party tools that could be used to instrument your code with On Error blocks, for exactly that purpose (VB/Rig, VB-Failsafe).
.Net's Exception object, however, does provide a .StackTrack property that represents the execution stack to the point of failure, so it's no longer necessary to use On Error blocks in every method, just so you can learn where your code failed, post-mortem.
Here is one simple strategy you can use, as you transition:
First, as you suggested, replace all of your "boilerplate" On Error Goto Errorline / :Errorline with Try / Catch ex As Exception blocks. But, do this only in the "top-level" methods where execution can "begin". In VB, these are usually all of the Event methods in your forms that directly handle system events (_Click, _MouseDown, _Timer, etc.)
Second, remove all the boilerplate error handling from "lower-level" methods -- methods that are merely called from the "top-level" or other "lower-level" methods.
Now you have provided a "safety net" of Try/Catch exception handling that will protect your app from dying from an unhandled exception. When an exception does occur, even deep in the execution stack, your code will unwind back to the nearest Catch, usually one of your UI event-handler methods. But, you will have the ex.StackTrack property that documents the execution up to the failure, module by module, method by method, with the source code line-number at each level.
One exception to the above strategy is when you find an error-handling block that is not boilerplate -- it was written specifically to handle a certain error(s), and to respond specifically. Leave this code in place, but again replace the On Error Goto Errorline / :Errorline with Try / Catch ex As Exception.
Here's a helpful rule of thumb: In your "top-level" methods, enclose the entire method in a "boilerplate" Try/Catch. In your "lower-level" methods, only write Try/Catch blocks around code where you can anticipate that certain exceptions will occur -- ones that your code wants to specifically respond to.
It's not unreasonable, or "too much", for a Try/Catch block to encompass large chunks of code. You should always strive to keep your methods as short as possible, but there is no reason to arbitrarily truncate or partition a long method just because it's enclosed by a Try/Catch.

How to catch exceptions in initialization section of Units in Delphi

I have a third party unit, witch raises an exception in initialization section of unit. How can I catch this exception on my application?
You cannot catch such a thing. The RTL executes the initialization sections and the rules are that no exceptions are to be raised. If exceptions are raised, then the fault is terminal.
Another way to thing about this is that when the initialization sections start to be executed, the language exception handling framework is not yet in place. That itself is installed as part of the RTL initialization.
The solution is to fix the code so that it obeys the rules. No exceptions raised in initialization sections.
Well, I suppose that you could hook the RTL code that executes initialization and perhaps replace that RTL code with exception resilient code. But what would be the point? If an initialization section raises an exception, the only sane assumption to be made is that the unit is not initialized and so not fit for use. Please don't try to bury your head in the sand and ignore the real problem. Fix the third party code.
You could try the OnExceptionEvent of the class TApplicationEvents, but I'm not sure if this works.

Guard page exceptions in Delphi?

There is a post by Raymond Chen, where he tells how bad IsBadXxxPtr function is by eating guard page exception.
I don't quite understand how it is applied to Delphi. Who and how should normally (i.e. without call to IsBadXxxPtr) process this exception?
I do know that Delphi inserts a code, which (for example) access a memory for large static arrays - exactly for this reason: to expand stack.
But if guard page exception is raised: who will handle it in a Delphi application? Can't I accidentally mess with it by using try/except in inappropriate way? Will Delphi's debugger notify me about these exceptions?
Windows structured exception handling (SEH) is has a two-phase structure. When an exception occurs, Windows first looks for a handler for the exception by following the registered exception handler chain (the head of which is stored in fs:[0] on x86, i.e. the first dword in the segment pointed to by the FS segment register - all that ugly 16-bit segment-offset logic didn't go away in 32-bit, it just became less relevant).
The search is done by calling a function with a particular flag, a pointer to which is stored in each exception frame on the stack. fs:[0] points to the topmost frame. Each frame points to the previous frame. Ultimately, the last frame on the list is one that has been provided by the OS (this handler will pop up a app-crash dialog if an unhandled exception reaches it).
These functions normally check the type of the exception, and return a code to indicate what to do. One of the codes that can be returned is basically, "ignore this exception and continue". If Windows sees this, it will reset the instruction pointer to the point of the exception and resume execution. Another code indicates that this exception frame should handle the given exception. A third code is "I'm not going to catch this exception, keep searching". Windows keeps on calling these exception filter functions until it finds one that handles the exception one way or the other.
If Windows finds one that handles the exception by catching it, then it will proceed to unwind the stack back to that handler, which consists of calling all the functions again, only passing in a different flag. It's at this point that the functions execute the finally logic, up until the handler which executes the except logic.
However, with the stack page guard exception, the process is different. None of the language's exception handlers will elect to handle this exception, because otherwise the stack growth mechanism would break. Instead, the filter search filters all the way through to the base exception handler provided by the OS, which grows the stack allocation by committing the appropriate memory, and then returns the appropriate return code to indicate that the OS should continue where it left off, rather than unwind the stack.
The tool and debugging infrastructure are designed to let these particular exceptions play out correctly, so you don't need to worry about handling them.
You can read more about SEH in Matt Pietrek's excellent article in MSJ from over a decade ago.
From looking at the comments, it looks to me like the "guard page exception" mess takes place entirely within the kernel, and is not something that you need to be worrying about from user space.
You've gotta remember that this article was written for C++, which is nowhere near as advanced as Delphi on the memory management front. The uninitialized pointers issue is a lot less of a mess in Delphi than in C/C++ for two reasons:
Delphi checks for uninitialized variables at compile time, which (for whatever reason) a lot of C compilers tend to have trouble with.
Delphi initializes all of its dynamic memory to 0, so you don't have random heap garbage to deal with that might look like a good pointer when it's really not. This means that most bad pointers give you access violations, which are easy to debug, instead of silently failing and corrupting memory.

Resources