access violation

Started by
6 comments, last by Simagery 18 years, 3 months ago
If I get a AVs address,how to find function in source code in c++? I found a article about it,I can not find it again. in delphi CPU WINDOW do the job but in vc how to do?
Advertisement
Use the debugger. Select debug (or Win32 Debug or whatever) from a drop down on the toolbar list then hit F5 or the 'play' icon
Quote:Original post by dave_
Use the debugger. Select debug (or Win32 Debug or whatever) from a drop down on the toolbar list then hit F5 or the 'play' icon


this will get a address .

I wanna know which function fail according to the address.
I do not wanna step track.
I don't know where the setting is in VC++, but you need to create a .map file as part of the project. A .map file is basically a map of the executeable file. One of the items in the file will be a list of the functions in the exe sorted by their address in the exe. If the AV is due to something in your code, the faulting address will fall inside the range of addresses found on that list. To find the function, compare the faulting address with each function address. The first function you find with an address greater than the faulting address is the function after the function with the fault. So, the function with the fault is the function before that one.

You can't make the .map file after the fact. It has to be made during compilation along with the .exe (or .dll) and for it to remain current it has to be remade everytime the .exe is compiled. For release versions of .exe files, a .map file may be the only debug information you have.

Most of the functions in your exe will have addresses relatively near 0x00400000. If the faulting address is far away from there, it's most likely that the fault occured in a .dll file - possibly even a system dll. If that is the case, it's quite likely that the code is passing a bad parameter to an API function. A helpful tool for determining which .dll is Dependency Walker. This tool lists the load addresses for the various dlls in a program. Look for Preferred Base and Actual Base in the module list table. For example, on Windows XP Sp2, Kernel32.dll has a preferred base 0x7C800000. If the faulting address is near that address, then examine the list of exported functions from that dll, looking at their EntryPoint values. These values are relative to the base of the dll, so you'll have to add them to the actual base of the dll to get the actual function address. Do the same with these function addresses as with the function addresses in the .map file.

A very helpful book on debugging is Debugging Applications by John Robbins. You might be able to find an ebook version of it if you look in the right places.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Quote:Original post by LessBread
I don't know where the setting is in VC++, but you need to create a .map file as part of the project. A .map file is basically a map of the executeable file. One of the items in the file will be a list of the functions in the exe sorted by their address in the exe. If the AV is due to something in your code, the faulting address will fall inside the range of addresses found on that list. To find the function, compare the faulting address with each function address. The first function you find with an address greater than the faulting address is the function after the function with the fault. So, the function with the fault is the function before that one.

You can't make the .map file after the fact. It has to be made during compilation along with the .exe (or .dll) and for it to remain current it has to be remade everytime the .exe is compiled. For release versions of .exe files, a .map file may be the only debug information you have.

Most of the functions in your exe will have addresses relatively near 0x00400000. If the faulting address is far away from there, it's most likely that the fault occured in a .dll file - possibly even a system dll. If that is the case, it's quite likely that the code is passing a bad parameter to an API function. A helpful tool for determining which .dll is Dependency Walker. This tool lists the load addresses for the various dlls in a program. Look for Preferred Base and Actual Base in the module list table. For example, on Windows XP Sp2, Kernel32.dll has a preferred base 0x7C800000. If the faulting address is near that address, then examine the list of exported functions from that dll, looking at their EntryPoint values. These values are relative to the base of the dll, so you'll have to add them to the actual base of the dll to get the actual function address. Do the same with these function addresses as with the function addresses in the .map file.

A very helpful book on debugging is Debugging Applications by John Robbins. You might be able to find an ebook version of it if you look in the right places.


thanks
but how do I make map file? in vc ide where to set to make it?

Visual C++ Linker Options: /MAP (Generate Mapfile)
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
What I normally do is look at the call stack, and see which function gets call that cause teh AV, the break into that function and debug that function.
Assuming you don't have a call stack, and you're not in the debugger (for example, you've got the details of an access violation for an end-user), here's how you can use the map file:

  1. The access violation will give you the address of the instruction (normally, at least WindowsXP does if you look at the "details" for the violation). Looking at the details under Windows XP this information is labeled "Offset."

  2. Take the map file you generated (see earlier post). Looking inside the map file, you'll see a "Preferred load address" near the top. Make note of this.

  3. Later in the map file you'll have a list of all of your functions. In the first column you have the "address" of the function, then the "symbol" for the function, followed by "Rva+address". This last one is of interest to us.

  4. If you have an access violation dialog like the one I get on Windows XP, then you have an offset. Otherwise, you may have an actual memory address. If all you have is an actual memory address, you may have a "base address" somewhere else in the access violation's details. If you do, subtract out this base address. If not, you can *hope* that Windows used the preferred base address that we saw earlier in the map file. I have no idea how often its the case that it either does or does not use this base address (in my test case it did). Try subtracting out that preferred load address.

  5. Now you have a relative offset into your executable. Looking at the "rva+address" column of the map file, that offset should fall after one of the addresses listed (but before the following function). In my case, it was _main (the only function I wrote in my test case). Note: "rva+address" values are offsets with the "preferred load address" added in (hence the "+").


That won't give you a line number, but it'll give you a function. But you know the function name and the number of bytes after the function's entry point, so you then just need to check out the disassembly of your code.

Hope that helps, none of that is "official" knowledge, I just poked at MSVC for a few minutes and that's what I discovered.

This topic is closed to new replies.

Advertisement