Delphi XE7/10 最终确定时西雅图 DataSnap OpenSSL 访问冲突
Delphi XE7/10 Seattle DataSnap OpenSSL Access Violation on finalization
在我们的 DataSnap TCP 服务器中添加对 https 网站的调用后,它开始在完成时崩溃。
崩溃发生在 Data.DBXOpenSSL.pas
更具体地说是在这个方法上:
class procedure TRSACypher.ClearKey(var AKey: PRSAPeer);
begin
if AKey <> nil then
IPPeerProcs._RSA_free(AKey); // Crash here
AKey := nil;
end;
例外情况是:
First chance exception at [=14=]000000. Exception class $C0000005 with message 'access violation at 0x00000000: read of address 0x00000000'. Process Project1.exe (3996)
我写了一个重现问题的项目,它在 XE7 和 Delphi 10 Seattle 上都崩溃了,该项目托管在这里:
https://gist.github.com/fabioxgn/aaaddb5aa65db5d17202
项目做的事情很简单:
- 使用 OpenSSL 对 https://google.com
进行 GET 调用
- 启动 DataSnap 服务器
- 打开然后关闭与此 DataSnap 服务器的单个连接
几点:
- 如果不进行 https 调用,一切正常
- 这只会在启用 RSA 过滤器时发生,如果我删除过滤器它不会崩溃
关于是什么导致了这次崩溃,有什么线索吗?我尝试调试,但这段代码使用了很多 IPPeerFactory,我找不到最终代码 运行.
编辑
我打开了一份报告,他们确认这是一个错误:https://quality.embarcadero.com/browse/RSP-12495
据 Embarcadero 研发团队发现,问题在于 Indy 在 Data.DBXOpenSSL 之前完成。当 Indy 完成时,它会将指向所有 OpenSSL 方法的函数指针置为零。当 Data.DBXOpenSSL 完成时,它会执行尝试使用现在为 nil 的函数指针的代码。
作为临时解决方法,可以通过将 Indy 抽象单元作为 uses 子句中的第一个单元(IPPeerClient 在客户端,IPPeerServer 在服务器端)来避免错误并更改初始化和完成顺序侧)项目。
在我们的 DataSnap TCP 服务器中添加对 https 网站的调用后,它开始在完成时崩溃。
崩溃发生在 Data.DBXOpenSSL.pas
更具体地说是在这个方法上:
class procedure TRSACypher.ClearKey(var AKey: PRSAPeer);
begin
if AKey <> nil then
IPPeerProcs._RSA_free(AKey); // Crash here
AKey := nil;
end;
例外情况是:
First chance exception at [=14=]000000. Exception class $C0000005 with message 'access violation at 0x00000000: read of address 0x00000000'. Process Project1.exe (3996)
我写了一个重现问题的项目,它在 XE7 和 Delphi 10 Seattle 上都崩溃了,该项目托管在这里:
https://gist.github.com/fabioxgn/aaaddb5aa65db5d17202
项目做的事情很简单:
- 使用 OpenSSL 对 https://google.com 进行 GET 调用
- 启动 DataSnap 服务器
- 打开然后关闭与此 DataSnap 服务器的单个连接
几点:
- 如果不进行 https 调用,一切正常
- 这只会在启用 RSA 过滤器时发生,如果我删除过滤器它不会崩溃
关于是什么导致了这次崩溃,有什么线索吗?我尝试调试,但这段代码使用了很多 IPPeerFactory,我找不到最终代码 运行.
编辑
我打开了一份报告,他们确认这是一个错误:https://quality.embarcadero.com/browse/RSP-12495
据 Embarcadero 研发团队发现,问题在于 Indy 在 Data.DBXOpenSSL 之前完成。当 Indy 完成时,它会将指向所有 OpenSSL 方法的函数指针置为零。当 Data.DBXOpenSSL 完成时,它会执行尝试使用现在为 nil 的函数指针的代码。
作为临时解决方法,可以通过将 Indy 抽象单元作为 uses 子句中的第一个单元(IPPeerClient 在客户端,IPPeerServer 在服务器端)来避免错误并更改初始化和完成顺序侧)项目。