Subject: | FD leak in -ErrFile option to Env? |
Date: | Wed, 11 Aug 2010 03:41:17 +0100 |
To: | bug-BerkeleyDB [...] rt.cpan.org |
From: | Conrad Hughes <conrad.hughes [...] ed.ac.uk> |
O/S: Debian 5.0 (stable)
Perl: 5.10.0
BerkeleyDB: 0.42
Dear Mr Marquess,
Thanks very much for maintaining the BerkeleyDB module --- I find it
extremely useful in a range of scripts.
I'm writing to report a rather difficult-to-pin-down problem whereby I
run out of file descriptors when using BerkeleyDB and IPC::Run3
together. If I open an environment with the -ErrFile switch set to
*STDERR and then immediately *close* that environment (!), every
subsequent invocation of run3 leaks two file descriptors. Without the
-ErrFile option no such problem occurs.
The attached code exhibits the failure (I use /proc/.../fd in order to
quickly find out what file descriptors my process has open, so the code
should be run under a fairly modern Linux; without that feature though,
it should still be possible to observe failure just by waiting for the
script to run out of handles).
I seem to be able to work around this using system() instead of run3(),
so it's not a crucial issue but I'd be curious to know what the root
cause is. It could certainly also be a problem with run3() rather than
BerkeleyDB --- the fact that tweaking BDB flags controls the failure is
what leads me to write to you first.
I'm aware that BDB shouldn't be used in conjunction with fork() (which I
think run3() uses), but in the C world I've worked around this
constraint in the past by closing BDB environments and databases before
forking, and re-opening afterward; it would appear that that trick
doesn't work here, since I've already closed my environment before the
run3() calls start to leak.
Am I doing anything obvious wrong, or do you think there's something to
this?
Best regards,
Conrad Hughes
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
#!/usr/bin/perl
# Demonstrates a leak in BerkeleyDB -ErrFile: comment out the -ErrFile line,
# and this script executes completely; otherwise, it will show an ever-
# increasing number of file descriptors in use and, if your default max fds is
# 1023, eventually die.
# This is intended for use on a modern linux, supporting /proc/.../fd and
# /dev/null.
use strict;
use warnings;
use IPC::Run3;
use BerkeleyDB;
my $tmpdir = 'tmpdir';
mkdir $tmpdir unless -d $tmpdir;
my $env = BerkeleyDB::Env->new(
-Home => $tmpdir,
-ErrFile => *STDERR, # Comment this line out and the leak vanishes
-Flags => DB_CREATE
) or die $BerkeleyDB::Error;
$env->close();
$env = undef;
my $ufd = used_fds();
for(0 .. 511) {
run3 ['cat', '/dev/null'], \undef, 'tmpdir/stdout', 'tmpdir/stderr';
my $nufd = used_fds();
print "$ufd -> $nufd descriptors in use.\n";
$ufd = $nufd;
}
sub used_fds {
opendir DIR, "/proc/$$/fd" or die "Couldn't open /proc/$$/fd: $!";
my @entries = readdir(DIR);
closedir DIR;
@entries - 2
}