假设该程序名为mydebug,并且使用
cscript.exe adplus.vbs -crash -pn mydebug.exe -o c:\test\crashdump -quiet ,捕获了程序crash时刻的dump文件。下载该程序的crash dump,请点击此处。

step1:打开该crash dump之后,立刻可以看到捕获的exception

Loading Dump File [D:\study\mydebug\crashdump\Crash_Mode__Date_11-12-2008__Time_15-30-1818\PID-3512__MYDEBUG.EXE__2nd_chance_IntegerDivide__full_0474_2008-11-12_15-30-35-715_0db8.dmp]
User Mini Dump File with Full Memory: Only application data is available

Comment: '2nd_chance_IntegerDivide_exception_in_MYDEBUG.EXE_running_on_T-RENHE-03'
Symbol search path is: srv*d:\symbolslocal*http://msdl.microsoft.com/download/symbols;D:\symbolslocal
Executable search path is:
Windows Server 2003 Version 3790 (Service Pack 2) UP Free x86 compatible
Product: Server, suite: Enterprise TerminalServer SingleUserTS
Debug session time: Wed Nov 12 15:30:35.000 2008 (GMT+8)
System Uptime: 0 days 6:30:46.419
Process Uptime: 0 days 0:02:46.000
...
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(db8.1678): Integer divide-by-zero - code c0000094 (first/second chance not available)
eax=00000004 ebx=7ffdd000 ecx=00434e40 edx=00000000 esi=00000000 edi=0012fe60
eip=00401490 esp=0012fe04 ebp=0012fe60 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
*** WARNING: Unable to verify checksum for mydebug.exe
mydebug!CallFast+0x60:
00401490 f77df4          idiv    eax,dword ptr [ebp-0Ch] ss:0023:0012fe54=00000000

从以上这段信息可以看到,在指令寄存器eip所保存的00401490处的指令出现exception,并且产生异常的instruction和exception information已经列出。

一眼即可以看出,这个程序是因为除零而产生的exception,究竟这个exception如何产生的呢?

下面列出完整debug过程。

0:000> .logopen c:\crahdebug1.log //打开crashdebug1.log开始写入debug log
Opened log file 'c:\crashdebugl.log'
0:000> kb 
/*
该comand显示call stack内容,call stack保存的是exception发生时的瞬时状态,而stack top是出现exception的焦点所在,从以下的callstack可以看出,其调用嵌套过程如下:main-> CallWidhCDel-> CallWithStd ->CallFast (->表示调用关系),当在调用CallFast函数时,运行到00401490处的指令时发生exception.因此,下面需要step into至CallFast函数中,查看其指令。

*/
ChildEBP RetAddr  Args to Child             
0012fe60 00401402 00000006 0012ff18 00000000 mydebug!CallFast+0x60 [D:\study\mydebug\mydebug.cpp @ 58]
0012feb8 00401393 004310d8 00000004 00000006 mydebug!CallwithStd+0x42 [D:\study\mydebug\mydebug.cpp @ 44]
0012ff18 0040130a 0043101c 00000004 00000006 mydebug!CallWithCDecl+0x43 [D:\study\mydebug\mydebug.cpp @ 37]
0012ff80 00401969 00000001 00440e90 00440dc0 mydebug!main+0x9a [D:\study\mydebug\mydebug.cpp @ 28]
0012ffc0 77e6f23b 00000000 00000000 7ffdd000 mydebug!mainCRTStartup+0xe9 [crt0.c @ 206]
0012fff0 00000000 00401880 00000000 78746341 kernel32!BaseProcessStart+0x23

/*

从call stack我们可以清晰的看出函数调用链,在完成所有初始化process之后主函数调用CallWithCDecl,然后CallWithCDecl嵌套调用CallWithStd,然后CallWithStd又嵌套调用CallFast。每次嵌套调用的同时都伴随着一系列寄存器和,各参数的push stack。因此我们才可以顺着call stack看出清晰的调用链:)

下面对call stack中返回的值作简要说明:

ChildEBP:

该值保存的是对应的函数被调用时的EBP寄存器的值e.g.

0:000> dd 0012feb8 L4
0012feb8  0012ff18 00401393 004310d8 00000004
0:000> dd 0012ff80 L4
0012ff80  0012ffc0 00401969 00000001 00440e90

*/

0:000> kn
 # ChildEBP RetAddr 
00 0012fe60 00401402 mydebug!CallFast+0x60 [D:\study\mydebug\mydebug.cpp @ 58]
01 0012feb8 00401393 mydebug!CallwithStd+0x42 [D:\study\mydebug\mydebug.cpp @ 44]
02 0012ff18 0040130a mydebug!CallWithCDecl+0x43 [D:\study\mydebug\mydebug.cpp @ 37]
03 0012ff80 00401969 mydebug!main+0x9a [D:\study\mydebug\mydebug.cpp @ 28]
04 0012ffc0 77e6f23b mydebug!mainCRTStartup+0xe9 [crt0.c @ 206]
05 0012fff0 00000000 kernel32!BaseProcessStart+0x23
0:000> .frame 0  //选择stack top的frame
00 0012fe60 00401402 mydebug!CallFast+0x60 [D:\study\mydebug\mydebug.cpp @ 58]
0:000> dv //然后查看其参数情况
      szMessage = 0x004310d8 "Now in the callwithstd function, parameters are :"
              a = 4
              b = 6
       iDivider = 0 //从名字意义上判断不符合business logic.
        iResult = 0
