Skip to content

panic: invalid pad in intro_my with perl -MO=... and use v5.39* #21981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wolfsage opened this issue Feb 12, 2024 · 6 comments · Fixed by #22090
Closed

panic: invalid pad in intro_my with perl -MO=... and use v5.39* #21981

wolfsage opened this issue Feb 12, 2024 · 6 comments · Fixed by #22090
Assignees

Comments

@wolfsage
Copy link
Contributor

wolfsage commented Feb 12, 2024

Description

With -DDEBUGGING:

$ ./perl -Ilib -MO=Concise -e 'use v5.39'
panic: invalid pad in intro_my: 0x55ef8a17ca20[0x55ef8a1945b0] at -e line 1

Also

$ ./perl -Ilib -MO=Deparse -e 'use v5.39'
panic: invalid pad in intro_my: 0x55cd471baa20[0x55cd471d2630] at -e line 1.
sub BEGIN {
    require v5.39;
    ()
}

Note this doesn't happen with anything use v5.38 or less, only 5.39 and higher.

According to a bisect this appears to have been introduced here:

HEAD is now at 6d65c70ff0 Import from `builtin` version bundles should be idempotent on existing symbols
good - zero exit from ./perl -Ilib -MO=Concise -e use v5.39;
48d382667948f6a16c732c47791ca4be891a9bdb is the first bad commit
commit 48d382667948f6a16c732c47791ca4be891a9bdb
Author: Paul "LeoNerd" Evans <[email protected]>
Date:   Fri Jan 19 15:00:35 2024 +0000

    Have `use VERSION` and `perl -E` import a corresponding `use builtin` bundle
@leonerd leonerd self-assigned this Feb 12, 2024
@leonerd
Copy link
Contributor

leonerd commented Feb 13, 2024

Hmm. Specifically it's about Concise:

$ ./perl -Ilib -MO=Concise -e 'use v5.39'
panic: invalid pad in intro_my: 0x565259cf7920[0x565259d179f8] at -e line 1.

$ ./perl -Ilib -e 'use v5.39'
(ok)

The panic appears in pad.h:

$ findsrc | grepin "invalid pad in "
./pad.h:172:        Perl_croak(aTHX_ "panic: invalid pad in %s: 0x%" UVxf "[0x%" UVxf "]",\
169 #  define ASSERT_CURPAD_ACTIVE(label) \  
170     pad_peg(label); \  
171     if (!PL_comppad || (AvARRAY(PL_comppad) != PL_curpad))                \  
172         Perl_croak(aTHX_ "panic: invalid pad in %s: 0x%" UVxf "[0x%" UVxf "]",\  
173             label, PTR2UV(PL_comppad), PTR2UV(PL_curpad));  

Invoked in pad.c:

./pad.c:1478:    ASSERT_CURPAD_ACTIVE("intro_my");

I'll have to read more into it to work out why.

@leonerd
Copy link
Contributor

leonerd commented Feb 13, 2024

Hrm; gdb doesn't show much more of any real excitement:

$ gdb --args ./perl -Ilib -MO=Concise -e 'use v5.39; no v5.39'
...
(gdb) break Perl_croak
Breakpoint 1 at 0x45c745: file util.c, line 1942.
(gdb) run
Starting program: /home/leo/src/bleadperl/perl/perl -Ilib -MO=Concise -e use\ v5.39\;\ no\ v5.39
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, Perl_croak (my_perl=0x555555c942a0, 
    pat=0x555555a19db8 "panic: illegal pad in %s: 0x%lx[0x%lx]") at util.c:1942
1942    {
(gdb) bt
#0  Perl_croak (my_perl=0x555555c942a0, 
    pat=0x555555a19db8 "panic: illegal pad in %s: 0x%lx[0x%lx]") at util.c:1942
#1  0x00005555556b7704 in Perl_pad_new (my_perl=0x555555c942a0, flags=6) at pad.c:199
#2  0x0000555555997e35 in Perl_start_subparse (my_perl=0x555555c942a0, is_format=0, 
    flags=0) at toke.c:12824
#3  0x00005555556e05c6 in Perl_yyparse (my_perl=0x555555c942a0, gramtype=258)
    at perly.y:766
#4  0x00005555555ec7b1 in S_parse_body (my_perl=0x555555c942a0, env=0x0, 
    xsinit=0x55555559b396 <xs_init>) at perl.c:2672
