Guard page exceptions in Delphi? - 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.

Related

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.

Delphi - Why is TObject.InitInstance public?

I'm somewhat new to Delphi, and this question is just me being curious. (I also just tried using it by accident only to discover I'm not supposed to.)
If you look at the documentation for TObject.InitInstance it tells you not to use it unless you're overriding NewInstance. The method is also public. Why not make it protected if the user is never supposed to call it?
Since I was around when this whole Delphi thing got started back around mid-1992, there are likely several answers to this question. If you look at the original declaration for TObject in Delphi 1, there weren't any protected/private members on TObject. That was because very early on in the development of Delphi and in concert with the introduction of exceptions to the language, exceptions were allocated from a different heap than other objects. This was the genesis of the NewInstance/InitInstance/CleanupInstance/FreeInstance functions. Overriding these functions on your class types you can literally control where an object is allocated.
In recent years I've used this functionality to create a cache of object instances that are literally "recycled". By intercepting NewInstance and FreeInstance, I created a system where instances are not returned to the heap upon de-allocation, rather they are placed on a lock-free/low-lock linked list. This makes allocating/freeing instances of a particular type much faster and eliminates a lot of excursions into the memory manager.
By having InitInstance public (the opposite of which is CleanupInstance), this would allow those methods to be called from other utility functions. In the above case I mentioned, InitInstance could be called on an existing block of memory without having to be called only from NewInstance. Suppose NewInstance calls a general purpose function that manages the aforementioned cache. The "scope" of the class instance is lost so the only way to call InitInstance is of it were public.
One of these days, we'll likely ship the code that does what I described above... for now it's part of an internal "research" project.
Oh, as an aside and also a bit of a history lesson... Prior to the Delphi 1 release, the design of how Exception instances were allocated/freed was returned to using the same heap as all the other objects. Because of an overall collective misstep it was assumed that we needed to allocate all Exception object instances to "protect" the Out of memory case. We reasoned that if we try and raise an exception because the memory manager was "out of memory", how in the blazes would we allocate the exception instance!? We already know there is no memory at that point! So we decided that a separate heap was necessary for all exceptions... until either Chuck Jazdzewski or Anders Heijlsberg (I forget exactly which one), figured out a simple, rather clever solution... Just pre-allocate the out of memory exception on startup! We still needed to control whether or not the exception should ever actually be freed (Exception instances are automatically freed once handled), so the whole NewInstance/FreeInstance mechanism remained.
Well never say never. In the VCL too much stuff is private and not virtual as it is, so I kinda like the fact that this stuff is public.
It isn't really necessary for normal use, but in specific cases, you might use it to allocate objects in bulk. NewInstance reserves a bit of memory for the object and then calls InitInstance to initialize it. You could write a piece of code that allocates memory for a great number of objects in one go, and then calls InitInstance for different parts of that large block to initialize different blocks in it. Such an implementation could be the base for a flyweight pattern implementation.
Normally you wouln't need such a thing at all, but it's nice that you can if you really want/need to.
How it works?
The fun thing is: a constructor in Delphi is just some method. The Create method itself doesn't do anything special. If you look at it, it is just a method as any other. It's even empty in TObject!
You can even call it on an instance (call MyObject.Create instead of TMyObject.Create), and it won't return a new object at all. The key is in the constructor keyword. That tells the compiler, that before executing the TAnyClass.Create method, it should also construct an actual object instance.
That construction means basically calling NewInstance. NewInstance allocates a piece of memory for the data of the object. After that, it calls InitInstance to do some special initialization of that memory, starting with clearing it (filling with zeroes).
Allocating memory is a relatively expensive task. A memory manager (compiled into your application) needs to find a free piece of memory and assign it to your object. If it doesn't have enough memory available, it needs to make a request to Windows to give it some more. If you have thousands or even millions of objects to create, then this can be inefficient.
In those rare cases, you could decide to allocate the memory for all those objects in one go. In that case you won't call the constructor at all, because you don't want to call NewInstance (because it would allocate extra memory). Instead, you can call InitInstance yourself to initialize pieces of your big chunk of memory.
Anyway, this is just a hypotheses of the reason. Maybe there isn't a reason at all. I've seen so many irrationally applied visibility levels in the VCL. Maybe they just didn't think about it at all. ;)
It gives developers a way to create object not using NewInstance (memory from stack/memory pool)

