alexander_lunev has asked for the wisdom of the Perl Monks concerning the following question:

Greetings to all! I'm trying to make work old code (proven to work on 5.8.6) with new perl (5.24.1), and in some point it goes to core dump. Here's my own localization class:
package Hello::Locale; use strict; use Encode qw(encode); require Locale::Maketext::Lexicon; use base qw( Locale::Maketext); our %Lexicon = ( _AUTO => 1 ); sub get_handle { my $class = shift; my( $lang, $enc ) = @_; my $self = $class->SUPER::get_handle($lang); $self->{encoding} = $enc; $self; } sub maketext { my $self = shift; my @params = @_; my $result = encode( $self->encoding(), $self->SUPER::maketext( @p +arams)); $result; } sub load { my $self = shift; my %params = @_; Locale::Maketext::Lexicon->import( { $self->language_tag() => [ %p +arams], _decode => 1}); 1; } package Hello::Locale::ru; use Hello::Locale; use base qw( Hello::Locale); our %Lexicon = (); our $LEXICON_LOADED = 1; 1;
Here's my a program to test my localization class:
#!/usr/local/bin/perl use strict; use Hello::Locale; use Data::Dumper; my $filename = shift; my $lh = Hello::Locale->get_handle("ru","KOI8-R"); $lh->load( Messages => $filename); no strict 'refs'; print Dumper( $lh ); print "Lexicon loaded\n" if ${ref($lh)."\::LEXICON_LOADED"} ; print Dumper( %{ref($lh)."\::Lexicon" } );
And here's a result:
% ./test.pl file.msg $VAR1 = bless( { 'encoding' => 'KOI8-R', 'blacklist' => { 'get_handle' => 1, 'new' => 1, 'encoding' => 1, 'language_tag' => 1, 'init' => 1, 'failure_handler_auto' => 1, '_ambient_langprefs' => 1, '_langtag_munging' => 1, '_die_pointing' => 1, 'maketext' => 1, '_compile' => 1, '_try_use' => 1, '__ANON__' => 1, 'whitelist' => 1, 'fallback_languages' => 1, '_lex_refs' => 1, 'blacklist' => 1, 'fail_with' => 1, '_add_supers' => 1, 'fallback_language_classes' => 1 } }, 'Hello::Locale::ru' ); Lexicon loaded Segmentation fault (core dumped)
Now, if i add before a call to $lh->maketext('ok') before print Dumper( %{ref($lh)."\::Lexicon" } ); line - it works and no core dumping. In short, with 5.8.6 i was able to access %subclass::Lexicon before calling $superclass->maketext('anything'), but with 5.24.1 i can't, as if %Lexicon is not exists before $superclass->maketext('anything') call. Is it normal?

Replies are listed 'Best First'.
Re: Core dump while trying to access %Lexicon in Locale::Maketext subclass
by choroba (Cardinal) on Jun 15, 2017 at 12:14 UTC
    I don't have neither any experience with Maketext, nor the file.msg, so I tried with a random file. The output was different:
    Can't locate Locale/Maketext/Lexicon/Messages.pm in @INC (you may need + to install the Locale::Maketext::Lexicon::Messages module) (@INC con +tains: ...) at (eval 5) line 1. BEGIN failed--compilation aborted at (eval 5) line 1.
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Yes, sorry, it's a subclass for my own messages format:
      package Locale::Maketext::Lexicon::Messages; use strict; use Encode qw( decode); require Locale::Maketext::Lexicon; sub parse { my( $class, @content) = @_; my $res = {}; my $decode = Locale::Maketext::Lexicon::option( 'decode'); foreach ( @content) { /^\s*$/o and next; /^\s*#/o and next; $res->{ $1} = $2 if (/^\s*([^\s:]*)\s*:\s*(.*)$/o); } return $res; } 1;
      And the file.msg format is like this:
      message_code1: Message Text 1 message_code2: Message Text 2
Re: Core dump while trying to access %Lexicon in Locale::Maketext subclass
by beech (Parson) on Jun 15, 2017 at 23:19 UTC

    Hi,

    Nice discovery :)

    I get

    Faulting application perl.exe, version 5.18.2.2, faulting module perl518.dll, version 0.0.0.0, fault address 0x000d74da.

    panic: gv name too long (4294967294) at ...strawberry-perl-5.18.2.2-32bit-portable/perl/lib/Data/Dumper.pm line 587.

    which comes from Perl_gv_name_set

    If I use

    print Dumper( \%{ref($lh)."\::Lexicon" } );
    then there is no panic

    If I do print keys %Hello::Locale::ru::Lexicon ; it only returns message_code2, but a second time it returns message_code1message_code2

    Since lexicon uses perltie/tiehash, I suspect its related to Bug #128588 for perl5: Tied hash magic ignored in references the first time 'round

      Thanks! I'll rewrite the code with \%{ ref($lh)."\::Lexicon" }.