调试心得:通过观察正常的程序行为来识别Bug

有时候 , 当我调试一个问题的时候 , 我会特意忽略掉某些线程 。
这个时候 , 有人就问了:”这些线程是干什么的?你为什么知道要忽略它们?”
我的回答是:我也不清楚这些线程是干啥的 , 但是无论它的内部工作是什么 , 这都是正常的 。”
博主 Tess Ferrandez 一直在编写关于 CLR 调试的系列文章 , 这些文章十分有用 , 但最为重要的一条是在调试 ASP.NET 死锁问题时该如何忽略掉不相关的部分 。
在实际项目中 , 死锁和挂起这类问题十分难以调试 , 因为出现这类问题时 , 调试器中并没有输出异常相关的信息 。程序突然之间就停止了响应 , 开发者不得不苦思冥想 , 到底哪里出错了 。
出现此类问题 , 我们需要先有一个大概的思路 , 即:我们需要寻找那些”不同寻常”的东西 , 而为了找到这类东西 , 我们首先需要知道 , 哪些东西是正常的 。
举个例子 , 先运行程序一段时间 , 然后中断到调试器 , 看看内存数据 , 线程 , 加载的模块等相关信息 , 并将这些信息记录下来 。你所记录下的这些信息 , 就是所谓的”正常”的程序行为 , 就是说 , 当程序正常运行的时候 , 你所记录的就是正常的运行数据 。
有了上面的记录 , 当程序异常的时候 , 再次对比下运行时数据 , 就有可能识别出那些不太正常的数据结构了 。
当调试一个大型工程的时候 , 可能程序会启动非常多的线程 , 你不必知晓每个线程具体的工作细节 。例如 , 当我挂接调试器到一个目标进程后 , 我经常会看到有一些线程会等待 RPC 对象或者是内核线程池相关的线程 , 说老实话 , 我也不清楚这些线程是干啥的 , 但是因为它们总是在那里悄无声息的运行着 , 所以 , 我也不会太关注它们 , 这些可能就是我上面所说的正常的东西 。
总结随着代码规模越来越大 , 诊断机制需要进一步完善 , 单纯通过下断点调试可能不是那么有效了 , 这个时候 , 需要结合调试输出和日志来查找问题 。

【调试心得:通过观察正常的程序行为来识别Bug】


    推荐阅读