如何使用Win32 Debugging API实现代码覆盖率工具

时间:2009-04-07 16:02:24

标签: delphi winapi

我试图了解如何使用Win32调试API实现代码覆盖率工具。

我的想法是利用Win32 Debugging API在调试模式下启动进程 - 并跟踪已执行的CPU指令。在跟踪了所有CPU指令之后,我将使用映射文件将其映射到执行的源代码行。

据我所知,有两种方法可以知道CPU指令的执行情况。

  1. 将以调试模式启动进程 - 以单步模式设置所有线程,让调试应用记录所有已执行的指令

  2. 这将是一个更智能的方法,你会对x86指令有更多的了解,并基本上用断点替换下一个分支指令。然后跟踪两个断点之间的delta指令。

  3. 更新 - 受迈克尔回应启发的新建议方法:

    1. 从映射文件开始,在每行的开头插入断点,并在每次断点发出时通知调试框架。

    2. 从映射文件开始 - 二进制检测以插入在每个源代码行的条目处调用的“钩子” - 避免通过调试器框架进行回调。

    3. 使用VM技术(例如VMware)找出特定流程中的指令执行情况 - 我不完全理解这种方法......

    4. 有人可以验证上述方法之一,也可能建议替代方案 - 请注意,用例是逐行代码覆盖而不是性能分析 - 因此我们需要知道是否访问了每个单一源代码行。 / p>

      我的主要目标(虽然没有特别的计划......)主要是为Delphi创建一个简单的代码覆盖工具。

      谢谢!

3 个答案:

答案 0 :(得分:2)

一种方法是挂钩所有api调用和函数调用,以与源代码表进行比较。因此,您可以发现所涵盖的内容 钩子有很多api,一个是Trappola API hooking

答案 1 :(得分:1)

这可能有效 - 每个单步事件都会创建一个异常,您可以在执行代码行的地图中记录命中的IP地址。

不幸的是,我想这会非常缓慢。这是非常低效的,因为每一行代码都会产生1000倍的工作量,因为生成异常,捕获,发送到调试器的消息,然后在记录命中后回转。尝试为每条被覆盖的线设置断点并在它们被击中后清除它们可能会更好。那会更快,但很可能仍然很慢。

核心问题是您正在尝试将调试器用作代码覆盖工具,而不是它的用途。快速搜索在互联网上显示了Delphi的几种代码覆盖工具。

答案 2 :(得分:1)

我建议,不要为每行代码挂钩,你可以选择每个块。我的意思是说代码块的钩子。它会更快,您也可以从块数中获得行数。