Ron*_*ijs 2 delphi winapi multithreading
我正在使用Peter Below 的 PBThreadedSplashForm在应用程序启动期间显示启动窗口。
这个组件工作了 10 年,但自从将我的 Delphi 更新到 11.2 后,我在 CreateWindowEx 调用上收到了 AV。
这种情况仅发生在 Win64 平台上,在 Win32 上出现问题。
谁知道这可能是什么原因造成的?
这是由于编译器和链接器中新的默认ASLR设置而在 11.2 中出现的众多问题之一。
快速浏览一下源代码后,我看到了这一点:
SetWindowLong( wnd, GWL_WNDPROC, Integer( thread.FCallstub ));
Run Code Online (Sandbox Code Playgroud)
thread.FCallstub定义为Pointer.
正如我所预料的那样。
您会看到,指针具有本机大小,因此在 32 位应用程序中,指针是 32 位宽,而在 64 位应用程序中,指针是 64 位宽。
在 32 位世界中,指针值临时保存在Integers 中是很常见的。这是有效的,因为 32 位指针适合 32 位Integer.
但在 64 位应用程序中,这是一个明显的错误,因为 64 位指针不适合 32 位Integer. 这就像将 5362417812 这样的电话号码截断为 17812,希望它仍然“有效”。
当然,一般来说,这会导致 AV 和内存损坏等错误。
然而,直到最近,64 位 Delphi 应用程序中的指针“偶然”没有使用其 32 个高位的可能性相当高(所以它就像 Maybe 一样$0000000000A3BE41,因此将其截断为$00A3BE41没有任何影响)。所以它似乎在大多数时候都有效,但只是偶然的。
现在,最新版本的 Delphi 编译器和链接器启用了 ASLR,从而大大降低了此类事故的可能性。
这是一件好事:如果您的代码中有严重的错误,最好立即发现它,而不是“随机”地发现您的客户。
因此,要解决此问题,您需要仔细检查代码并确保永远不会将指针存储在 32 位Integer. 相反,请使用本机大小的NativeInt、Pointer、LPARAM或任何语义上合适的内容。
(禁用 ASLR 也会使其再次意外地在“许多”情况下工作,但这是一个非常糟糕的方法。您的软件仍然存在一个非常严重的错误,可能随时显现出来。)
在你的代码中,还有
Integer( Pchar( FStatusMessage ))
Integer( Pchar( msg ))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
316 次 |
| 最近记录: |