Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Devel-Cover CPAN distribution.

Report information
The Basics
Id: 57174
Status: resolved
Priority: 0/
Queue: Devel-Cover

People
Owner: Nobody in particular
Requestors: GENEHACK [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.66
Fixed in: 0.65



Subject: Devel::Cover 0.66 does not work with Moose+type constraints
I wish I could boil this down further, but so far I've been unable to. I'll keep trying. Basically, when testing a Moose role with attributes that require Moose::Utils::TypeConstraints, Devel::Cover blows up: $ perl -MDevel::Cover -I./lib t/00-load.t Devel::Cover: Can't find file "generated method (unknown origin)" (generated method (unknown origin)): ignored. Devel::Cover 0.66: Collecting coverage data for branch, condition, pod, statement, subroutine and time. Selecting packages matching: Ignoring packages matching: /Devel/Cover[./] ^t/ \.t$ ^test\.pl$ Ignoring packages in: . /opt/perl/perls/perl-5.12.0/lib/5.12.0 /opt/perl/perls/perl-5.12.0/lib/5.12.0/darwin-2level /opt/perl/perls/perl-5.12.0/lib/site_perl/5.12.0 /opt/perl/perls/perl-5.12.0/lib/site_perl/5.12.0/darwin-2level Devel::Cover: Can't find file "(reeval 239)[/opt/perl/perls/perl- 5.12.0/lib/site_perl/5.12.0/darwin-2level/Moose/Util/TypeConstraints.pm:599]" ((reeval 239)[/opt/perl/perls/perl-5.12.0/lib/site_perl/5.12.0/darwin- 2level/Moose/Util/TypeConstraints.pm:599]): ignored. Devel::Cover: Can't find file "(reeval 96)[/opt/perl/perls/perl- 5.12.0/lib/site_perl/5.12.0/darwin-2level/Moose/Util/TypeConstraints.pm:589]" ((reeval 96)[/opt/perl/perls/perl-5.12.0/lib/site_perl/5.12.0/darwin- 2level/Moose/Util/TypeConstraints.pm:589]): ignored. Devel::Cover: Can't find file "(reeval 240)[/opt/perl/perls/perl- 5.12.0/lib/site_perl/5.12.0/darwin-2level/Moose/Util/TypeConstraints.pm:593]" ((reeval 240)[/opt/perl/perls/perl-5.12.0/lib/site_perl/5.12.0/darwin- 2level/Moose/Util/TypeConstraints.pm:593]): ignored. Segmentation fault (This particular test case is from my MooseX::Role::Pluggable dist.) In this particular case, adding '-replace_ops,off' does NOT fix the problem. In other cases that I've seen but haven't been able to reproduce in a simple or sharable form, adding '-replace_ops,off' DOES fix the problem. (Specifically, in a Catalyst app that's using Catalyst::Model::DBIC::Schema to wrap an existing Schema.) As I said, I'll continue to try to reduce this to something simpler as I have time, but I wanted to get the report into RT before something else popped up demanding my attention...
00-load.t: #! perl use strict; use warnings; { package Foo; use Moose; with 'MooseX::Role::Pluggable'; } package main; use Test::More; diag( "Testing MooseX::Role::Pluggable $MooseX::Role::Pluggable::VERSION, Perl $], $^X" ); my $foo = Foo->new(); ok( $foo->does( 'MooseX::Role::Pluggable' ) , 'role was consumed' ); ok( $foo->can( 'plugin_list' ), 'can look at plugin list' ); is( $foo->plugin_list , undef , 'plugin list is undef with no plugins loaded' ); ok( $foo->can( 'plugin_hash' ), 'can look at plugin hash' ); is( $foo->plugin_hash , undef , 'plugin hash is undef with no plugins loaded' ); done_testing();
Subject: ppaddr-based covering breaks complex regular expressions
sawyerx traced this issue down to Moose's use of complex regular expressions to parse type constraint strings. From there I've simplified the test a lot and came up with 'x' =~ m{ (?: ((??{ 'x' })) )? }x; This piece of code runs fine without Devel::Cover, or with Devel::Cover hooking the runops. Using the ppaddr-based approach, the behavior of the code is changed. The most obvious way to see this change is using a debugging perl, on which it will result in a failed assertion within the regexp engine: perl: regexec.c:2963: S_regmatch: Assertion `(my_perl->Ireg_state).re_state_regoffs == rex->offs' failed. On non-debugging perls there's no hard fail, but incorrect results: $1 will usually be undef, even tho a value of 'x' is to be expected. Sometimes $1 also appears to contain garbage, source code, or constant strings from the perl interpreter, so I'm guessing there's some memory/state corruption going on.
Looking futher, it turns out the issue is being caused by covering opcodes within regexp evals. Covering opcodes with ppaddr-based hooking involves calling Devel::Cover::use_file, which happens to use regular expressions itself. Those regular expressions may change global regexp state, causing the enclosing regexp that did the eval to misbehave. Possible fixes include not calling use_file within regexp evals, making use_file not use regular expressions, pushing all the required regexp state onto the safe stack, or delaying the heavy lifting done in use_file until after the runtime of the code to be covered.
Thanks to everyone involved in this ticket for tracking down the problem and fixing it. The ultimate fix is perl 91332126cd9c948fe94d99b88f88ed9f528cc0d8 as documented in Devel::Cover 2227fc87048d958da104a76fa7b7705292859ac9.