0:000> r
eax=00000004 ebx=7ffdd000 ecx=00434e40 edx=00000000 esi=00000000 edi=0012fe60
eip=00401490 esp=0012fe04 ebp=0012fe60 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
mydebug!CallFast+0x60:
00401490 f77df4          idiv    eax,dword ptr [ebp-0Ch] ss:0023:0012fe54=00000000
0:000> u mydebug!CallFast //查看该function的指令 默认显示10行
mydebug!CallFast [D:\study\mydebug\mydebug.cpp @ 48]:
00401430 55              push    ebp
00401431 8bec            mov     ebp,esp
00401433 83ec50          sub     esp,50h
00401436 53              push    ebx
00401437 56              push    esi
00401438 57              push    edi
00401439 51              push    ecx
0040143a 8d7db0          lea     edi,[ebp-50h]
0:000> u mydebug!CallFast L40  //显示40个单元块的指令集合
/*

00401490处的指令肯定包含其中

*/
mydebug!CallFast [D:\study\mydebug\mydebug.cpp @ 48]:
00401430 55              push    ebp
00401431 8bec            mov     ebp,esp
00401433 83ec50          sub     esp,50h
00401436 53              push    ebx
00401437 56              push    esi
00401438 57              push    edi
00401439 51              push    ecx
0040143a 8d7db0          lea     edi,[ebp-50h]
0040143d b914000000      mov     ecx,14h
00401442 b8cccccccc      mov     eax,0CCCCCCCCh
00401447 f3ab            rep stos dword ptr es:[edi]
00401449 59              pop     ecx
0040144a 8955f8          mov     dword ptr [ebp-8],edx
0040144d 894dfc          mov     dword ptr [ebp-4],ecx
00401450 8b4508          mov     eax,dword ptr [ebp+8]
00401453 50              push    eax
00401454 8b4df8          mov     ecx,dword ptr [ebp-8]
00401457 51              push    ecx
00401458 8b55fc          mov     edx,dword ptr [ebp-4]
0040145b 52              push    edx
0040145c 6814114300      push    offset mydebug!`string' (00431114)
00401461 e89a030000      call    mydebug!printf (00401800)
00401466 83c410          add     esp,10h
00401469 c745f400000000  mov     dword ptr [ebp-0Ch],0
00401470 c745f000000000  mov     dword ptr [ebp-10h],0
00401477 837d0806        cmp     dword ptr [ebp+8],6
0040147b 7509            jne     mydebug!CallFast+0x56 (00401486)
0040147d c745f400000000  mov     dword ptr [ebp-0Ch],0
00401484 eb06            jmp     mydebug!CallFast+0x5c (0040148c)
00401486 8b4508          mov     eax,dword ptr [ebp+8]
00401489 8945f4          mov     dword ptr [ebp-0Ch],eax
0040148c 8b45f8          mov     eax,dword ptr [ebp-8]
0040148f 99              cdq
00401490 f77df4          idiv    eax,dword ptr [ebp-0Ch]  //这就是罪魁祸首
00401493 8945f0          mov     dword ptr [ebp-10h],eax
00401496 8b4df0          mov     ecx,dword ptr [ebp-10h]
00401499 51              push    ecx
0040149a 8b55f4          mov     edx,dword ptr [ebp-0Ch]
0040149d 52              push    edx
0040149e 8b45f8          mov     eax,dword ptr [ebp-8]
004014a1 50              push    eax
004014a2 6824114300      push    offset mydebug!`string' (00431124)
004014a7 e854030000      call    mydebug!printf (00401800)
004014ac 83c410          add     esp,10h
004014af b803000000      mov     eax,3
004014b4 5f              pop     edi
004014b5 5e              pop     esi
004014b6 5b              pop     ebx
004014b7 83c450          add     esp,50h
004014ba 3bec            cmp     ebp,esp
004014bc e87f010000      call    mydebug!_chkesp (00401640)
004014c1 8be5            mov     esp,ebp
004014c3 5d              pop     ebp
004014c4 c20400          ret     4
004014c7 cc              int     3
004014c8 cc              int     3
004014c9 cc              int     3
004014ca cc              int     3
004014cb cc              int     3
004014cc cc              int     3
004014cd cc              int     3
004014ce cc              int     3
004014cf cc              int     3
004014d0 cc              int     3
0:000> dd ebp-0Ch L1  //看看指定的内存单元地址表示的被除数的值,当然为0了
0012fe54  00000000
0:000> .logclose
Closing open log file c:\crashdebugl.log

至于这个0是怎么来的,你可以联系你的vendor,告诉他当前实参为dv中所指定的值时,在CallFast函数中会抛出divide by zero exception,然后让他们去进行修改business logic了,vendor在有源代码的情况下debug就轻松多了。