Delphi obtain stack trace after exception

I'm trying to figure out how to obtain a stack trace after an exception is thrown in Delphi. However, when I try to read the stack in the Application.OnException event using the function below, the stack already seems to be flushed and replaced by the throwing procedures.
function GetStackReport: AnsiString;
var
retaddr, walker: ^pointer;
begin
// ...
// History of stack, ignore esp frame
asm
mov walker, ebp
end;
// assume return address is present above ebp
while Cardinal(walker^) <> 0 do begin
retaddr := walker;
Inc(retaddr);
result := result + AddressInfo(Cardinal(retaddr^));
walker := walker^;
end;
end;
Here's what kind of results I'm getting:
001A63E3: TApplication.HandleException (Forms)
00129072: StdWndProc (Classes)
001A60B0: TApplication.ProcessMessage (Forms)
That's obviously not what I'm looking for, although it's correct. I'd like to retrieve the stack as it was just before the exception was thrown, or in other words the contents before (after would do too) the OnException call.
Is there any way to do that?
I am aware that I'm reinventing the wheel, because the folks over at madExcept/Eurekalog/jclDebug have already done this, but I'd like to know how it's done.
It is not possible to manually obtain a viable stack trace from inside the OnException event. As you have already noticed, the stack at the time of the error is already gone by the time that event is triggered. What you are looking for requires obtaining the stack trace at the time the exception is raised. Third-party exception loggers, like MadExcept, EurekaLog, etc handle those details for you by hooking into key functions and core exception handlers inside of the RTL itself.
In recent Delphi versions, the SysUtils.Exception class does have public StackTrace and StackInfo properties now, which would be useful in the OnException event except for the fact that Embarcadero has chosen NOT to implement those properties natively for unknown reasons. It requires third-party exception loggers to assign handlers to various callbacks exposed by the Exception class to generate stack trace data for the properties. But if you have JclDebug installed, for instance, then you could provide your own callback handlers in your own code that use JCL's stack tracing functions to generate the stack data for the properties.
I'd like to retrieve the stack as it was just before the
exception was thrown, or in other words the contents before
(after would do too) the OnException call.
Actually, you don't want the stack before the OnException call. That's what you've already got. You want the stack at the point at which the exception was raised. And that requires the stack tracing to happen ASAP after the raise. It's too late in the OnException call because the exception has propagated all the way to the top-level handler.
madExcept works by hooking all the RTL functions that handle exceptions. And it hooks the lowest level functions. This takes some serious effort to bring about. With these routines hooked the code can capture stack traces and so on. Note that the hooking is version specific and requires reverse engineering of the RTL.
What's more the stack walking is very much more advanced than your basic code. I don't mean that in a derogatory way, it's just that stack walking on x86 is a tricky business and the madExcept code is very well honed.
That's the basic idea. If you want to learn more then you can obtain the source code of JclDebug for free. Or buy madExcept and get its source.

How do you name and organize your exceptions?

