📄 csdn_文档中心_如何通过崩溃地址找到出错的代码行(zt).htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0053)http://www.csdn.net/develop/Read_Article.asp?id=27335 -->
<!--内容开始//--><HTML><HEAD><TITLE>CSDN_文档中心_如何通过崩溃地址找到出错的代码行(ZT)</TITLE>
<META content="MSHTML 5.00.3315.2870" name=GENERATOR>
<META content="text/html; charset=gb2312" http-equiv=Content-Type><LINK
href="CSDN_文档中心_如何通过崩溃地址找到出错的代码行(ZT).files/csdn.css" rel=stylesheet></HEAD>
<BODY bgColor=#ffffff leftMargin=0 topMargin=0 marginheight="0" marginwidth="0">
<DIV align=center>
<STYLE>.title0 {
COLOR: #ffffff; FONT-FAMILY: arial; FONT-SIZE: 17px; FONT-WEIGHT: bold; TEXT-DECORATION: none
}
A.title2:link {
COLOR: #000000; TEXT-DECORATION: none
}
A.title2:visited {
COLOR: #000000; TEXT-DECORATION: none
}
A.title2:active {
COLOR: #ff0000; TEXT-DECORATION: none
}
A.title2:hover {
COLOR: #ff0000; TEXT-DECORATION: none
}
</STYLE>
<SCRIPT language=JavaScript>
<!--
function submitlog(sign)
{
var types=document.alogon.type.options[document.alogon.type.selectedIndex].value;
if (document.alogon.name.value!="" && document.alogon.pass.value!="")
{
if (types!="1")
document.alogon.action="http://www.csdn.net/member/logon.asp";
else
document.alogon.action="http://expert.csdn.net/member/logon.asp";
if(sign)
document.alogon.submit();
//return true;
}
else
{
if (document.alogon.name.value=="")
alert("请输入用户名!");
if (document.alogon.pass.value=="")
alert("请输入密码");
return false;
}
return true;
}
function GetMyPass()
{
if (document.alogon.name.value!="")
{
document.alogon.action="http://www.csdn.net/member/getpass.asp";
document.alogon.submit();
}
else
{
alert("请在姓名输入框里输入用户名或注册EMAIL!");
}
}
// -->
</SCRIPT>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=770>
<TBODY>
<TR>
<TD bgColor=#004d99 height=25 width=20></TD>
<TD bgColor=#004d99> <A
href="http://www.csdn.net/member/login.asp"><FONT color=#ffff33>登
录..</FONT></A> <A href="http://www.csdn.net/member/zc.asp"
target=_blank><FONT color=#ffff33>[注 册]</FONT></A> <A
href="http://www.csdn.net/member/login.asp"><FONT
color=#ffff33>忘记密码</FONT> </A> <A
href="http://www.csdn.net/member/logonout.asp"><FONT
color=#ffff33>注销登录</FONT> </A></TD>
<TD align=right bgColor=#990000 width=20><IMG height=25
src="CSDN_文档中心_如何通过崩溃地址找到出错的代码行(ZT).files/top_1.gif" width=20></TD>
<FORM action=http://www.csdn.net/search_ok.asp method=post target=_blank>
<TD align=right bgColor=#009999 width=250><FONT color=#ffffff><FONT
color=#ffffff><INPUT class=FormText_1 name=search size=15> <SELECT
class=FormText_1 name=type> <OPTION selected value=1>新闻标题</OPTION>
<OPTION value=2>软件名称</OPTION> <OPTION value=3>商品名称</OPTION> <OPTION
value=4>文档标题</OPTION> <OPTION value=6>职位名称</OPTION></SELECT> </FONT><INPUT class=td3 name=Submit type=submit value="搜 索">
</FONT></TD></FORM></TR></TBODY></TABLE>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=770>
<TBODY>
<TR>
<TD align=middle height=70 width=150><IMG height=60
src="CSDN_文档中心_如何通过崩溃地址找到出错的代码行(ZT).files/csdn.gif" width=120></TD>
<TD align=middle width=470>
<SCRIPT language=javascript>
var rand = Math.random().toString();
var ordval = parseInt(rand.substring(2,4));
function Showad(width)
{
if(width=='468')
{
document.write("<a href='http://www.dearbook.com.cn/' target='_blank'><OBJECT classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0' WIDTH=468 HEIGHT=60><PARAM NAME=movie VALUE='/adv//468x60.swf'> <PARAM NAME=quality VALUE=high> <EMBED src='/adv//468x60.swf' quality=high border=0 WIDTH=468 HEIGHT=60 TYPE='application/x-shockwave-flash' PLUGINSPAGE='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'></EMBED></OBJECT></a>");
return;
}
if(width=='120')
{
document.write("<a href='http://www.csdn.net/csdn/csdnClick.aspx?ad=Oracle-button1&adurl&adurl=http://www.oracle.com/global/cn/documentation/10g/index.html?content.html' target='_blank'><img src='/adv/develop/grid_computing_120x60_text1.gif' width=120 HEIGHT=60 border=0></a>");
return;
}
return;
}
Showad('468')</SCRIPT>
</TD>
<TD align=middle width=150>
<SCRIPT>Showad('120')</SCRIPT>
</TD></TR></TBODY></TABLE>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=770>
<TBODY>
<TR>
<TD align=middle bgColor=#000000 colSpan=2 height=1 width=770></TD></TR>
<TR>
<TD align=middle bgColor=#004d99 height=28 width=150><FONT
class=title0>csdn.net</FONT></TD>
<TD align=middle width=620>
<SCRIPT
src="CSDN_文档中心_如何通过崩溃地址找到出错的代码行(ZT).files/navigation1.js"></SCRIPT>
</TD></TR>
<TR>
<TD align=middle bgColor=#000000 colSpan=2 height=1
width=770></TD></TR></TBODY></TABLE>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=770>
<TBODY>
<TR>
<TD bgColor=#f3f9fc height=23 width=10></TD>
<TD bgColor=#f3f9fc>
<MARQUEE onmouseout=this.start() onmouseover=this.stop() scrollAmount=5
scrollDelay=80>
<SCRIPT src="CSDN_文档中心_如何通过崩溃地址找到出错的代码行(ZT).files/marquee.htm"></SCRIPT>
</MARQUEE></TD>
<TD align=right bgColor=#f3f9fc width=101>
<SCRIPT>document.write("<img src=http://count.csdn.net/count/pageview1.asp?columnid=4&itemid=11 border=0 width=0 height=0>");</SCRIPT>
<B>
<SCRIPT language=JavaScript>
<!--
document.ns = navigator.appName == "Netscape"
tmpDate = new Date();
date = tmpDate.getDate();
month= tmpDate.getMonth() + 1 ;
if(document.ns)
{
year1=tmpDate.getYear()
year= year1.toString().substr(1,2);
}
else
year= tmpDate.getYear();
document.write(year);
document.write(".");
document.write(month);
document.write(".");
document.write(date);
// -->
</SCRIPT>
</B> </TD></TR>
<TR bgColor=#999999>
<TD colSpan=3 height=1></TD></TR></TBODY></TABLE>
<TABLE border=0 width=770>
<TBODY>
<TR>
<TD align=middle bgColor=#fafafa class=td1 vAlign=top width=150><BR>
<SCRIPT src="CSDN_文档中心_如何通过崩溃地址找到出错的代码行(ZT).files/microsoft.js"></SCRIPT>
</TD>
<TD align=middle width=620>
<TABLE bgColor=#eeeeee border=0 cellPadding=0 cellSpacing=0 width=600>
<TBODY>
<TR bgColor=#ffffff>
<TD align=middle height=10 width=50></TD>
<TD align=right><A href="http://www.csdn.net/">CSDN</A> - <A
href="http://www.csdn.net/develop/">文档中心</A> - <FONT
color=#003399>Visual C++</FONT> </TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399 height=10><FONT
color=#ffffff>标题</FONT></TD>
<TD><B> 如何通过崩溃地址找到出错的代码行(ZT)</B> ydfok(收藏)
</TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399><FONT color=#ffffff>关键字</FONT></TD>
<TD width=500> 错误代码</TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR></TBODY></TABLE><!--文章说明信息结束//-->
<TABLE border=0 width=600>
<TBODY>
<TR>
<TD align=left><BR>
<P><BR>这是从“VC编程经验总结7”中转出来的</P>
<P>借花献佛——如何通过崩溃地址找到出错的代码行</P>
<P>作为程序员,我们平时最担心见到的事情是什么?是内存泄漏?是界面不好看?……错啦!我相信我的看法是不会有人反对的--那就是,程序发生了崩溃!
</P>
<P>“该程序执行了非法操作,即将关闭。请与你的软件供应商联系。”,呵呵,这句 M$
的“名言”,恐怕就是程序员最担心见到的东西了。有的时候,自己的程序在自己的机器上运行得好好的,但是到了别人的机器上就崩溃了;有时自己在编写和测试的过程中就莫名其妙地遇到了非法操作,但是却无法确定到底是源代码中的哪行引起的……是不是很痛苦呢?不要紧,本文可以帮助你走出这种困境,甚至你从此之后可以自豪地要求用户把崩溃地址告诉你,然后你就可以精确地定位到源代码中出错的那行了。(很神奇吧?呵呵。)</P>
<P>首先我必须强调的是,本方法可以在目前市面上任意一款编译器上面使用。但是我只熟悉 M$ 的 VC 和 MASM
,因此后面的部分只介绍如何在这两个编译器中实现,请读者自行融会贯通,掌握在别的编译器上使用的方法。</P>
<P>Well,废话说完了,让我们开始! :)</P>
<P>首先必须生成程序的 MAP 文件。什么是 MAP 文件?简单地讲, MAP
文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方、任何时候使用,不需要有额外的程序进行支持。而且,这是唯一能找出程序崩溃的地方的救星。</P>
<P>好吧,既然 MAP 文件如此神奇,那么我们应该如何生成它呢?在 VC 中,我们可以按下 Alt+F7 ,打开“Project
Settings”选项页,选择 C/C++ 选项卡,并在最下面的 Project Options 里面输入:/Zd ,然后要选择
Link 选项卡,在最下面的 Project Options 里面输入: /mapinfo:lines 和
/map:PROJECT_NAME.map 。最后按下 F7 来编译生成 EXE 可执行文件和 MAP 文件。</P>
<P>在 MASM 中,我们要设置编译和连接参数,我通常是这样做的:</P>
<P>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 </P>
<P>把它保存成 makem.bat ,就可以在命令行输入 makem filename 来编译生成 EXE 可执行文件和 MAP
文件了。</P>
<P>在此我先解释一下加入的参数的含义:</P>
<P>/Zd 表示在编译的时候生成行信息<BR>/map[:filename] 表示生成 MAP
文件的路径和文件名<BR>/mapinfo:lines 表示生成 MAP 文件时,加入行信息<BR>/mapinfo:exports
表示生成 MAP 文件时,加入 exported functions (如果生成的是 DLL 文件,这个选项就要加上) </P>
<P>OK,通过上面的步骤,我们已经得到了 MAP 文件,那么我们该如何利用它呢?</P>
<P>让我们从简单的实例入手,请打开你的 VC ,新建这样一个文件:</P>
<P>01 <A
href="file://****************************************************************/">file://****************************************************************/</A><BR>02
<A href="file://程/">file://程/</A>序名称:演示如何通过崩溃地址找出源代码的出错行<BR>03 <A
href="file://作/">file://作/</A>者:罗聪<BR>04 <A
href="file://日/">file://日/</A>期:2003-2-7<BR>05 <A
href="file://出/">file://出/</A>处:<A
href="http://www.luocong.com/">http://www.luocong.com/</A>(老罗的缤纷天地)<BR>06
<A href="file://本/">file://本/</A>程序会产生“除0错误”,以至于会弹出“非法操作”对话框。<BR>07
<A href="file://“/">file://“/</A>除0错误”只会在 Debug
版本下产生,本程序为了演示而尽量简化。<BR>08 <A
href="file://注/">file://注/</A>意事项:如欲转载,请保持本程序的完整,并注明:<BR>09 <A
href="file://转/">file://转/</A>载自“老罗的缤纷天地”(<A
href="http://www.luocong.com/">http://www.luocong.com/</A>)<BR>10 <A
href="file://****************************************************************/">file://****************************************************************/</A><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 } </P>
<P>很显然本程序有“除0错误”,在 Debug
方式下编译的话,运行时肯定会产生“非法操作”。好,让我们运行它,果然,“非法操作”对话框出现了,这时我们点击“详细信息”按钮,记录下产生崩溃的地址--在我的机器上是
0x0040104a 。</P>
<P>再看看它的 MAP 文件:(由于文件内容太长,中间没用的部分我进行了省略)</P>
<P>CrashDemo</P>
<P>Timestamp is 3e430a76 (Fri Feb 07 09:23:02 2003)</P>
<P>Preferred load address is 00400000</P>
<P>Start Length Name Class<BR>0001:00000000 0000de04H .text
CODE<BR>0001:0000de04 0001000cH .textbss CODE<BR>0002:00000000
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -