xslate / p5-Mouse

Lightweight class builder for Perl, as a subset of Moose
https://metacpan.org/release/Mouse
Other
46 stars 32 forks source link

get_all_attributes() crashes when an object has more than 121(126) attributes. #114

Open mf-takayuki opened 2 years ago

mf-takayuki commented 2 years ago

Similar to https://github.com/xslate/p5-Mouse/issues/64

Tested environments.

File:cpanfile

requires 'Mouse', '==2.5.10';

File: Bar.pm

package Bar;
use strict;
use warnings;
use Mouse;
has [qw/
    p1   p2   p3   p4   p5   p6   p7   p8   p9   p10
    p11  p12  p13  p14  p15  p16  p17  p18  p19  p20
    p21  p22  p23  p24  p25  p26  p27  p28  p29  p30
    p31  p32  p33  p34  p35  p36  p37  p38  p39  p40
    p41  p42  p43  p44  p45  p46  p47  p48  p49  p50
    p51  p52  p53  p54  p55  p56  p57  p58  p59  p60
    p61  p62  p63  p64  p65  p66  p67  p68  p69  p70
    p71  p72  p73  p74  p75  p76  p77  p78  p79  p80
    p81  p82  p83  p84  p85  p86  p87  p88  p89  p90
    p91  p92  p93  p94  p95  p96  p97  p98  p99  p100
    p101 p102 p103 p104 p105 p106 p107 p108 p109 p110
    p111 p112 p113 p114 p115 p116 p117 p118 p119 p120
    p121 p122 p123 p124 p125 p126
/] => (
    is => 'ro'
);
no Mouse;
__PACKAGE__->meta->make_immutable;
1;

File: main.pl

use warnings;
use feature qw/say/;
use Bar;

# crashes: 122 attributes.
sub ng_once {
    Bar->meta->get_all_attributes;
}

# segfault: 126 attributes.
sub ng_map {
    map {
        $_->meta->get_all_attributes;
    } ('Bar');
}

# returns wrong value (0): 119 attributes.
sub ng_for {
    my @tmp;
    for ('Bar') {
        push @tmp, $_->meta->get_all_attributes;
    }
    @tmp;
}

sub ok_twice {
    Bar->meta->get_all_attributes;
    Bar->meta->get_all_attributes;
}

my @result = +{
    ng_once  => \&ng_once,
    ng_map   => \&ng_map,
    ng_for   => \&ng_for,
    ok_twice => \&ok_twice,
}->{$ARGV[0]}->();

say scalar @result;
1;

When main.pl is executed, it crashes with following error messages. However, when the method is called twice, it works just fine.

$ perl -I./ -I./local/lib/perl5 ./main.pl ng_once
Bizarre copy of CODE in subroutine exit at ./main.pl line 8.

$ perl -I./ -I./local/lib/perl5 ./main.pl ng_map
Bizarre copy of CODE in block exit at ./main.pl line 14.
zsh: segmentation fault  perl -I./ -I./local/lib/perl5 ./main.pl ng_map

$ perl -I./ -I./local/lib/perl5 ./main.pl ng_for
0

$ perl -I./ -I./local/lib/perl5 ./main.pl ok_twice
126
mf-takayuki commented 2 years ago

This issue seems to occur with perl v5.20 and up.

Confirmed crash with perl v5.20.3, v5.22.4, v5.24.4, v5.30.0 and v5.34.0. Not reproducible with v5.18.4.

tokuhirom commented 2 years ago

How about 5.19.x? if we can detect the target commit, we can detect the cause(maybe...)

syohex commented 2 years ago
% ~/.cpanm/perl-5.19.6/bin/perl -I. main.pl ng_once
126
% ~/.cpanm/perl-5.19.7/bin/perl -I. main.pl ng_once
0

I suppose that the target commit is in from 5.19.6 and 5.19.7. I'll check it in detail later.

tokuhirom commented 2 years ago

Note: https://metacpan.org/release/ABIGAIL/perl-5.19.7/view/pod/perldelta.pod

syohex commented 2 years ago

https://github.com/Perl/perl5/commit/ebdc88085efa6fca8a1b0afaa388f0491bdccd5a

I did git bisect. It says the bug was introduced by this commit.