[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Avoiding leaks when using SVN::Fs, etc.

From: Dan Mercer <dmercer_at_8kb.net>
Date: 2006-04-13 21:59:21 CEST

Dan Mercer wrote:
> Hi folks,
>
> I have some tools that make use of the perl bindings to Subversion
> 1.3. As we are dealing with moderate amounts of data in long running
> processes, we are managing memory using the SVN::Pool interface but it
> appears that we are leaking memory. The leak I am focusing on right
> now is related to how I am calling SVN::Fs::file_contents, (though I
> have found other leaks in at least my usage of apply_textdelta and
> send_string).

The leak I described appears be in the getline method of SVN:Stream (in
Core.pm):

sub getline
{
    my $self = shift;
    *$self->{pool} ||= SVN::Core::pool_create (undef);
    my ($buf, $eof) = *$self->{svn_stream}->readline ($/, *$self->{pool});
    return undef if $eof && !length($buf);
    return $eof ? $buf : $buf.$/;
}

It appears that SVN::Stream, $self->{pool} will never exist and so is
always allocated for the read. This memory is not cleaned up, even if a
default pool is created prior to the read. Fortunately, file contents
can be read using the 'read' method in a way that doesn't cause a memory
leak:

my $stream = SVN::Fs::file_contents($root, $path, $pool);
my $size = SVN::Fs::file_length($root, $path, $pool);
my $data =
''; #
must be a scalar and not undef!
$stream->read($data, $size); #
$data contains file contents

I am including a patch to my earlier script that demonstrates that
<$stream> still leaks, even if a subpool has been explicitly created. It
also demonstrates a non-leaky read of file contents using the read method.

--- svn_find_leak.pl Thu Apr 13 10:50:24 2006
+++ svn_find_leak2.pl Thu Apr 13 12:43:34 2006
@@ -30,13 +30,20 @@
    # the test looks like our actual use-case, but if you do away with
    # this and just allocate from $p, the leak will still occur.
    my $sp = SVN::Pool->new($p);
- my $stream = SVN::Fs::file_contents($root, $path, $sp);
    # we only leak if we try to read from $stream
    if (defined $leak) {
+ $sp->default();
+ my $stream = SVN::Fs::file_contents($root, $path, $sp);
        my $contents = <$stream>;
+ $stream = undef;
+ } else {
+ my $contents = '';
+ my $stream = SVN::Fs::file_contents($root, $path, $sp);
+ my $size = SVN::Fs::file_length($root, $path, $sp);
+ $stream->read($contents, $size);
+ $stream = undef;
    }
    # cleanup
- $stream = undef;
    $sp = undef;

Hopefully this will be helpful to those making use of the perl bindings
to SVN. I would submit a patch for getlines(), but I'm not really sure
what the appropriate fix should be... maybe this will help someone with
greater perl skills than myself devise a real fix.

Dan M.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Thu Apr 13 22:13:48 2006

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.