Skip Menu |

This queue is for tickets about the IO-Socket-SSL CPAN distribution.

Report information
The Basics
Id: 125867
Status: resolved
Priority: 0/
Queue: IO-Socket-SSL

People
Owner: Nobody in particular
Requestors: leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in:
  • 2.056
  • 2.058
Fixed in: (no value)



Subject: Memory leak at close time
I've been investigating a memory leak of a long-running HTTPS process as part of https://rt.cpan.org/Ticket/Display.html?id=124927. I suspect the issue is within IO::Socket::SSL. This is against version 2.056. If I regularly poll HTTPS servers in a long-running process, then the memory grows linearly without bounds over time. Analysis with Devel::MAT has so far revealed this is unbounded growth of the my %SSL_OBJECT; hash in IO/Socket/SSL.pm. By inserting some `print STDERR` statements in key places, it appears that every time the poll interval comes up, it finds that the old connection has been closed by the server, so it has to be destroyed and recreated. The line sub stop_SSL 1430: delete ${*$self}{_SSL_object}; runs, deleting the _SSL_object key from the instance, so that in a moment later when the SSL socket object itself is destroyed, the line sub DESTROY 2010 my $ssl = ${*$self}{_SSL_object} or return; finds nothing of interest, so returns before it gets to 2011 delete $SSL_OBJECT{$ssl}; This causes an unbounded accumulation of keys in %SSL_OBJECT, and so the process memory grows indefinitely. Another small observation is that this seems very related to connection setup/close, because if I poll at sufficiently small interval (say, 1 second) then the servers I connect to don't get bored and timeout the connections, so sockets get reused. In that case, no new SSL connections need creating and old ones destroying, and the memory usage remains flat. -- Paul Evans
Show quoted text
> > my %SSL_OBJECT; > ...
Thanks for debugging the issue. I've tried to fix the issue in https://github.com/noxxi/p5-io-socket-ssl/commit/7a19aaaf31cca0973179f820b81a3589fcacfe19. It seems to fix the problem for me. Please check if it fixes the problem for you to and if it does I'll release a new version. Regards, Steffen
On Tue Jul 17 14:55:25 2018, SULLR wrote: Show quoted text
> Thanks for debugging the issue. I've tried to fix the issue in > https://github.com/noxxi/p5-io-socket- > ssl/commit/7a19aaaf31cca0973179f820b81a3589fcacfe19. It seems to fix > the problem for me. Please check if it fixes the problem for you to > and if it does I'll release a new version.
Yeah, that patch appears to fix it for me too, my test script no longer leaks at either 1 or 10-second intervals. Seems like a new version would be good then. -- Paul Evans
Show quoted text
> > Yeah, that patch appears to fix it for me too, my test script no > longer leaks at either 1 or 10-second intervals. > > Seems like a new version would be good then.
Thank you for testing. I've no released 2.057 with the fix.
Actually this doesn't quite seem resolved after all :( With new version 2.058 we don't get any leaking ARRAYs any more, but we still have some leaking SCALARs. I've traced that down with similar techniques, this time to the contents of the %CREATED_IN_THIS_THREAD hash. The connect_SSL or accept_SSL methods put keys into this hash, but (at least in my test-case with stop_SSL) the DESTROY method never gets a chance to remove them from the hash [line 2020] because $ssl isn't defined, having been deleted itself by stop_SSL [line 1437]. I don't quite see such a simple solution as before. Maybe moving more of the logic from DESTROY into stop_SSL might be best, and having DESTROY simply call it? The attached patch does *seem* to fix the issue, but I'm not sure if it's making the underlying problem worse or not. -- Paul Evans
Subject: rt125867-2.patch
--- /usr/share/perl5/IO/Socket/SSL.pm 2018-07-19 08:45:08.000000000 +0100 +++ lib/IO/Socket/SSL.pm 2018-07-24 00:15:15.453828470 +0100 @@ -1433,6 +1433,10 @@ Net::SSLeay::X509_free($cert); } delete ${*$self}{_SSL_object}; + if (!$use_threads or delete $CREATED_IN_THIS_THREAD{$ssl}) { + $self->close(_SSL_in_DESTROY => 1, SSL_no_shutdown => 1) + if ${*$self}{'_SSL_opened'}; + } ${*$self}{'_SSL_opened'} = 0; delete $SSL_OBJECT{$ssl}; untie(*$self);
Show quoted text
> The attached patch does *seem* to fix the issue, but I'm not sure if > it's making the underlying problem worse or not.
Thanks for the follow-up. I think it should be enough to just remove the object from CREATED_IN_THIS_THREAD. I did so in commit 49c7878c and released it as 2.059. Hopefully it works for you.