[教程]如果在 Delphi /C++ Builder 中调试单元初始化时的错误

有时候,我们程序在进入 Main 函数入口前,就开始报错,比如 Acesss volation at XXX read at yyyy 一类的错误。这类错误一般是由于单元之间的引用关系和初始化顺序不一致造成的。比如单元 A 的初始化代码调用了单元 B 的函数,但单元 B 此时尚未初始化,所以其使用到的一些全局或静态变量没有正确的值,造成程序得出错误的结果。

那么,针对这种情况,较快的找到问题的解决办法:

  • 在出错的位置设置断点,如果是第一次进入该函数时就出错,那就好找了,当然检查它调用了那个单元的啥代码,审核其逻辑就可以了。
  • 如果出错的位置是重复进入的,那么我们就需要:
    • 判断它是第几次进入时出现的问题:如果没有啥判断依据,可以假设一个中间值,比如 100,设置断点,然后设置其 Pass count 的值为 100 ,如果不出,则加倍,如果出了,则减半,通过二分法,几次后找到出错的次数。假设为第 7 次出现的错误,那么我们将 Pass count 设置 为 6
    • 单步执行到函数退出的位置,然后按 Ctrl+Alt+C 切换到 CPU 窗口,然后按 F8 直到遇到 RET 指令跳回上级函数,然后按 F7 单步调试,根据汇编窗口的提示的单元和位置去找对应的出错位置,如下图中就可以看到当前汇编内容对应的是 qstring.pas 单元的 13350 行,我们可以切换到对应的单元进一步去看非汇编的源码:
    • 找到出错位置后,可以将对应的初始化代码想办法延迟到其它代码初始化完成后再调用。

分享到: