zoukankan      html  css  js  c++  java
  • VC程序查错之内存访问异常

    作者:langouster

    先来看下面这张图,相信很多程序员都见过类似。

    ---------------------------
    test1.exe - 应用程序错误
    ---------------------------
    "0x00401002" 指令引用的 "0x00000000" 内存。该内存不能为 "written"。
    要终止程序,请单击“确定”。
    要调试程序,请单击“取消”。
    ---------------------------
    确定   取消   
    ---------------------------

    从这个对话框中我们可以提到三个有效信息

    1.这个一个内存写错误,所以引起这个错误的语句肯定是一个写操作

    2.0x00401002这个地址表示的是出错时的EIP地址,换言之是出错的那行语句的错误。

    3."0x00000000" 内存说明程序把一段数据写到了空指针上。

    这个错误,如果能重现,那没什么说的了,太简单,直接在VS2003上按F5,然后等着出错,出错时VS会自动指向出错的那一行。

    我们重点来讲不能重现的情况,比如在测试机器上出现了。对于一个好的程序员是不应该放过这样一个错误的,必须要找到错误的原因并修正,否则将会给产品埋下定时炸弹。

    一般我们编译好做好版本时,我们应该备份下每个版本的pdb文件与exe文件,它于exe在同一目录下生成,这个文件对于调试非常重要,会减少很多麻烦。

    这时我们需要用上windbg了,它可以从微软官方下载到,安装后它实际上是绿色的,压缩一下就可以拷来拷去。

    在出错的机器上运行windbg,界面大致如下:
     

    选择File->Attach To Process,或直接按F6键。出来一个进程选择界面,默认是按进程启动时间排序的,选择你的出错的进程,单击“OK”。

    然后要看你方不方便把pdb文件复制到出错的机器上,如果不方便,我们就要把它的出错状态拿回来,慢慢分析,如果能把pdb复制到对方机器上并调试那是最好的。如果不能,我们就输入.dmp /f c:1.dmp 这个命令,意思是把出错程序的完整状态复制下来保存到c:1.dmp文件里,然后你把这个文件复制把你的有pdb的机器上,再打开windbg,把1.dmp拖到windbg上。

    在File->Symbol Search Path里设置好pdb目录。在命令行中输入!analyze -v。意思是分析错误,经常windbg是分析不出错误的,你可以输入KB试试,这个命令是查看堆栈。

    如果看到类似

    这样的就表示可以找到原因了,在test1.cpp的第11行出错了。

    这里最简单的调错方法,在实际环境中,往往会比这个情况复杂的多,这需要慢慢积累经验。

    如果程序是多线程,有时候还需要先找到出错的线程是哪一个,我一般是开一个windbg的堆栈窗口,再开一个windbg的线程窗口,线程一个个点过去,看哪个线程的堆栈中有异常。

    下面再来看一种稍微复杂一点的情况,你可能没有办法在用户机器上安装windbg,或者用户只是给了一张出错时的截图,出错的程序可能已经关了。

    这时你可以使用IDA,把对应版本的exe文件与pdb放在一个目录里,把exe放进ida里分析,然后按"G"键输入上面窗口中的0x00401002,那行就是有问题的代码,往前面找找一般都有函数名,但这种方法得到不到具体出错的代码行。我们还可以使用windbg可以直接得到出错的代码行,选择File->Open Executable菜单,选择出错的版本的exe,确定,再设置好pdb路径,然后在命令行窗口中输入u 0x00401002,意思是反汇编这个地址,出来如下图这样的结果,上面直接有出错的代码行。

    调试分析BUG需要较多的经验,熟能生巧,欢迎大家多多交流。

    http://www.langouster.com/HTML/119.html

  • 相关阅读:
    Linux ->> VirtualBox Linux虚拟机与Windows主机共享目录
    Linux ->> CentOS 7 执行service network restart 报错
    借助企业微信实现“调接口”给个人微信发消息
    idea提交代码到github教程
    Content type ‘multipart/form-data;boundary=--------------------------9107
    org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;bounda
    org.hibernate.LazyInitializationException: could not initialize proxy 解决方案(JPA)
    GitLab代码回滚到特定版本
    js 导入excel文件
    GoLand 2021.1.3安装之后需要激活得步骤
  • 原文地址:https://www.cnblogs.com/findumars/p/4227450.html
Copyright © 2011-2022 走看看