当然如果你有兴趣,可以去研究以上列出的出现exception的instruction set所表明的business logic。

转载于:https://www.cnblogs.com/Winston/archive/2008/11/13/1332888.html

windbg入门之旅:(2)一个简单的integer divide-by-zero exception分析案例相关推荐

  1. WF4.0入门系列1——创建一个简单的工作流

    WF4.0入门系列1--创建一个简单的工作流 打开VS2010,选择文件-新建-项目,选择Workflow项 工作流台应用程序,在名称处输入chapter01,选择合适的位置,这里默认,单击确定. V ...

  2. 【Yocto学习入门】02 - 构建一个简单的Poky参考嵌入式操作系统

    [Yocto学习入门]02 - 构建一个简单的Poky参考嵌入式操作系统 一.开发环境准备 二.下载 Poky 代码 三.配置编译环境 3.1 下载失败情况处理 Failed to fetch URL ...

  3. ava入门篇——如何编写一个简单的Java程序

    最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...

  4. Visual Studio 2019 C# 上位机入门(2):写一个简单的串口助手

    前言 本文记录一下用Visual Studio 2019 C# 写一个简单的串口助手的过程,由于没有先从小处学习,而是直接找相关资料就开始做,免不了很多奇怪的问题花了一些时间,基于此情况,我将尽可能整 ...

  5. 后端入门之Python实现一个简单接口编写

    最近好像要转向后端了,故想提前学习下,实现一个简单接口编写,熟悉一下编写接口的流程和框架.写这个主要是记录一下自己的学习过程,以便后面温习.在Python实现一个简单接口编写之前需要了解一些后端开发的 ...

  6. ros订阅话题python_ROS入门教程 (写一个简单的消息发布器和订阅器 (Python))

    Note: This tutorial assumes that you have completed the previous tutorials: 创建ROS消息和ROS服务. Descripti ...

  7. QT学习之C++入门知识准备+建立一个简单的QT界面

    本人使用的QT5.12.10下载地址http://download.qt.io/archive/qt/5.12/5.12.10/ 1.什么是C++ C++是C语言的升级版,在C的基础上加了很多功能,是 ...

  8. 【零基础】MT4量化入门一:跑一个简单的boll

    一.前言 今天开始研究MT4了,MT4是大大有名的外汇交易和量化软件,使用一种叫做MQL的语言来开发量化程序(跟C比较像).因为是外国人做的,用的也大部分是外国人,使用起来不是很顺手,跟极星各有优劣吧 ...

  9. python初学者可以做的金融小程序-Python入门 —— 用pycharm写一个简单的小程序3...

    环境:Win10操作系统:Python3.7:Pycharm 题目来源:PTA 编程实例1:日期格式化 世界上不同国家有不同的写日期的习惯.比如美国人习惯写成"月-日-年",而中国 ...

  10. python简单编程例子-Python入门 —— 用pycharm写一个简单的小程序3

    环境:Win10操作系统:Python3.7:Pycharm 题目来源:PTA 编程实例1:日期格式化 世界上不同国家有不同的写日期的习惯.比如美国人习惯写成"月-日-年",而中国 ...

最新文章

  1. 时间处理_pandas_时间处理小结
  2. cmake使用示例与整理总结_QTVLC的博客-CSDN博客_cmake使用示例与整理 施公队演示时用的blog B zhan
  3. 宅在家限制智力输出?这场论文复现赛让思维发光
  4. CSS中的选择器之类选择器和id选择器
  5. autohold有什么弊端吗_自动驻车AUTO HOLD有啥作用?怎样使用?
  6. distinct sql用法_十分钟搞懂SQL数据分析
  7. 极速安装JumpServer - 官方文档版
  8. JavaScript中eval()和$.parseJSON()的区别和联系以及JSON.stringify()的区别
  9. 从网络营销辞职转行软件测试,100天的心酸拿到9K,过程都是自己在苦撑,只因我...
  10. centos7 java 1.8_Centos7下安装Java JDK 1.8
  11. 软件技术基础复习提纲
  12. EduSoho教育周报(0805-0811)
  13. Python:练习打字游戏
  14. 14个令人惊叹的Ionic应用程序模板
  15. 闲情雅致-(诗词篇1)
  16. esp32 micropython 控制ws2812 RGB灯带
  17. viicms仿乐享微信源码官方版
  18. 学习笔记之在eclipse中,使用ADT开发
  19. 用matplotlib.pyplot绘制线形图
  20. iOS10会带来哪些新变化?

热门文章

  1. day3-python之函数初识(二)
  2. 创建java普通工程 ( 4 )
  3. [Ubuntu18.04]美化
  4. 容器技术学习系列文章总目录
  5. 【kafka】生产者速度测试
  6. 反射(3)反射应用:一个插件项目
  7. 对于 js 性能优化的启发,debounce 和 throttle。
  8. IE浏览器中a:hover设置background失效的解决方法
  9. 码支付(php版本)应用
  10. 常见的HTTP状态码说明