如何根据异常提示信息找出程序出错代码LINUX编程2010-06-2322:44:10阅读136评论0 字号:大中小 订阅看到网上说在debug下可以找到预料的崩溃地址行,但是实际上没有什么用呀。(既然在debug下,那直接用调试器找不更好吗?费这么大劲干什么)(转的文章在后面)Release版本(指编译器优化后的),要找崩溃地址行就比较费劲了。linux下的方法:1、使之生成coredump文件2、gdb调试该core文件3、根据大概的堆栈信息,运行disassemble(具体用法见gdb帮助)4、根据崩溃地址找到对应的崩溃反汇编码5、分析反汇编代码,找到程序中崩溃代码。(如果用debug调试,就更简单了,步骤同上,编译的时候加上编译选项-ggdb,选项详情请见mang++)mac下的方法:1.、使之可以生成core文件,方法同linux2、分析对应的crashlog在系统日志目录下。3、根据2的堆栈信息,反汇编,得到具体地址行。最后转2篇win下的文章。(这种方法好像难找release的。)(1) (vs2003以上,vc6找对应设置就可以)步骤一:编译代码时生成map文件和cod文件我建立了一个名为DataAbort的项目,A)生成map文件,打开项目属性对话框,找到“链接--调试”在“生成映射文件”栏选择“是”;B)生成cod文件,打开项目属性对话框,找到“C/C++--输出文件”在“汇编输出”栏选择“带机器码的程序集”。在默认情况下map文件以项目名称命名,而cod文件以cpp文件名命名,生成目录也不同,编译后可以在项目目录下搜索*.map和*.cod步骤二:根据异常信息找到相应的map文件,及异常地址所在的函数步骤三:打开异常函数所在的cod文件,找到异常对应的代码行。分析问题,解决问题(2)对“仅通过崩溃地址找出源代码的出错行”一文的补充与改进读了老罗的“仅通过崩溃地址找出源代码的出错行”(下称"罗文")一文后,感觉该文还是可以学到不少东西的。不过文中尚存在有些说法不妥,以及有些操作太繁琐的地方。为此,本人在学习了此文后,在多次实验实践基础上,把该文中的一些内容进行补充与改进,希望对大家调试程序,尤其是release版本的程序有帮助。欢迎各位朋友批评指正。一、该方法适用的范围在windows程序中造成程序崩溃的原因很多,而文中所述的方法仅适用与:由一条语句当即引起的程序崩溃。如原文中举的除数为零的崩溃例子。而笔者在实际工作中碰到更多的情况是:指针指向一非法地址,然后对指针的内容进行了,读或写的操作。例如:voidCrash1(){char*p=(char*)100;*p=100;} 这些原因造成的崩溃,无论是debug版本,还是release版本的程序,使用该方法都可找到造成崩溃的函数或子程序中的语句行,具体方法的下面还会补充说明。另外,实践中另一种常见的造成程序崩溃的原因:函数或子程序中局部变量数组越界付值,造成函数或子程序返回地址遭覆盖,从而造成函数或子程序返回时崩溃。例如:#includevoidCrash2();intmain(intargc,char*argv[]){ Crash2(); return0;}voidCrash2(){ charp[1]; strcpy(p,"0123456789");}在vc中编译运行此程序的release版本,会跳出如下的出错提示框。图一上面例子运行结果这里显示的崩溃地址为:0x34333231。这种由前面语句造成的崩溃根源,在后续程序中方才显现出来的情况,显然用该文所述的方法就无能为力了。不过在此例中多少还有些蛛丝马迹可寻找到崩溃的原因:函数Crash2中的局部数组p只有一个字节大小,显然拷贝"0123456789"这个字符串会把超出长度的字符串拷贝到数组p的后面,即*(p+1)=''1'',*(p+2)=''2'',*(p+3)=''3'',*(p+4)=4。。。。。。而字符''1''的ASC码的值为0x31,''2''为0x32,''3''为0x33,''4''为0x34。。。。。,由于intel的cpu中int型数据是低字节保存在低地址中,所以保存字符串''1234''的内存,显示为一个4字节的int型数时就是0x34333231。显然拷贝"0123456789"这个字符串时,"1234"这几个字符把函数Crash2的返回地址给覆盖,从而造成程序崩溃。对于类似的这种造成程序崩溃的错误朋友们还有其他方法排错的话,欢迎一起交流讨论。二、设置编译产生map文件的方法该文中产生map文件的方法是手工添加编译参数来产生map文件。其实在vc6的IDE中有产生map文件的配置选项的。操作如下:先点击菜单"Project"->"Settings。。。",弹出的属性页中选中
CC 定位崩溃代码行的方法 来自淘豆网m.daumloan.com转载请标明出处.