Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PATCH] Memory leak in Storable::dclone with STORABLE_freeze hook #13862

Closed
p5pRT opened this issue May 20, 2014 · 9 comments
Closed

[PATCH] Memory leak in Storable::dclone with STORABLE_freeze hook #13862

p5pRT opened this issue May 20, 2014 · 9 comments
Labels

Comments

@p5pRT
Copy link

p5pRT commented May 20, 2014

Migrated from rt.perl.org#121928 (status was 'resolved')

Searchable as RT121928$

@p5pRT
Copy link
Author

p5pRT commented May 20, 2014

From a.solovey@gmail.com

Storable documentation recommends using dclone shortcut in
STORABLE_freeze hook​: "Unless you know better, serializing hook should
always say​:
  sub STORABLE_freeze {
  my ($self, $cloning) = @​_;
  return if $cloning; # Regular default serialization
  ....
  }

  in order to keep reasonable dclone() semantics."

However, this causes a memory leak which is easy to observe with the
following small script​:

=== storable-leak.plx ===
#!/usr/bin/perl
use Storable qw( dclone );

package Foo {
  sub new { return bless {}, __PACKAGE__ }

  sub STORABLE_freeze {
  my( $self, $cloning ) = @​_;
  # Switch to regular default serialization results in memory leak
  return if $cloning;
  return 'Foo';
  }
}

my $d = Foo->new();
while(1)
{
  dclone( $d );
}

The leak is caused by missing cleanup of empty array value returned by
the hook. I've attached a simple patch for Storable-2.45 which fixes
this issue.

Version information​:

  $ perl -MStorable -E 'say Storable->VERSION'
  2.45

  $ perl -v

  This is perl 5, version 18, subversion 2 (v5.18.2) built for
x86_64-linux-gnu-thread-multi

--
Sincerely,
Alex Solovey

@p5pRT
Copy link
Author

p5pRT commented May 20, 2014

From a.solovey@gmail.com

Storable.patch
--- Storable.xs.orig	2014-05-20 14:35:36.175918558 -0500
+++ Storable.xs	2014-05-20 14:33:14.595919745 -0500
@@ -3011,6 +3011,10 @@
 	 */
 
 	if (!count) {
+		/* free empty list returned by the hook */
+		av_undef(av);
+		sv_free((SV *) av);
+		
 		/*
 		 * They must not change their mind in the middle of a serialization.
 		 */

@p5pRT
Copy link
Author

p5pRT commented May 21, 2014

From @tonycoz

On Tue May 20 12​:54​:06 2014, a.solovey@​gmail.com wrote​:

Storable documentation recommends using dclone shortcut in
STORABLE_freeze hook​: "Unless you know better, serializing hook should
always say​:

Thanks, I'll apply this once 5.20 is released.

I've attached the patch as a git format-patch patch.

Tony

@p5pRT
Copy link
Author

p5pRT commented May 21, 2014

From @tonycoz

0001-Memory-leak-in-Storable-dclone-with-STORABLE_freeze-.patch
From 2b8ff1ba4985ae0825effa13c6b14116aaa8919e Mon Sep 17 00:00:00 2001
From: Alex Solovey <a.solovey@gmail.com>
Date: Wed, 21 May 2014 16:27:14 +1000
Subject: [PATCH 1/2] Memory leak in Storable::dclone with STORABLE_freeze
 hook

Storable documentation recommends using dclone shortcut in
STORABLE_freeze hook: "Unless you know better, serializing hook should
always say:
                sub STORABLE_freeze {
                    my ($self, $cloning) = @_;
                    return if $cloning; # Regular default serialization
                    ....
                }

            in order to keep reasonable dclone() semantics."

However, this causes a memory leak which is easy to observe with the
following small script:

=== storable-leak.plx ===
use Storable qw( dclone );

package Foo {
     sub new { return bless {}, __PACKAGE__ }

     sub STORABLE_freeze {
         my( $self, $cloning ) = @_;
         # Switch to regular default serialization results in memory leak
         return if $cloning;
         return 'Foo';
     }
}

my $d = Foo->new();
while(1)
{
     dclone( $d );
}
===

The leak is caused by missing cleanup of empty array value returned by
the hook. I've attached a simple patch for Storable-2.45 which fixes
this issue.

Reported in [perl #121928]
---
 AUTHORS                   |    1 +
 dist/Storable/Storable.xs |    4 ++++
 2 files changed, 5 insertions(+)

diff --git a/AUTHORS b/AUTHORS
index 568c497..c59cefc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -54,6 +54,7 @@ Alexander Voronov		<alexander-voronov@yandex.ru>
 Alexei Alexandrov		<alexei.alexandrov@gmail.com>
 Alex Davies			<adavies@ptc.com>
 Alex Gough			<alex@rcon.org>
+Alex Solovey			<a.solovey@gmail.com>
 Alex Vandiver			<alexmv@mit.edu>
 Alex Waugh			<alex@alexwaugh.com>
 Alexander Bluhm			<alexander_bluhm@genua.de>
diff --git a/dist/Storable/Storable.xs b/dist/Storable/Storable.xs
index 9b55b50..9c13e33 100644
--- a/dist/Storable/Storable.xs
+++ b/dist/Storable/Storable.xs
@@ -3052,6 +3052,10 @@ static int store_hook(
 	 */
 
 	if (!count) {
+		/* free empty list returned by the hook */
+		av_undef(av);
+		sv_free((SV *) av);
+		
 		/*
 		 * They must not change their mind in the middle of a serialization.
 		 */
-- 
1.7.10.4

@p5pRT
Copy link
Author

p5pRT commented May 21, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented May 28, 2014

From @tsee

Thanks, applied. Not pushed to blead, so no commit id to share yet.

@p5pRT
Copy link
Author

p5pRT commented May 28, 2014

@tsee - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed May 28, 2014
@p5pRT
Copy link
Author

p5pRT commented May 28, 2014

From @tsee

On Wed May 28 01​:07​:49 2014, smueller@​cpan.org wrote​:

Thanks, applied. Not pushed to blead, so no commit id to share yet.

Applied as 6520641.

@p5pRT
Copy link
Author

p5pRT commented May 28, 2014

From @ppisar

On 2014-05-28, Steffen Mueller via RT <perlbug-followup@​perl.org> wrote​:

On Wed May 28 01​:07​:49 2014, smueller@​cpan.org wrote​:

Thanks, applied. Not pushed to blead, so no commit id to share yet.

Applied as 6520641.

Would it be possible do a release on CPAN. perl-5.20 has 2.49, CPAN 2.45.

-- Petr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant