软件调试基础

软件调试基础

软件调试的基本手段有:断点、单步执行、栈回溯等。
其初衷是跟踪和记录CPU执行软件的过程,把动态的瞬间凝固下来供检查和分析

**Bug一词来源:**
“Bug”的创始人格蕾丝·赫柏(Grace Murray Hopper),是一位为美国海军工作的电脑专家,也是最早将人类语言融入到电脑程序的人之一。
而代表电脑程序出错的“bug” 这名字,正是由赫柏所取的。
1947年9月9日,赫柏对Harvard Mark II设置好17000个继电器进行编程后,技术人员正在进行整机运行时,它突然停止了工作。于是他们爬上去找原因,发现这台巨大的计算机内部一组继电器的触点之间有一只飞蛾,这显然是由于飞蛾受光和热的吸引,飞到了触点上,然后被高电压击死。所以在报告中,赫柏用胶条贴上飞蛾,并把“bug”来表示“一个在电脑程序里的错误”,“Bug”这个说法一直沿用到今天。

软件调试:指使用调试工具求解各种软件问题的过程(比如跟踪软件的执行过程、探索软件本身或其配套的其他软件,或者硬件系统的工作原理等),这些过程有可能是为了去除软件缺欠,也可能不是。

软件调试基本过程:(有点像QA提bug,然后开发修复、提测,QA验证的过程)

  • 重现故障
  • 定位根源(这个通常是最困难也是最关键的步骤)
  • 探索和实现解决方案
  • 验证方案

软件调试基本特征

  • 难度大
  • 难以预估完成时间
  • 广泛的关联性

单步调试

在1978年,x86CPU的第一代8086CPU问世的时候,其标志寄存器(FLAGS)中,专门设计了一个用于软件调试的标志位,叫做TF(Trsce Flag)。
TF位主要是供调试器软件来使用的,当用户需要单步调试时,调试器会设置TF位,当CPU执行完一条指令后会检查TF位,如果这个位为1,那么便会产生一个调试异常(INT1),目的是停止执行当前的程序,中断到调试器中。

断点指令

  • 逗号断点指令(Comma Breakpoint)

分支监视

软件调试分类

  • 按调试目标的系统环境分类(Windows下的软件调试、Linux下的软件调试、Dos下的软件调试等)
  • 按目标代码的执行方式分:
    脚本程序 – 脚本调试器
    执行编译的程序:
    1. 先编译为中间代码,在运行时再动态编译为当前CPU能够执行的目标代码(比如C#开发的.NET程序) – 托管调试
    2. 直接编译和链接成目标代码的程序(C/C++) – 本地调试
    3. 兼具以上两种的 – 混合调试
      在这里插入图片描述
  • 按目标代码的执行模式分:用户态调试(User Mode Debugging)、内核态调试(Kernel Mode Debugging)
在Windows这样的多任务操作系统中,作为保证安全和秩序的一个根本措施,系统定义了两种执行模式,即低特权等级的用户模式(User Mode)和高特权等级的内核模式(Kernel Mode)。
应用程序代码是运行在用户模式下的,操作系统的内核、执行体和大多数设备驱动程序是运行在内核模式的。
  • 按软件所处的阶段分:开发期调试、产品期调试(分界线是产品的正式发布)
  • 按调试器和调试目标的相对位置分:本机提哦啊哈斯、远程调试
  • 按调试目标的活动性分:活动目标调试、转储文件调试
  • 按调试工具分
调试技术的一些其他知识

断点
断点是使用调试器进行调试的最常用的调试技术之一。器基本思想是在某一个位置设置一个“陷阱”,当CPU执行到这个位置的时候便停止执行被调试的程序,中断到调试器中,让调试着进行分析和调试。调试着分析结束后,可以让被调试程序恢复执行。
根据断点的设置空间可以把断点分为:

  • 代码断点 – 设置在内存空间中的断点,其地址通常为某一段代码的起始处。
  • 数据断点 – 设置在内存空间中的断点,其地址一般为要监视的变量(数据)的起始地址。
  • I/O断点 – 设置在I/O空间中的断点,其地址为某一I/O地址

输出调试信息
在windows操作系统中,驱动程序可以使用DbgPrint/DbgPrintEx来输出调试信息;应用程序可以调用OutputDebugString,控制台程序可以直接使用print函数打印信息。

  • 优点:实时性
  • 缺点:容易丢失和被覆盖,不适用于长期保存和事后分析

日志
事件跟踪
适用于监视频繁且复杂的软件过程(比如监视文件访问和网络通信等)
ETW(Event Trace for Windows)是Windows系统内建的一种事件跟踪机制,windows内核本身和很多windows下的软件工具间都使用了该机制。
转储文件(dump file)
栈回溯
栈回溯的基本原理:通过递归方式寻找放在栈上的函数返回地址,便可以追溯到当前线程的函数调用序列。

目前的主流CPU架构都是使用栈来进行函数调用的,栈上记录了函数的返回地址。

栈回溯是记录和探索程序执行踪迹的计价方法,使用这样方法,准确且基本不需要额外的开销。
反汇编
反汇编就是将目标代码(指令)翻译为汇编代码。
反汇编的依赖性非常小,根据二进制的可执行文件就可以得到汇编语言表示的程序。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值