The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,425 other followers

When a Delphi TCP server causes sudden EIdConnClosedGracefully Exceptions on the client

Posted by jpluimers on 2018/09/19

I always forget which sides of the connection throw this error, but the client side does as explained in [WayBackdelphi – Troubleshooting EIdConnClosedGracefully Exceptions? – Stack Overflow by [WayBackRemy Lebeau the main Indy contributor:

EIdConnClosedGracefully means the other party … has disconnected its end of the connection. Once that exception has been raised, you cannot send more data to the other party. You must reconnect first.

In this case, the server side of a legacy Delphi application I temporarily took over was suddenly closing the connection because of these reasons:

  1. The OnExecute handler of the TIdTCPServer fired a TIdSync.SynchronizeMethod(MyMethod) call propagating to
  2. TThread.Synchronize queued the call to MyMethod
  3. MyMethod got called in a separate thread executing its code
  4. The MyMethod code threw an exception but didn’t log it (not even handle it)
  5. TThread.Synchronize got back in the calling thread and re-raised the exception
  6. The OnExecute handler of the TIdTCPServer didn’t catch log (not even handle) the exception

This caused this cascade in the underlying TIdThread.Execute around the TIdTCPServer connection instance:

  1. the underlying TIdThread.Execute to check TIdThread.HandleRunException which returns fals resuling
  2. TIdThread.Execute to call Terminate calling in turn
  3. TIdContext.AfterRun calling
  4. TIdCustomTCPServer.ContextDisconnected which then disconnects the TCP connection

Luckily, the OnDisconnectHandler of the TIdTCPServer did log the disconnect, but it would also destroy the TIdContext.Data and nil it.

However, that TIdContext.Data internally was referenced from other places as well, so other threads would now throw errors because they were doing a reference-after-free, a special case of Dangling Pointer bugs.

A few major thing here

  • Always log Exceptions occurring in IdTCPServerExecute  method!
  • If you let Exceptions escape from a `IdTCPServerExecute` method, your connection will be killed.
  • A killed connection is a “fail early, fail fast” mechanism that lets your users know soon that something is wrong.
    • Be sure to have a mechanism in place to fix those things soon as well.

–jeroen

2 Responses to “When a Delphi TCP server causes sudden EIdConnClosedGracefully Exceptions on the client”

  1. “Always log Exceptions occurring in IdTCPServerExecute method!” – alternatively, you can use the server’s OnException event, which is fired for any exception that escapes the OnConnect, OnExecute, or OnDisconnect event.
    “If you let Exceptions escape from a IdTCPServerExecute method, your connection will be killed.” – that is well-known and documented behavior (http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdTCPServer_OnExecute.html).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: