Microsoft KB Archive/196755

= How to identify where a failure is occurring in your code by using the address in the error message that you receive =

Article ID: 196755

Article Last Modified on 6/8/2005

-

APPLIES TO


 * Microsoft Visual C++ 4.0 Standard Edition
 * Microsoft Visual C++ 4.2 Enterprise Edition
 * Microsoft Visual C++ 5.0 Enterprise Edition
 * Microsoft Visual C++ 6.0 Enterprise Edition
 * Microsoft Visual C++ 4.2 Professional Edition
 * Microsoft Visual C++ 5.0 Professional Edition
 * Microsoft Visual C++ 6.0 Professional Edition
 * Microsoft Visual C++ 6.0 Standard Edition

-



This article was previously published under Q196755



SUMMARY
This article describes how to identify where a failure is occurring in your code by using the address in the error message that you receive.

For example, a customer reports a crash while running a release version of your application, and the only information you have is the numeric address.



Technique 1 - Using a MAP file
If you can not generate debug information on all of the objects in your application, you can still identify the function where the crash is occurring. For example, one reason you might be unable to get debug information is if you are using a library that did not include it.

By using a MAP file you can identify the function that contains the code that is crashing. To generate the MAP file, use the /MAP linker switch when you build your release-mode build. If you have a crash in a debug build, you already have more effective information than a MAP file and should simply debug your application. You can also create a map file in the MSDev shell:


 * 1) In Project settings for the release configuration, click the Link tab.
 * 2) Under category General, select Generate mapfile.
 * 3) Rebuild your application.

Assume you start from an application error such as the following:

testcrash.exe - Application Error

The instruction at "0x004011a9" referenced memory at "0x00000000". The

memory could not be "written"

You would then look in the column of Rva+Base values and note where the location fits. The following is taken from a sample MAP file. To find this section in your own MAP file, search on "Rva+Base":   <... lines removed ...> Address           Publics by Value              Rva+Base   Lib:Object 0001:00000000  ?_GetBaseMessageMap@CTestcrashApp@@KGPBUAFX_MSGMAP@@XZ 00401000 f   testcrash.obj 0001:00000010      ?GetMessageMap@CTestcrashApp@@MBEPBUAFX_MSGMAP@@XZ 00401010 f testcrash.obj 0001:00000020      ??0CTestcrashApp@@QAE@XZ      00401020 f   testcrash.obj 0001:00000080      ??_ECTestcrashApp@@UAEPAXI@Z  00401080 f   testcrash.obj 0001:00000080      ??_GCTestcrashApp@@UAEPAXI@Z  00401080 f   testcrash.obj 0001:00000170      ?InitInstance@CTestcrashApp@@UAEHXZ 00401170 f   testcrash.obj 0001:00000210      ??1CTestcrashDlg@@UAE@XZ      00401210 f   testcrash.obj 0001:00000260      ?Serialize@CObject@@UAEXAAVCArchive@@@Z 00401260 f   testcrash.obj <... lines removed ...> The columns in a MAP are not always well aligned so it may be a little hard to read. The number following the function name indicates the starting address of the function. We find the function containing the crash by noticing that address 0x004011a9 falls after the start of ?InitInstance@CTestcrashApp@@UAEHXZ (start address is 00401170) and before the start of the next function ??1CTestcrashDlg@@UAE@XZ (start address is 00401210). The crash thus seems to be in InitInstance.

This method can usually be used to identify a function, but it won't narrow down the problem to a specific line or statement.

Technique 2 - Using a PDB file
If the crash is in your own code, then you can probably create a PDB file, which gives you much more accurate data on where the crash is occurring.

There are several settings that need to be changed to generate a useful PDB file:

 Save a copy of the MAP file created as described in Technique 1. In MSDev, click Project Settings for the release configuration. Click C++ tab, under the category General, under Debug info, select Program Database (the corresponding compiler switch is /Zi). Click the Link tab, under the category General, select Generate debug info (the corresponding linker switch is /debug). Make sure that "Use program database" is selected on the Link tab, category Customize (the corresponding linker switch is similar to the following:

/pdb:"Release/myproject.pdb" ).

 On the Link tab, in the Project Options box, append the following:

/OPT:ICF /OPT:REF

 Rebuild your application.</li> Use Windiff or FC to compare the MAP file generated at this step with the MAP file saved in step 1.</li> Compare the Rva+Base of the function where the crash occurred. If it has not changed after rebuilding in step 6, you can skip step 9.</li> If the Rva+Base has changed, calculate the difference in the start location of the function. Add this difference to the location of the reported crash so that you have an adjusted location, which will match the .exe and PDB you have just created. Use the adjusted value in all remaining steps.</li></ol>

You now have a PDB file that you can use to debug the released executable and determine exactly where the crash occurred:
 * 1) Load your project in MSDev (be sure to use the release configuration).
 * 2) Press F11 to step into your application.
 * 3) Press ALT+F9 to bring up the Breakpoints dialog box.
 * 4) Set a breakpoint at the location of the crash (be sure to include the "0x" at the beginning).
 * 5) Open the file containing the function that you identified in Technique 1; you should see the breakpoint location. This is where the crash occurred.

<div class="references_section">