65.9K
CodeProject 正在变化。 阅读更多。
Home

如何根据偏移量确定相应的源代码行

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (33投票s)

2003 年 7 月 23 日

2分钟阅读

viewsIcon

131543

downloadIcon

1597

如果你知道可执行文件中的偏移量,你可以确定它在源代码文件中对应的位置。

Sample error

引言

假设你的客户向你报告了一个带有偏移量的错误,你可以确定导致该错误的源代码行。本文档解释了如何使用发布版可执行文件中的偏移地址来检测错误的源代码行。

这种方法的优点是不需要向客户发送任何额外的程序或调试可执行文件,也不需要像其他文章中描述的那样重新构建你的程序。缺点是,你需要花费一些额外的精力来研究两种额外的编译器生成的文件类型:一个 .map 文件和一些 .cod 文件。

一个 *.map 文件基本上包含编译函数的基地址。一个 *.cod 文件通常包含汇编代码、机器代码和源代码,如果你应用以下设置的话。

使用代码

  1. 打开提供的演示项目,或者使用向导创建一个新的 MFC 对话框应用程序,并添加一些可能导致崩溃的代码。提供的项目包含一个点击时会崩溃的按钮。从“生成”->“设置活动配置”中选择“发布”。
  2. 项目 -> 设置 -> . 在“C/C++”下,选择“Listing Files”类别。将“Listing File type:”设置为“Assembly, Machine Code, and Source”。这个选项会强制编译器为每个源代码文件分别生成一个 Source_File_Name.cod 文件。
  3. 再次选择项目 -> 设置 -> . 在“链接”下,选择“Debug”类别。选中“Generate map file”,然后点击“确定”。这个选项会强制编译器生成一个 Project_Name.map 文件。
  4. 提供的项目可执行文件在地址 148f 处生成错误。打开 map 文件,确定包含地址 148f 处的代码的函数。

    以下是一些示例 map 文件中的行。

     0001:00000470   ?OnQueryDragIcon@CDebugSampleDlg@@IAEPAUHICON__
                                     @@XZ 00401470 f   Debug SampleDlg.obj
     0001:00000480   ?OnButton1@CDebugSampleDlg@@IAEXXZ 
                                     00401480 f   Debug SampleDlg.obj
     0001:000004a0   ?BeginModalState@CWnd@@UAEXXZ 004014a0 
                                     f i Debug SampleDlg.obj

    开头的 '1' 是段地址。因此,包含地址 48f 处的代码的函数是 OnButton1,它从地址 480 开始。

  5. 在 cod 文件中搜索字符串 OnButton1。找到该函数的实现。在该列表中,诸如 ; 174 : 之类的表达式对应于源代码中的行号。

    Debug SampleDlg.cod 文件包含以下行

    ?OnButton1@CDebugSampleDlg@@IAEXXZ PROC NEAR   
                                ; CDebugSampleDlg::OnButton1, COMDAT
    
    ; 174  : {
    
      00000    83 ec 0c     sub     esp, 12            ; 0000000cH
    
    ; 175  :     // TODO: Add your control notification handler code here
    ; 176  :     
    ; 177  :     // Some garbage code here {
    
    ...
    
    ; 182  :     //    }
    ; 183  :     
    ; 184  :     *( (int *) 0x0000) = 1;
    
      0000f    c7 05 00 00 00
        00 01 00 00 00     mov     DWORD PTR ds:0, 1
    
    ; 185  : }
  6. 从函数开始地址中减去发生错误的偏移量:148f - 1480 = fh。源代码在第 000f 行生成机器代码,该行存在于编号为 182-184 的源代码行中。也就是说
    ; 183  :     
    ; 184  :     *( (int *) 0x0000) = 1;
    
      0000f    c7 05 00 00 00
        00 01 00 00 00    mov   DWORD PTR ds:0, 1

    错误隐藏在 OnButton1 函数的第 *( (int *) 0x0000) = 1; 行。

如果你觉得这篇文章有用,或者知道更好的方法,请告诉我。

历史

  • 2003年7月21日:首次发布。
© . All rights reserved.