When introducing new exception types I am always a but unsure how to do this correctly. Is there a common convention? How do you do it?
I am interested in the scope you organize them (Keep them in the unit they are used in? Have a unit on component level? Package level? Application?)
This also influences naming. How much context do you include? Is it better to make them very specific (like EPersonIDNotFoundError) or try to make them reusable (like ENotFoundError)?
And what about the suffix "Error" - when should I add it and when leave it? I cannot see the logic e.g. in Classes.pas:
EWriteError = class(EFilerError);
EClassNotFound = class(EFilerError);
EResNotFound = class(Exception);
The only real convention I know of, is to prefix them with E.
I haven't really given it much thought in the past, but now I think of it, it seems to me that both Error and Exception are commonly used as a postfix. If you mix them, I'd say that Exception relates to something that goes wrong unexpectedly, like a connection that is broken, or a file that turns out to be unreadable, while an error relates more to wrong input, for instance a number was expected, but someone typed text.
The VCL seems to follow certain conventions too, but it seems to add a postfix only if it wouldn't be clearly and error without it, for instance
EConvertError, EMathError, EVariantError
vs
EAccessViolation, EInvalidPointer, EZeroDivide
The latter describe the error itself, where the first list need the postfix to indicate an error in a certain process or entity.
These examples are found in SysUtils, maybe you can take a look there, because it contains many exception classes as well as base classes for an even larger amount of exception. Very few of those end in Exception, except for some very specific errors that indeed you hope to never come across, like EHeapException and ESafecallException.
When creating a new exception I make it application wide. I start from the most detailed error to the most general, like class(Exception) and I name them accordingly.
So, in your example, I would use EPersonIDNotFoundError, ENotFoundError, Exception.
It really depends on how much detail you want from your error messages and what you include in your log (if you keep a log of errors)
Normally for simple applications you can get away with Exception.Create('ErrorMessage'). Where exceptions get powerful is being able to detect the kind of response required by looking at the class. Delphi already does this by the Abort procedure, which raises EAbort. EAbort is 'special' in that it does not trigger an 'error' as such, i.e. it is a kind of 'silent' exception. You can use this class-specific action to examine an exception and do different things. You could create a EMyWarning, EMyVeryNastyError etc, each descended from the basic Exception type.
Further, you can define a new exception class to carry more information out to the point where the exception is trapped. For example with the code (not checked):
EMyException = class( Exception )
constructor Create( const AErrorMessage : string; AErrorCode : integer ); reintroduce;
PUBLIC
ErrorCode : integer
end;
constructor EMyException.Create( const AErrorMessage : string; AErrorCode : integer );
begin
inherited Create( AErrorMessage );
ErrorCode := AErrorCode;
end;
You now have the possibility to set 'ErrorCode' when you raise the exception and you have it available when the exception is caught. Exceptions are pretty powerful.
Which scope to organize them in?
Use one unit for the whole application where you try to fit in the most general exceptions. Everything else goes into the unit where the exception is thrown. If you need these exceptions in other units then move them to a common unit used by the subsystem you are working on.
How about naming?
Try to make one or two levels of "general" exceptions like ENotFoundError. Put these in the application global file. Don't try too hard to generalize because you can't know what exception will come later requiring you to change everything. Create specialized exceptions on unit level inheriting from the global ones.
What about "Error" postfix?
Stop thinking about it. Add it. Unless it sounds stupid.

Delphi Win32 Programming/Access Violation problems

