- 02 Apr 2024
- 2 Minutes to read
- Print
- DarkLight
- PDF
Error: The memory could not be "written".
- Updated on 02 Apr 2024
- 2 Minutes to read
- Print
- DarkLight
- PDF
You receive the following error on certain Pharos applications:
The instruction at 0x00401320" referenced memory at "0x00000000". The memory could not be "written".
The instruction at "0x00401320" referenced memory at "0x00000000". The memory could not be "written".
Here's how you can track down the problem:
First, you need to find out if the instruction memory address corresponds to the executable, a Pharos DLL, part of the OS, etc. The easiest way to do this is to use SysInternals "Process Explorer".
Steps are:
Restart the crashed program.
Start Process Explorer.
On the top pane, select the program (after restarting it).
Click the "View DLLs" button on the tool bar.
The lower pane will now show a list of DLLs.
Right click on the column labels bar on the lower pane.
Click on Select Columns. On dialog to DLL tab. Check the "Base" "Image Base" and "Size" boxes. Close the dialog.
Lower pane now shows the memory locations the executable and it's DLLs are at.
From this, it's a simple matter to figure out if the instruction address is in the executable or a pharos DLL. (Note, if error is in the OS, or a 3rd party DLL, there's not much more we can do at this stage.)
Assuming the address IS in the executable (or a Pharos DLL), then we go to the map file to find the function (and even the source file and line) the instruction corresponds to.
http://www.codeproject.com/debug/mapfile.asp describes the process in detail, but the essence is:
You want to find the part of the map file that looks like this:
Address | Publics by Value | Rva+Base | Lib:Object |
---|---|---|---|
0001:00000000 | _WinMain@16 | 00401000 f | MAPFILE.obj |
0001:000000c0 | ?MyRegisterClass@@YAGPAUHINSTANCE__@@@Z | 004010c0 f | MAPFILE.obj |
0001:00000150 | ?InitInstance@@YAHPAUHINSTANCE__@@H@Z | 00401150 f | MAPFILE.obj |
0001:000001b0 | ?WndProc@@YGJPAUHWND__@@IIJ@Z | 004011b0 f | MAPFILE.obj |
0001:00000310 | ?About@@YGJPAUHWND__@@IIJ@Z | 00401310 f | MAPFILE.obj |
0001:00000350 | _WinMainCRTStartup | 00401350 f | LIBC:wincrt0.obj |
0001:00000446 | __amsg_exit | 00401446 f | LIBC:wincrt0.obj |
0001:0000048f | __cinit | 0040148f f | LIBC:crt0dat.obj |
This is a list of the functions in your program, and where they are in memory. The column of importance is Rva+Base, which gives the starting address of the function. Go through this column, and find the first function with an address bigger than the crash address. The preceding entry in the MAP file is the function that had the crash.
E.g. Using the above example, the failing instruction is 0x00401310. The relevant lines from the map file are:
0001:00000310 | ?About@@YGJPAUHWND__@@IIJ@Z | 00401310 f | MAPFILE.obj |
0001:00000350 | _WinMainCRTStartup | 00401350 f | LIBC:wincrt0.obj |
So we know to look for a function called About(), in Mapfile.cpp. Demangling the C++ function name is left as an exercise.
To track the instruction to the specific line, refer to http://www.codeproject.com/debug/mapfile.asp
One note of caution: if the instruction is in a DLL, you need to check if the DLL has been rebased. That is, loaded into a memory location other than what it expects. When a DLL is rebased, Process Explorer will highlight the DLL in yellow. To allow for the displacement, find the actual address the DLL loaded and the DLLs preferred load address (given on the 3rd line of the Map file). Use the difference to adjust the instruction address, and look for the adjusted address in Rva+Base
E.g. Assume error message was The instruction at "0x00501320" referenced memory at "0x00000000". The memory could not be "written".
However, when we check Process Explorer, we find this memory location is a DLL that wants to load at 0x004000000, but has instead been loaded at 0x00500000, (i.e. It's been loaded 0x00100000 bytes higher than it expects.) Therefore, to find the value we're looking for in the map file, take 0x00501320, subtract 0x00100000, and look for 0x0040132.