delphi - Indy 9 和 Windows Server 2003 之间不兼容?

标签 delphi soap delphi-2007 dep delphi-2005

我在某些 Windows 2003 服务器上使用 Delphi 应用程序时遇到问题。它使用 Web 服务调用与另一台服务器连接并来回传输数据。一旦应用程序到达 Authenticate 方法,应用程序就会终止。该应用程序多年来一直在装有 Win Server 2003 的旧机器上运行,但在新构建的机器上却无法运行。这些机器的设置方式在大多数情况下都是相同的,但显然有一些配置设置不同,我无法追踪。此外,虽然错误在调用 Authenticate 时变得明显,但数据包嗅探证明应用程序和它尝试联系的服务器之间没有发生任何事情,这强化了我的想法,即在建立连接的过程中有些东西正在消失。我无法在本地复制错误,因此我也无法在调试器中单步调试应用程序。关于为什么 Indy 9 Delphi Web 连接可能会默默失败的任何想法?

最佳答案

这里是爆炸的地方:

MySoapObject := GetNewSoapObject(usewsdl, addr, FHTTPRIO);  
 ...   
if MySoapObject <> nil then   
  MySoapObject.SomeFunction(); // BOOM! Access Violation here.

找到解决方案!原来是DEP(数据执行保护)。当我用 Delphi2007 SOAP 库重新构建代码时,问题就消失了。因为我不想这样做(反序列化导致的问题导致服务器在我们的 XML 上阻塞),而且我的经理也不想这样做(涉及广泛的回归测试),所以我寻找 SOAP 之间的差异D2005 和 D2007 之间的源代码,其想法是对两者之间的差异进行有针对性的更改。即找到造成差异的差异。 Beyond Compare是我在这里的 friend 。有一个变化有点奇怪 - RIO.PAS 现在包含一个新单元 PrivateHeap.pas。想知道为什么,我用谷歌搜索并发现了一个类似的问题,其解释似乎是正确的。

The DEP issue is basically that starting with Windows XP Service Pack 2, if your hardware is capable, Windows will prevent execution of code from non-executable memory. Unfortunately the Delphi SOAP runtime creates a bunch of thunks and the memory allocated for these were not marked executable. So when the OS update was released on capable hardware, you'd get an AV when invoking a method backed by a RIO component. This issue was addressed in an update with the PrivateHeap unit.
-- Jean-Marie Babet
http://delphigroups.info/2/11/344230.html

宾果!现在事情变得棘手了。我们的服务器上始终启用 DEP。所以一开始,这似乎不太可能。但 DEP 很棘手,而且较新的硬件比较旧的硬件功能更强大。所以我认为我们过去摆脱了 DEP 问题,而现在更新的硬件却让我们陷入困境。我们的服务器管理员关闭了 DEP 保护(针对第 3 方应用程序),重新启动,我们的旧代码就可以工作了!虽然我们最终将迁移到较新的库,但这对我们来说将是一个很好的短期修复,因为它让我们不必对这个运行良好的应用程序进行回归测试。

总结一下:由于数据执行保护 (DEP) 干扰 HTTPRIO 对象的创建,我们的 Delphi2005 应用程序在新建的 Windows2003 服务器上崩溃了。 RIO 将无一异常(exception)地被创建,看起来是有效的。但是,当使用关联的 IInvokable 对象时,它会在尝试在线通信之前引发访问冲突。感谢我们合作且非常耐心的管理员、开发同事 Mcmar、Beyond Compare 和 Jean-Marie Babet。

关于delphi - Indy 9 和 Windows Server 2003 之间不兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2485578/

相关文章:

.net - 如何处理返回未记录的 IUnknown 的 COM 服务器方法

delphi - 检测数组中唯一值的数量

java - 卡巴斯基正在阻止 SOAP 服务响应

delphi - delphi 2007 中缩进代码的快捷方式

delphi - 重构 "with" block 的工具

delphi - 为什么 Delphi 变体不能保存对象?

delphi - 为什么我的通用匿名方法类型不兼容?

soap - 解析 WSDL 时出错 - Worklight 6.1 - 后端发现服务

php - Codeception SOAP 命名空间

delphi - 如何访问 TCRDBGrid 组件中的搜索文本?