问题
I'm having a problem with a Delphi application on some Windows 2003 servers. It uses a webservice call to connect with another server and transmit data back and forth. As soon as the app gets to the Authenticate method, the app dies. The app has worked for years on previous boxes with Win Server 2003, but it doesn't on freshly built machines. The machines are set up the same way for the most part, but there is clearly some config setting that differs that I'm not able to track down. Also, while the error becomes apparent in the call to Authenticate, packet sniffing proves that nothing ever happens between the app and the server it's trying to contact, which strengthens my thoughts that something is dieing early on in setting up the connection. I can't duplicate the error locally, so I can't step through the app in a debugger either. Any thoughts on why an Indy 9 Delphi web connection might silently fail?
回答1:
Here's where it was blowing up:
MySoapObject := GetNewSoapObject(usewsdl, addr, FHTTPRIO);
...
if MySoapObject <> nil then
MySoapObject.SomeFunction(); // BOOM! Access Violation here.
Solution found! It turned out to be DEP (Data Execution Prevention). When I re-built our code with Delphi2007 soap libraries, the probelm went away. Since I didn't want to do that (de-serialization caused problems that made the server choke on our XML), and my mgr really didn't want to do that (involved extensive regression testing), I looked for differences between the SOAP source code between D2005 and D2007, with the idea of making a targeted change on whatever was different between the two. i.e find the difference that makes a difference. Beyond Compare was my buddy here. One change kind of stood out as being odd - the RIO.PAS now includes a new unit PrivateHeap.pas. Wondering why, I googled and found a similar problem with an explanation that seemed to be right on target.
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
Bingo! Now here's where it gets tricky. The DEP has always been enabled on our servers. So at first, this seemed like it wasn't likely. But DEP is tricky, and newer hardware is more capable than the older hardware. So I think we got away with DEP issues in the past, and now the newer hardware is tripping us up. Our server admin flipped DEP protection off (for 3rd-party apps), rebooted, and our old code worked! While we'll eventually move to the newer libraries, this will be a great short-term fix for us as it lets us avoid having to regression test this app that works fine otherwise.
So to summarize: Our Delphi2005 app was crashing on newly-built Windows2003 servers due to Data Execution Prevention (DEP) interfering with the creation of the HTTPRIO object. The RIO would be created without exception, appeared valid. But when the associated IInvokable object was used, it would throw an access violation, prior to attempting to communicate on the wire at all. Kudos to our cooperative and very patient admins, fellow dev Mcmar, Beyond Compare, and Jean-Marie Babet.
回答2:
Could it be the Firewall causing issues on 2003?
来源:https://stackoverflow.com/questions/2485578/incompatibilities-between-indy-9-and-windows-server-2003