Nothing more frustrating than an Access Violation error on a program compiled without managed code.
If you have worked with Delphi or C++ you know what I mean.
To make things even worse, you may have to refrain from using unhandled exception managers for different reasons, most often than not security. This is a common situation for installed software.
Many organizations see stack dumps as security holes in applications that can be used to facilitate cracking of the software.
How can you make troubleshooting easier if you don't have an exception manager capturing the full call stack?
A common technique used implies compiling your app with source code matching production, and then using your debugger tool to navigate to an specific address in memory. Different debuggers will offer different ways to do this.
In the case of Delphi there's at least a couple of ways:
- Use the main menu Search|Go to address... option
- Or, use the CPU/Assembly view, right click anywhere on the assembly view and select Go to address... context menu
Either way, this works... sometimes...
The problem is that any time you create a new project with an IDE, there's a project setting that goes often overlooked that is created always with the same value. The default value.
This setting is the "Image Base" of the binary you will be producing.
What is the Image Base?
In short, it's the address where a module will *tried* to be loaded. See the following articles for details:
The issue here is that if this setting is left unchanged, the OS will "relocate" your binary when it's loaded as the default address will likely be used by another module.
Of course when this happens, the likelihood that the binary is loaded at an address that matches the one in your machine where you intend to run the debugger is slim. You will do a Go to Address... punch in the address you got from your error message and most likely you will end up in lalaland.
To clarify, the address I mean you need to use to try to trace the location on the error is the highlighted in yellow below:
Now, if you set the ImageBase of your binary to something unique and acceptable (the value must be multiple of 64K), using Go to address... you will get to the exact place in the code (asm or source) where the error happened as long as the module was loaded in the same location while debugging.
Click OK, and you end up here:
As you can see, the memory address of the particular assembly instruction is highlighted, and it happens to be a few asm instructions below the line of code that generated the Access Violation:
s := PString(nil)^;
Where to do you change this ImageBase in your IDE?
Delphi:
In Visual Studio:
Hope this helps you with your Access Violation adventures.
Enjoy