I wasn't entirely sure how to name this, so apologies in advance.
You see, I'm trying to teach myself Win32/DirectX programming, utilizing Delphi (my language of choice) using this site - http://rastertek.com/tutindex.html
Of course, the site being all in C++, I have to port it to Delphi. It seemed simple enough, at first. I'm on the second tutorial for DirectX 11 - setting up the framework and getting the initial window to show up.
Now for my actual problem. I was getting Access Violation errors. So I found and started to use MadExcept to try and find out what was going on. So it tells me the lines, but I'm clueless as to how to solve the issues at hand.
I have everything set up to mimic as well as I can the original source code. The only real difference being that in the instances where a pointer to a class for a variable, such as the case with m_input, m_grahics, and system, I made a type for those. So I have the TSystemClass, TInputClass, TGraphicsClass, and then I have PSystemClass, etc. that = ^TSystemClass, etc. I figured that this would make things a bit simpler and more neater. On a side note, I assume it should be said, but I for the construction of the copy constructors made the initial classes inherit from TPersistent so I could use it's Assign procedure.
So, back to the Access Violation errors. So first, the problem was in the main program with system being of type PSystemClass. So for a reason unknown to me, when I tried to use system.create, it was at that very instant, creating the access violation. I then realized however that I wasn't assigning system the system.create. So I tried this, and it said that, and rightfully so I suppose, at compile time an error that the two were incompatible since system.create is of type TSystemClass, and system is of PSystemClass. So I tried typecasting it, and that worked. but once again, still getting the dreaded access violations.
So then I had an odd idea, maybe I should call the regular constructor right from the TSystemClass itself. And I tried, needed to typecast again. So I did. And it worked! No longer an access violation error there! Now... New problem! Or rather in this case "problems". There's 3 things now listed in the call stack in MadExcept. The first one:
m_hinstance := GetModuleHandle(nil);
It's saying that this is causing an access violation error. Though why is this, exactly? From what I understand and have read, if GetModuleHandle is set to null/nil, it should retrieve the handle for the file that called it, right? And from what the documentation says, that should be executable.
However note: I'm not sure if the fact that I have the main program, the systemclass stuff, the inputclass stuff, and the graphicsclass stuff, all in different program/unit files to mimic the nature of the original source code. So is this possibly what's causing it? And if so how would I fix it? By putting all of the code from the unit files into the main program file? Though that, in my own personal opinion, would be quite messy and unintuitive.
The next one baffles me even more.
InitializeWindows(ScreenWidth, ScreenHeight);
I'm not dealing with anything other then a function to register the window class and set things up for the window and all here. So I'm not quite sure what the problem here is since it only deals with 2 parameters and they're defined and all already before it's called. So I'm not quite sure what the problem here is at all and what exactly is causing the access violation.
and then finally the final one is in the main program:
return := system.initialize;
Return is what I used in all instances of the result variable of the original source code, as result is of course a built in variable of all functions.
I suppose if system is never able to properly do what it's meant to do then something could/should happen here. Likewise, because I used TSystemClass.Create (typecasted to PSystemClass) earlier to create system would that do anything here? And is it possibly linked to the other two because they're not able to do their own thing properly?
And on a final note; there is one last thing actually on the call stack in MadExcept.
It says Kernel32.dll in the module section, but aside from the main thread, it lists nothing else. (If this information is needed I'll gladly put it up).
Thanks in advance to anyone who's read this far and I hope to find some help on this problem so I may further my studies.
You're instantiating your classes all wrong. Here's an example from TSystemClass.Initialize:
m_Input := PInputClass(m_Input.create);
That's a variable you declared as a PInputClass.
Earlier, in TSystemClass.Create, you initialized that variable:
m_Input := nil;
So, since you have a null reference, it should be clear that you can't call any methods on it. In particular, you cannot call Create on it. Instead, call Create on the class you want to instantiate: TInputClass.Create.
That constructor returns a value of the type you constructed, a TInputClass. It doesn't return a PInputClass, so your type-cast is wrong. As Cosmin's comment explains, Delphi object variables are already pointers. It's exceedingly rare to have to declare a pointer type based on Delphi classes. The correct code is this:
m_Input := TInputClass.Create;
After that line, you check whether m_Input is null. You never have to do that in Delphi; a constructor either returns a valid object, or it doesn't return at all. If there's a problem constructing an object, the constructor throws an exception and the assignment statement never executes. (The original C++ code does it wrong, too. The new operator hasn't returned a null pointer on failure for over a decade, long before anyone was in a position to start writing a DirectX 11 tutorial.)
You should first of all try to get rid of the TPersistent inheritance. If you want to pass an object to a library its interface should be exactly the same as the original that is used in C++. By inheriting from TPersistent you take a whole lot of load into your class that might be not needed or might even be the reason of your problems.
Additionally it would help if you posted the exact output of the exceptions. Or even the CallStack. That might help tracing down the error.

Resources