Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I disable Devel::Cover for forked child processes?

I noticed, that when I run my program with perl -MDevel::Cover=-silent,-nogcov foo.pl to collect coverage information for foo.pl, I am getting massive slowdowns from parts of my program that fork and exec non-perl programs like tar, gzip or dpkg-deb. Thanks to this question I figured out how to disable Devel::Cover selectively, so I'm now writing:

my $is_covering = !!(eval 'Devel::Cover::get_coverage()');
my $pid = fork();
if ($pid == 0) {
    eval 'Devel::Cover::set_coverage("none")' if $is_covering;
    exec 'tar', '-cf', ...
}

Doing so, shaves off five minutes of runtime per test which, for 122 tests saves me 10 hours of computation time.

Unfortunately, I cannot always add this eval statement into the forked child process. For example it's impossible to do so when I use system(). I want to avoid rewriting each of my system() calls to a manual fork/exec.

Is there a way to disable Devel::Cover for my forked processes or basically for everything that is not my script foo.pl?

Thanks!

like image 982
josch Avatar asked Jan 07 '20 07:01

josch


1 Answers

Forks::Super is kind of heavy, but it has the feature of post-fork callbacks that are executed after each fork but before any other code in a child process is executed.

use Forks::Super;
my $is_covering = !!(eval 'Devel::Cover::get_coverage()');
POSTFORK_CHILD {
    # runs in every child process immediately after fork()
    eval 'Devel::Cover::set_coverage("none")' if $is_covering;
};
...
like image 77
mob Avatar answered Sep 20 '22 17:09

mob