#5  0x00005555555e9eee in perl_parse (my_perl=0x555555c942a0, 
    xsinit=0x55555559b396 <xs_init>, argc=5, argv=0x7fffffffe218, env=0x0) at perl.c:1912
#6  0x000055555559b286 in main (argc=5, argv=0x7fffffffe218, env=0x7fffffffe248)
    at perlmain.c:106

@leonerd
Copy link
Contributor

leonerd commented Feb 13, 2024

More excitement: order matters:

leo@hevva:~/src/bleadperl/perl [git]
$ ./perl -Ilib -e 'use v5.39; use O q(Concise);'
3  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter v ->2
2     <0> stub v ->3
-     <;> ex-nextstate(main 1 -e:1) v:us,*,&,{,$,fea=7 ->3
-e syntax OK

$ ./perl -Ilib -e 'use O q(Concise); use v5.39'
panic: invalid pad in intro_my: 0x5622c15488f0[0x5622c15689a8] at -e line 1.

@tonycoz
Copy link
Contributor

tonycoz commented Mar 20, 2024

It looks like AvARRAY() of the saved pad is being modified after the saves:

tony@venus:.../git/perl6$ gdb --args ./perl -Ilib -MO=Concise -e 'use v5.39'
...
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./perl...
(gdb) b Perl_finish_export_lexical 
Breakpoint 1 at 0xb35be: file builtin.c, line 66.
(gdb) r
Starting program: /home/tony/dev/perl/git/perl6/perl -Ilib -MO=Concise -e use\ v5.39
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, Perl_finish_export_lexical () at builtin.c:66
66          intro_my();
(gdb) n
68          LEAVE;
(gdb) 
69      }
(gdb) p AvARRAY(PL_comppad)
$1 = (SV **) 0x555555ccb9c0
(gdb) p PL_curpad
$2 = (SV **) 0x555555c49f90
(gdb)

@tonycoz
Copy link
Contributor

tonycoz commented Mar 20, 2024

Changing Perl_prepare_export_lexical to use SAVECOMPPAD() fixes it:

void
Perl_prepare_export_lexical(pTHX)
{
    assert(PL_compcv);

    /* We need to have PL_comppad / PL_curpad set correctly for lexical importing */
    ENTER;
    SAVESPTR(PL_comppad_name); PL_comppad_name = PadlistNAMES(CvPADLIST(PL_compcv));
    SAVECOMPPAD();
    PL_comppad      = PadlistARRAY(CvPADLIST(PL_compcv))[1];
    PL_curpad       = PadARRAY(PL_comppad);
}

Trying to see why -MO=... cause this, it's not just Concise, I see it for Deparse, Showlex and Xref too.

@tonycoz
Copy link
Contributor

tonycoz commented Mar 21, 2024

tony@venus:.../git/perl6$ ./perl -Ilib -MB -e 'BEGIN { B::save_BEGINs; } use v5.39'
panic: invalid pad in intro_my: 0x55c071135a20[0x55c07114cf00] at -e line 1.

though I still don't know why.

tonycoz added a commit to tonycoz/perl5 that referenced this issue Mar 21, 2024
When the pad being saved and the pad for PL_compcv is the same,
in some cases the actual exports would result in reallocating the
AvARRAY() for the saved PL_comppad.

The LEAVE in finish_export_lexical() would restore the old PL_comppad
(which is fine) and the pre-reallocation PL_curpad (which isn't fine).

This would later panic.

SAVECOMPPAD; restores PL_comppad on LEAVE and then restores PL_curpad
from PL_comppad, preventing the desync between those values.

It's unclear to me why only the save_BEGINs; causes this, but the fix
does fix a real problem and prevents the panics that I'm aware of
here.

Fixes Perl#21981
tonycoz added a commit that referenced this issue Mar 24, 2024
When the pad being saved and the pad for PL_compcv is the same,
in some cases the actual exports would result in reallocating the
AvARRAY() for the saved PL_comppad.

The LEAVE in finish_export_lexical() would restore the old PL_comppad
(which is fine) and the pre-reallocation PL_curpad (which isn't fine).

This would later panic.

SAVECOMPPAD; restores PL_comppad on LEAVE and then restores PL_curpad
from PL_comppad, preventing the desync between those values.

It's unclear to me why only the save_BEGINs; causes this, but the fix
does fix a real problem and prevents the panics that I'm aware of
here.

Fixes #21981
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants