Exception tracer solution?
Well, basically, if you use EurekaLog or any other exception tracer tool - you usually don't get just "Access Violation at address..." error message, but get a full bug report instead - including call stack and CPU state. However, if:- you're working with application without exception tracer
- application handles the error by itself without passing it to exception tracer
Address Lookup Tool
EurekaLog 7 as well as standalone EurekaLog Tools Pack have a Address Lookup Tool, which can help you to analyze addresses in the application and provide more information than just RAW address. You can launch this tool via Start menu (Programs\EurekaLog 7\Tools\Address Lookup) or via Tools\EurekaLog\Address Lookup IDE command (for EurekaLog 7 only, not applicable to Tools Pack).Note: there are 32-bit and 64-bit versions available. Use the tool of corresponding bitness. 32-bit Address Lookup will fail for 64-bit executable files and visa versa. 64-bit Address Lookup will only be installed on Win64 machine.
Address Lookup main window |
Next, select source of debug information to lookup. Usually, you should leave this option in its default position - "Auto". But you may want to use specific source, if you want to.
Note: support for madExcept information is experimental. It may not always work properly.
So, basically, you'll need at least one source of debug information available. If you use EurekaLog or other exception tracer solution - you already have one. If not - then you should supply it manually. The easiest way to do this - enable Map file = Detailed option on Linker page from project options in IDE (however, you'll need to rebuild your application).
Last thing to do - is to enter address itself. There is a catch though. Usually you get the full absolute address like "00515974" in the example above. This address can not be resolved into source code line. What you need is to have an offset from the start of the exe/DLL/BPL file. If you have .exe file - this task is easy: just substract $400000 from your address value and you're done:
Looking for source line from address (click on image to enlarge) |
$00515974 - $00400000 = $00115974
- and (as you can see) this is line number 128 in Unit99.pas, which belongs to TForm99.Button1Click
method. Location found.The Address Lookup Tool also supports include files:
Finding address inside .inc file (click to enlarge) |
- Provider - is the name of a EurekaLog debug information provider class, which was able to extract location information from your executable. If you leave "Auto" position in "Debug information source" option - then this can be any class among supported. If you select specific source - then this will be specific class only which corresponds to your choice.
- Location - a short description of found source code location. The same information is provided below this line with more detailed view:
- Unit - name of the unit with the code. This is the name as it appears into "
unit UnitName;
" statement. - Source - name of source file. Well, usually this is the same as unit name + .pas extension, but it is not necessary so. Think about .dpr file and .inc files. This is the file which you need to open, if you want to see source code location.
- Class - name of the class to which belongs method. If your address belongs to simple function - class name will be empty.
- Routine - name of the routine (procedure, function or method).
- Line - absolute line number inside "source" file.
- Unit - name of the unit with the code. This is the name as it appears into "
- Routine offset (bytes) - the difference (offset) between current address and routine's start in bytes.
- Routine offset (lines) - the difference (offset) between current line and first line in routine (in lines). This valus is useless if you use include files inside routine.
- Line offset (bytes) - the offset of code from the start of the current line in bytes. This is applicable for complex expressions in single line.
Working with addresses and offsets
Each executable module (exe or DLL) can be loaded into memory on different addresses, which are called base addresses. As you can guess, the same code will have different address if it was loaded on different base addresses. Thus, absolute address of code location is usually useless - because base address of executable on analyzing stage may be different than it was when the error was raised.For example, suppose there was an error in your DLL at address $6E775974 and DLL itself was loaded at address $6E660000 (which is base address for that DLL). Now, you want to find source code location for that DLL from address $6E775974. So, you load DLL and try to look for this address, but on your machine DLL is now loaded at address $642A0000 (not $6E660000 - as it was when error was raised). This means that address $6E775974 is useless - it will point to something else.
This is similar to the process address space isolation, when two processes can have different data on the same address. If you need to exchange data between processes you can't pass pointers (addresses) - you need to use relative offsets.
The similar approach is applied here too: find an offset of your code from the start of the module. In our imaginable example this is $6E775974 - $6E660000 = $00115974. And now - when you have offset - you can find exact the same location at any time. Just retrieve the base address of DLL (you can use Process Explorer tool to find it) and add our offset to it: $642A0000 + $00115974 = $643B5974 - and that is the final address of your code when you loaded DLL.
So that is how you work with addresses and offsets. To find source code location you need either:
- relative offset (1 value)
- absolute address and base address (2 values)
However, there is a quick tip: exe files are loaded at the same address in 99.99% cases. So you can blindly assume the base address of $00400000 for .exe files.
Manual search
If you can't use Address Lookup Tool (for example: you miss debug information source), then you still can get useful information from code, but only if you have source code for exact the same version of your application. To do that:- load your application into IDE (restore it to previous version, if needed);
- launch it via Run/Run (F9) command;
- put your application on pause (Run/Pause);
- use Search/Go to address command;
- enter absolute address (don't forget to add '$' prefix) into dialog;
- click OK;
Searching for address location manually (click to enlarge) |
You can download freeware EurekaLog Tools Pack here.