在我正在编写的组件中,我想要包含automatic detection of registered image formats,但这是一个仅在使用调试DCU的编译器选项被禁用时才有效的解决方案。
我真正想知道的是此解决方案的替代方案,不涉及编译器选项依赖。
但就目前而言,我只想知道如何在运行时检查是否设置了使用调试DCU的编译器选项。
答案 0 :(得分:5)
Use Debug DCUs
编译器选项仅切换搜索路径;编译器最终会发现什么是未知的。 (误导)用户可能已将Release dcu复制到调试目录上,反之亦然。
即使没有误解用户,也可能会将一些文件添加到项目中(并使用项目进行编译)以包含一些错误修复。例如,如果用户将Graphics.pas
添加到项目中,执行release / no-debug构建,但保留Use Debug DCU's
编译器选项,那么实际链接的Graphics.dcu
不是调试版本,因为它是使用可执行文件重新构建的。所以你得到一个“混合”的调试和非调试dcus包。
您可以尝试检测是否存在与某些对象或方法相关的调试信息,但这也是不可靠的:如果您使用“Build with Debug Dcus”但将“Debug Information”设置为false,那么您实际上是扔掉调试信息,以便你不再寻找它。
来自GLScene项目的代码不是一个好的黑客,它使用硬编码的偏移到TPicture.RegisterFileFormat
的代码,然后继续使用硬编码的偏移量来获取全局{{1}的地址变量(不调用FileFormats
例程)。那里的魔法数太多了!
我的第一个问题是将使用GetFileFormats
方法识别的TList
与我已识别的GLScene
进行比较,但猜猜:在我的机器上在两种情况下都没有问题,两个例程都得到了相同的结果。在我的机器上,TList
,实际上是丑陋的,不会被Debug DCU打破。
我甚至尝试过“指纹识别”一些rtl / vcl单元(SysUtils,Graphics,Classes);我列出了所有公共类,为每个类中的每个方法生成了一些使用RTTI的代码,并将代码的前1024个字节转储到字符串文件中。使用调试DCU和非调试DCU以及获得相同的结果。我的文本文件包含大约3500种方法的指纹!
由于该选项并不真正影响编译器编译的方式(只是链接器链接的方式),因此创建依赖于此选项的代码非常不可靠并且不是一个好主意。 这只会影响低级攻击,并且您不希望在完全无法控制的情况下可能导致应用程序崩溃的低级攻击。
唯一真正的选择是将一个可能失败的黑客替换为一个不会失败的黑客攻击(或至少以可控方式失败)。
答案 1 :(得分:2)
作为Ken comments,可能无法检测此编译器选项涉及的路径更改。命令行编译器documentation未提及编译器开关,因此意味着它根本不存在。如果没有编译器开关,则无法检查是否已设置该编译器选项
...但这是一个仅在使用调试DCU的编译器选项被禁用时才有效的解决方案。
如果仅起作用意味着它会导致异常,那么您可以使用以下替代方法:
try
// AutoDetectRegisteredImageFormats
except
// Handle case when Use Debug DCU's is on
end;