📄 如何通过崩溃地址找到出错的代码行(zt)——请斑竹加精~ vc-mfc - 基础类 - csdn社区 community_csdn_net.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0048)http://topic.csdn.net/t/20040416/08/2971645.html -->
<HTML lang=zh-CN xml:lang="zh-CN"
xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~ VC/MFC / 基础类 - CSDN社区 community.csdn.net</TITLE>
<META content=all name=robots>
<META http-equiv=Content-Language content=zh-CN>
<META http-equiv=Content-Type content="text/html; charset=utf-8"><LINK
href="如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~ VC-MFC - 基础类 - CSDN社区 community_csdn_net.files/topic.css"
type=text/css rel=stylesheet>
<SCRIPT
src="如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~ VC-MFC - 基础类 - CSDN社区 community_csdn_net.files/Topic.js"
type=text/javascript></SCRIPT>
<META content=".net c/c++ 文件 代码 源代码 编译器 选项 编译 崩溃 出错 VC/MFC 基础类" name=Keywords>
<META
content="这是从“VC编程经验总结7”中转出来的借花献佛——如何通过崩溃地址找到出错的代码行作为程序员,我们平时最担心见到的事情是什么?是内存泄漏?是界面不好看?……错啦!我相信我的看法是不会有人反对的--那就是,程序发生了崩溃! “该程序执行了非法操作,即将关闭。请与你的软件供应商联系。”,呵呵,这句 M$ 的“名言”,恐怕就是程序员最担心见到的东西了。有的时候,自己的程序在自己的机器上运行得好好的,但是到了别人的机器上就崩溃了;有时自己在编写和测试的过程中就莫名其妙地遇到了非法操作,但是却无法确定到底是源代码中的哪行引起的……是不是很痛苦呢?不要紧,本文可以帮助你走出这种困境,甚至你从此之后可以自豪地要求用户把崩溃地址告诉你,然后你就可以精确地定位到源代码中出错的那行了。(很神奇吧?呵呵。)首先我必须强调的是,本方法可以在目前市面上任意一款编译器上面使用。但是我只熟悉 M$ 的 VC 和 MASM ,因此后面的部分只介绍如何在这两个编译器中实现,请读者自行融会贯通,掌握在别的编译器上使用的方法。Well,废话说完了,让我们开始! :)首先必须生成程序的 MAP 文件。什么是 MAP 文件?简"
name=description>
<META content="MSHTML 6.00.2900.2096" name=GENERATOR></HEAD>
<BODY>
<DIV id=wrapper>
<DIV id=innerWrapper>
<TABLE class=CSDN-PHF id=CSDNPHL cellSpacing=1 cellPadding=0 border=0>
<TBODY>
<TR>
<TD><A href="http://www.csdn.net/" rel=external>CSDN首页</A></TD>
<TD><A href="http://news.csdn.net/" rel=external>新闻</A></TD>
<TD><A href="http://bbs.csdn.net/" rel=external><STRONG>论坛</STRONG></A></TD>
<TD><A href="http://groups.csdn.net/"
rel=external><STRONG>小组</STRONG></A></TD>
<TD><A href="http://blog.csdn.net/"
rel=external><STRONG>Blog</STRONG></A></TD>
<TD><A href="http://dev.csdn.net/" rel=external>文档</A></TD>
<TD><A href="http://download.csdn.net/" rel=external>下载</A></TD>
<TD><A href="http://book.csdn.net/" rel=external>读书</A></TD>
<TD><A href="http://tag.csdn.net/"
rel=external><STRONG>Tag</STRONG></A></TD>
<TD><A href="http://wz.csdn.net/" rel=external><STRONG>网摘</STRONG></A></TD>
<TD><A href="http://search.csdn.net/"
rel=external><STRONG>搜索</STRONG></A></TD>
<TD><A href="http://dotnet.csdn.net/"
rel=external><STRONG>.NET</STRONG></A></TD>
<TD><A href="http://java.csdn.net/"
rel=external><STRONG>Java</STRONG></A></TD>
<TD><A href="http://gamedev.csdn.net/" rel=external>游戏</A></TD>
<TD><A href="http://live.csdn.net/" rel=external>视频</A></TD>
<TD><A href="http://job.csdn.net/" rel=external>人才</A></TD>
<TD><A href="http://prj.csdn.net/" rel=external>外包</A></TD>
<TD><A href="http://www.dearbook.com.cn/" rel=external>第二书店</A></TD>
<TD><A href="http://www.programmer.com.cn/"
rel=external>程序员</A></TD></TR></TBODY></TABLE>
<DIV id=logo><A href="http://community.csdn.net/" rel=external><IMG class=logo
alt=CSDN社区
src="如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~ VC-MFC - 基础类 - CSDN社区 community_csdn_net.files/logo_csdn.gif"></A><A
href="http://www.sd2china.cn/default.html" rel=external><IMG alt=""
src="如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~ VC-MFC - 基础类 - CSDN社区 community_csdn_net.files/468.60_csdn.gif"></A><A
href="http://g.csdn.net/5021657" rel=external><IMG alt=""
src="如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~ VC-MFC - 基础类 - CSDN社区 community_csdn_net.files/120_60.gif"></A>
<IMG style="DISPLAY: none" alt=""
src="如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~ VC-MFC - 基础类 - CSDN社区 community_csdn_net.files/pv.htm">
</DIV>
<DIV id=navigation>
<DIV id=search>
<DIV id=innerSearch><INPUT id=key onfocus="value=''"><A
onclick="return Search()"
href="http://topic.csdn.net/t/20040416/08/2971645.html#">搜索</A> | <A
title=功能强大的网络收藏夹,一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐
href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏</A> | <A
onclick="return Print()"
href="http://topic.csdn.net/t/20040416/08/2971645.html#">打印</A> | <A
onclick="return Close()"
href="http://topic.csdn.net/t/20040416/08/2971645.html#">关闭</A> </DIV></DIV>
<DIV><A class=CSDNRoom href="http://community.csdn.net/"
rel=external>CSDN社区</A> > <A
href="http://community.csdn.net/Expert/ForumsList.asp?typenum=1&roomid=50"
rel=external>VC/MFC</A> > <A
href="http://community.csdn.net/Expert/ForumList.asp?typenum=1&roomid=5001"
rel=external>基础类</A> </DIV></DIV>
<DIV id=mainWrapper>
<DIV id=pageContent>
<DIV id=innerContent>
<H1>如何通过崩溃地址找到出错的代码行(ZT)——请斑竹加精~</H1>
<DIV class=author><A class=anchor name=Top>楼主</A>fzd999(花差花差)<INPUT class=star2 title="二星用户 该版得分小于等于30000分,大于10000分" type=button>2004-04-16
08:59:33 在 VC/MFC / 基础类 提问</DIV>
<P>这是从“VC编程经验总结7”中转出来的 <BR> <BR>
借花献佛——如何通过崩溃地址找到出错的代码行 <BR> <BR>
作为程序员,我们平时最担心见到的事情是什么?是内存泄漏?是界面不好看?……错啦!我相信我的看法是不会有人反对的--那就是,程序发生了崩溃!
<BR> <BR> “该程序执行了非法操作,即将关闭。请与你的软件供应商联系。”,呵呵,这句
M$
的“名言”,恐怕就是程序员最担心见到的东西了。有的时候,自己的程序在自己的机器上运行得好好的,但是到了别人的机器上就崩溃了;有时自己在编写和测试的过程中就莫名其妙地遇到了非法操作,但是却无法确定到底是源代码中的哪行引起的……是不是很痛苦呢?不要紧,本文可以帮助你走出这种困境,甚至你从此之后可以自豪地要求用户把崩溃地址告诉你,然后你就可以精确地定位到源代码中出错的那行了。(很神奇吧?呵呵。)
<BR> <BR> 首先我必须强调的是,本方法可以在目前市面上任意一款编译器上面使用。但是我只熟悉
M$ 的 VC 和 MASM
,因此后面的部分只介绍如何在这两个编译器中实现,请读者自行融会贯通,掌握在别的编译器上使用的方法。 <BR>
<BR> Well,废话说完了,让我们开始! :) <BR> <BR>
首先必须生成程序的 MAP 文件。什么是 MAP 文件?简单地讲, MAP
文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方、任何时候使用,不需要有额外的程序进行支持。而且,这是唯一能找出程序崩溃的地方的救星。
<BR> <BR> 好吧,既然 MAP
文件如此神奇,那么我们应该如何生成它呢?在 VC 中,我们可以按下 Alt+F7 ,打开“Project
Settings”选项页,选择 C/C++ 选项卡,并在最下面的 Project
Options 里面输入:/Zd ,然后要选择 Link 选项卡,在最下面的
Project Options 里面输入: /mapinfo:lines 和
/map:PROJECT_NAME.map 。最后按下 F7 来编译生成 EXE
可执行文件和 MAP 文件。 <BR> <BR> 在 MASM
中,我们要设置编译和连接参数,我通常是这样做的: <BR> <BR> rc
%1.rc <BR> ml /c /coff /Zd %1.asm
<BR> link /subsystem:windows /mapinfo:exports
/mapinfo:lines /map:%1.map %1.obj %1.res
<BR> <BR> 把它保存成 makem.bat ,就可以在命令行输入
makem filename 来编译生成 EXE 可执行文件和 MAP
文件了。 <BR> <BR> 在此我先解释一下加入的参数的含义: <BR>
<BR> /Zd 表示在编译的时候生成行信息 <BR> /map[:filename]
表示生成 MAP 文件的路径和文件名 <BR> /mapinfo:lines
表示生成 MAP 文件时,加入行信息 <BR> /mapinfo:exports 表示生成
MAP 文件时,加入 exported functions (如果生成的是
DLL 文件,这个选项就要加上) <BR> <BR>
OK,通过上面的步骤,我们已经得到了 MAP 文件,那么我们该如何利用它呢? <BR>
<BR> 让我们从简单的实例入手,请打开你的 VC ,新建这样一个文件: <BR>
<BR> 01
//****************************************************************
<BR> 02 //程序名称:演示如何通过崩溃地址找出源代码的出错行 <BR> 03
//作者:罗聪 <BR> 04 //日期:2003-2-7 <BR> 05
//出处:http://www.luocong.com(老罗的缤纷天地) <BR> 06
//本程序会产生“除0错误”,以至于会弹出“非法操作”对话框。 <BR> 07 //“除0错误”只会在
Debug 版本下产生,本程序为了演示而尽量简化。 <BR> 08
//注意事项:如欲转载,请保持本程序的完整,并注明: <BR> 09
//转载自“老罗的缤纷天地”(http://www.luocong.com) <BR> 10
//****************************************************************
<BR> 11 <BR> 12 void Crash(void)
<BR> 13 { <BR> 14 int i =
1; <BR> 15 int j = 0; <BR>
16 i /= j; <BR> 17 } <BR>
18 <BR> 19 void main(void) <BR>
20 { <BR> 21 Crash(); <BR> 22 }
<BR> <BR> 很显然本程序有“除0错误”,在 Debug
方式下编译的话,运行时肯定会产生“非法操作”。好,让我们运行它,果然,“非法操作”对话框出现了,这时我们点击“详细信息”按钮,记录下产生崩溃的地址--在我的机器上是
0x0040104a 。 <BR> <BR> 再看看它的 MAP
文件:(由于文件内容太长,中间没用的部分我进行了省略) <BR> <BR> CrashDemo
<BR> <BR> Timestamp is 3e430a76
(Fri Feb 07 09:23:02 2003) <BR>
<BR> Preferred load address is 00400000
<BR> <BR> Start Length Name Class
<BR> 0001:00000000 0000de04H .text CODE
<BR> 0001:0000de04 0001000cH .textbss CODE
<BR> 0002:00000000 00001346H .rdata DATA
<BR> 0002:00001346 00000000H .edata DATA
<BR> 0003:00000000 00000104H .CRT$XCA DATA
<BR> 0003:00000104 00000104H .CRT$XCZ DATA
<BR> 0003:00000208 00000104H .CRT$XIA DATA
<BR> 0003:0000030c 00000109H .CRT$XIC DATA
<BR> 0003:00000418 00000104H .CRT$XIZ DATA
<BR> 0003:0000051c 00000104H .CRT$XPA DATA
<BR> 0003:00000620 00000104H .CRT$XPX DATA
<BR> 0003:00000724 00000104H .CRT$XPZ DATA
<BR> 0003:00000828 00000104H .CRT$XTA DATA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -