hma has asked for the wisdom of the Perl Monks concerning the following question:
I released my second module, Biblio::Refbase, to CPAN on Sunday.
I've got now the first CPAN Testers error reports with a quite surprising result. The one of all tests failing is the standard pod-coverage test on some Perl 5.10 environments.
Currently I've got 6 fails (all 5.10) and 42 passes (12 passes on 5.10).(see at CPAN Testers)
I could reproduce the error on Strawberry Perl 5.10 and ActiveState Perl 5.10 on Windows: Perl just crashes when I run t/06-pod-coverage.
I tracked down the location of the crash and the situation when it happens. I use constant in my module and have some index($string, CONSTANT) calls in my code. Pod::Coverage uses Devel::Symdump to walk the symbol tree, which lets Perl crash in the moment it takes action on one of the constants I use as parameter to the index function (my other use of constants makes no problems).
I've prepared a code snippet that simulates the situation I think my module enters.
Here's the code:
use Devel::Symdump; my $x = Mod::idx('some string'); print "x=$x\n"; # works, x=5 my $obj = Devel::Symdump->new('Mod'); # crash on 5.10 package Mod; use constant 'STRING' => 'string'; sub idx { my $s = shift; return index($s, STRING); }
The crash happens in Devel::Symdump (version 2.08, line 55), where this code is executed:
local(*ENTRY) = $val;
If I print $val it reads: GLOB(0x1fa64e4)
Further investigation lead me to constant.pm (1.17, line 106):
if ($symtab && !exists $symtab->{$name}) { # No typeglob yet, so we can use a reference as space- # efficient proxy for a constant subroutine # The check in Perl_ck_rvconst knows that inlinable # constants from cv_const_sv are read only. So we have to: Internals::SvREADONLY($scalar, 1); $symtab->{$name} = \$scalar; mro::method_changed_in($pkg); } else { *$full_name = sub () { $scalar }; }
As far as I can tell this is an optimization in 5.10.
If I change the if-condition (0 && $symtab ...) to force the "else" branch, the crash does not happen.
$val then reads: *Mod::STRING
Lucky me, I found a solution for my module. Of course I didn't want to remove pod-coverage from the test suite (and I didn't want to switch to Readonly or plain variables or to use a regex instead of index). If I force the constant into scalar context, it works, too:
index($s, scalar STRING)
$val then reads (with unmodified constant.pm): SCALAR(0x1fa65ec)
I replaced the constant in index() with a simple function showing the state of wantarray(). I think the context is always scalar, so using scalar() should make no difference. But it does in the situation above!?
At this point I came to the edge of my knowledge and decided to head for the wisdom of the monks (I've been registered here for more than a year but never posted something until now. But I've read many, many marvellous posts. Thanks, monks!)
I'm very interested in some explanation or direction to the source of some explanation.
And then, if the problem I encountered is a bug (I think so), I would like advice whom to tell.
My assumptions (in descending order): It's a bug in
Thanks in advance,
Henning Manske
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: constant.pm + index() + Pod::Coverage crashes on Perl 5.10
by Anonymous Monk on Dec 18, 2015 at 10:16 UTC | |
by Corion (Patriarch) on Dec 18, 2015 at 10:27 UTC | |
by Anonymous Monk on Jan 07, 2016 at 12:28 UTC |