在我正在编写的组件中,我想包括注册图像格式的自动检测,但它是一种仅在禁用使用调试 DCU 的编译器选项时才有效的解决方案。
我真正想知道的是这个解决方案的替代方案,它不涉及编译器选项依赖。
但就目前而言,我只想知道如何在运行时检查是否设置了Use Debug DCU 的编译器选项。
在我正在编写的组件中,我想包括注册图像格式的自动检测,但它是一种仅在禁用使用调试 DCU 的编译器选项时才有效的解决方案。
我真正想知道的是这个解决方案的替代方案,它不涉及编译器选项依赖。
但就目前而言,我只想知道如何在运行时检查是否设置了Use Debug DCU 的编译器选项。
Use Debug DCUs
编译器选项只切换搜索路径;编译器最终会发现什么是未知的。(被误导的)用户可能已将 Release dcu 复制到调试目录中,反之亦然。
即使没有错误的用户,也可能会将一些文件添加到项目中(并与项目一起编译)以包含一些错误修复。例如,如果用户已Graphics.pas
添加到项目中,进行了发布/无调试构建,但保留了Use Debug DCU's
编译器选项,那么Graphics.dcu
实际链接的不是调试构建,因为它是使用可执行文件重新构建的。因此,您会得到一个“混合”的调试和非调试 dcus 包。
您可以尝试检测是否存在与某些对象或方法相关的调试信息,但这也是不可靠的:如果您使用“Build with Debug Dcus”,然后将“Debug Information”设置为 false,那么您实际上是在丢弃调试信息,因此您无法再查找它。
来自 GLScene 项目的代码不是一个好的 hack,它使用硬编码的偏移量到代码中TPicture.RegisterFileFormat
,然后继续使用硬编码的偏移量来获取全局FileFormats
变量的地址(不调用GetFileFormats
例程)。里面有太多神奇的数字!
我的第一个想法是TList
将使用该方法识别的GLScene
方法与TList
我识别的方法进行比较,但猜猜看:在我的机器上没有问题,两个例程在两种情况下都得到了相同的结果。在我的机器上GLScene
,尽管它很丑,但调试 DCU 并没有破坏它。
我什至尝试过“指纹识别”一些 rtl/vcl 单元(SysUtils、Graphics、Classes);我列出了所有公共类,为每个类中的每个方法生成了一些使用 RTTI 的代码,并将代码的前 1024 个字节转储到字符串文件中。使用调试 DCU 和非调试 DCU 运行该程序,我得到了相同的结果。我的文本文件包含大约 3500 种方法的指纹!
由于该选项不会真正影响编译器的编译方式(仅影响链接器链接的内容),因此创建依赖于该选项的代码非常不可靠,也不是一个好主意。这只会影响低级黑客攻击,并且您不希望在您完全无法控制的情况下可能会导致应用程序崩溃的低级黑客攻击。
唯一真正的选择是用不会失败(或至少以可控方式失败)的黑客替换可能失败的黑客。