Hello, We are using the latest version of Apache (1.3.33) and mod_perl (1.29) running on FreeBSD 4.9. When mod_perl is compiled as a DSO the server grows by approximately 12MB every time it does a graceful restart. When it gets greater than 512MB FreeBSD stops giving it more memory (this can be changed in the kernel) the server will die. I have heard of other people with this problem and it seems to be widely known. In our environment this only happens on the FreeBSD servers, Linux is unaffected
The advice appears to be either do a full restart or compile in mod_perl with Apache. A full restart would inconvenience many users and is not practical. Does anyone know of a fix? We compiled in mod_perl with Apache which fixed the memory leak but introduced a very strange bug. A hash was being corrupted, only some data was being set when a package is preloaded. This does not happen when compiled as a DSO. Again, Linux is unaffected by this bug even when mod_perl is compiled in with Apache. I produced a short test case to demonstrate this bug. It appears that on FreeBSD when packages are preloaded they are compiled twice. This does not happen on Linux. We found this out by tie()ing a hash and writing every access to a file. The test case sets two keys on a hash. When this is preloaded on Linux the following happens to the hash on Apache start up: Hash is created Key 'a' is set Key 'b' is set and the hash is destroyed when Apache exits. I would expect this behaviour. On FreeBSD when compiled as a DSO the following happens: Hash 1 is created Key 'a' is set on hash 1 Key 'b' is set hash 1 Hash 1 is destroyed Hash 2 is created Key 'a' is set on hash 2 Key 'b' is set hash 2 Hash 1 and 2 are the same declared hash but different instances. As you can see it appears the code has been compiled twice but it runs as normal. When the same code is preloaded on a build where mod_perl is compiled into Apache the following happens which demonstrates the bug: Hash 1 is created Key 'a' is set on hash 1 Key 'b' is set hash 1 Key 'a' is set on hash 1 Hash 2 is created Hash 1 is destroyed Key 'b' is set hash 2 Therefore the hash is only populated with 'b' as 'a' has been set twice on the first instance of the hash. This does not happen if the PerlFreshRestart is not defined in the Apache configuration, but this means we cannot update code with a graceful restart. Does anyone know of a fix? The code for the test case is defined below. The bug only appears when the Test::A and Test::B packages are defined in separate files. If they are defined in-line, even in a BEGIN block the bug does not appear. The bug also disappears when the hash is defined as a package variable 'our' rather than a lexically scoped variable 'my'. Note the 'use Test::A' and 'use Test::B' must come after the 'set' subroutine as they call it. We are therefore in a situation where on FreeBSD if we use mod_perl as a DSO the server crashes and if we compile it in with Apache data gets corrupted. We have tested this on vanilla and FreeBSD ports builds. None of these bugs are present on Linux. So can anyone give us advice on fixing the memory leak and/or fixing the data corruption? Any suggestions are gratefully received. Kind regards, Tim Test code (Test.pm, Test/A.pm, Test/B.pm) Test.pm ------------------ package Test; use strict; use warnings; use Data::Dumper; my %hash; sub set { $hash{$_[1]} = ''; }; sub handler { print Dumper \%hash; } use Test::A; use Test::B; 1; ------------------ Test/A.pm ------------------ package Test::A; use strict; use warnings; Test->set('a'); 1; ------------------ Test/B.pm ------------------ package Test::B; use strict; use warnings; Test->set('b'); 1; ------------------ -- Timothy Coggins Perl Programmer, Sophos Tel: 01235 559933 Web: www.sophos.com Sophos - protecting businesses against viruses and spam