首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

关于map文件中偏移地址的有关问题

2012-01-15 
关于map文件中偏移地址的问题刚看了几篇关于release文件出错时,根据map文件,确定出错函数的文章如http://b

关于map文件中偏移地址的问题
刚看了几篇关于release文件出错时,根据map文件,确定出错函数的文章


http://blog.csdn.net/fisker0303/archive/2006/04/15/664591.aspx

在这篇文章中,程序崩溃时,报告的错误
AppName:   crash_test.exeAppVer:   1.0.0.1ModName:   crash_test.exe  
ModVer:   1.0.0.1Offset:   000014a0  
偏移地址(offset)为14a0

但map文件中,是这样的
0001:00000480?OnOK@CCrash_TestDlg@@MAEXXZ   00401480   fCrash_TestDlg.obj  
0001:000004c0?BeginModalState@CWnd@@UAEXXZ   004014c0   f   i   Crash_TestDlg.obj  

作者紧接着写道:
“1480(OnOK地址)   <   14a0(出错地址)   <   14c0(BeginModalState地址),很显然,14a0的地址是在OnOK函数的地址范围内的,也就是说OnOK就是引起崩溃的函数。接下来再来确定出错的具体代码行。”

为什么偏移地址是1480,但却要对应map文件中的480?
为什么会差1K?


[解决办法]
0001:00000480?OnOK@CCrash_TestDlg@@MAEXXZ 00401480 fCrash_TestDlg.obj
看后面不是00401480 这个嘛
前面那个0001类似段地址,480类似偏移地址.
[解决办法]
<Debugging Applications for Microsoft .NET and Microsoft Windows>

Finding the Source File, Function Name, and Line Number
The algorithm for extracting the source file, function name, and line number from a MAP file is straightforward, but you need to do a few hexadecimal calculations when using it. As an example, let 's say that a crash in MAPDLL.DLL, the module shown in Listing 12-1, occurs at address 0x03901038.

The first step is to look in your project 's MAP files for the file that contains the crash address. First look at the preferred load address and the last address in the public function section. If the crash address is between those values, you 're looking at the correct MAP file.

To find the function, scan down the Rva+Base column until you find the first function address that 's greater than the crash address. The preceding entry in the MAP file is the function that had the crash. For example, in Listing 12-1, the first function address greater than the 0x03901038 crash address is 0x03901023, so the function that crashed is ?MapDLLHappyFunc@@YAPADPAD@Z. Any function name that starts with a question mark is a C++ decorated name.

You 're probably wondering why I didn 't mention the C++ name decoration when I talked about the calling convention name decoration in Chapter 6. Although both serve similar purposes, they come from different places. The calling convention name decoration simply tells the code generator how to generate the parameter pushes and stack cleanup, and it comes from the operating system definitions. C++ name decoration comes as a result of the language. Since you can have overloaded methods, the compiler has to have some way to differentiate them. It "decorates " the name with the return type, calling convention, and parameter information. That way it will know exactly what function you meant to call. To translate the name, pass it as a command-line parameter to the program UNDNAME.EXE, which is included with Visual Studio .NET. In the example, ?MapDLLHappyFunc@@YAPADPAD@Z translates into char * __cdecl MapDLLHappyFunc(char *). You probably could have figured out that MapDLLHappyFunc was the function name just by looking at the decorated name. Other C++ decorated names are harder to decipher, especially when overloaded functions are used.

To find the line number, you get to do a little hexadecimal subtraction by using the following formula:

(crash address) – (preferred load address) – 0x1000
Remember that the addresses are offsets from the beginning of the first code section, so the formula does that conversion. You can probably guess why you subtract the preferred load address, but you earn extra credit if you know why you still have to subtract 0x1000. The crash address is an offset from the beginning of the code section, but the code section isn 't the first part of the binary. The first part of the binary is the PE (portable executable) header and associated DOS stub, which is 0x1000 bytes long. Yes, all Win32 binaries still have that MS-DOS heritage in them.



I 'm not sure why the linker still generates MAP files that require this odd calculation. The linker team put in the Rva+Base column a while ago, so I don 't see why they didn 't just fix up the line number at the same time.

Once you 've calculated the offset, look through the MAP file line information until you find the closest number that isn 't over the calculated value. Keep in mind that during the generation phase the compiler can jiggle the code around so that the source lines aren 't in ascending order. With my crash example, I used the following formula:

0x03901038 – 0x03900000 – 0x1000 = 0x38
If you look through the MAP file in Listing 12-1, you 'll see that the closest line that isn 't over 0x38 is 39 0001:00000033 (Line 39) in MAPDLL.CPP.

热点排行