Skip to content
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

SIGSEGV if you croak() from inside free magic invoked by tidying up SAVEt_HINTS + hintsthash #17903

Open
leonerd opened this issue Jun 27, 2020 · 1 comment

Comments

@leonerd
Copy link
Contributor

leonerd commented Jun 27, 2020

I am still investigating the exact situation that triggers it, so I might alter the subject line while I''m working, but....

I have some code that inserts an SV into the (localized) hints hash, which has free magic on it. In fact that is the only magic hook, which is why it is there. I intend to run some code when the hints hash is cleared up. If my code doesn't croak, then all works as expected.

But, if I croak from somewhere inside that free magic, I get a segfault from perl itself. A stack trace from 5.30:

Program received signal SIGSEGV, Segmentation fault.
Perl_leave_scope (my_perl=my_perl@entry=0x5555558aa2a0, base=base@entry=0) at scope.c:922
922     scope.c: No such file or directory.
(gdb) bt
#0  Perl_leave_scope (my_perl=my_perl@entry=0x5555558aa2a0, base=base@entry=0)
    at scope.c:922
#1  0x00005555555bd803 in S_my_exit_jump (my_perl=my_perl@entry=0x5555558aa2a0)
    at perl.c:5327
#2  0x00005555555c6b8e in Perl_my_failure_exit (my_perl=my_perl@entry=0x5555558aa2a0)
    at perl.c:5311
#3  0x000055555569fdc7 in Perl_die_unwind (my_perl=my_perl@entry=0x5555558aa2a0, 
    msv=msv@entry=0x5555560bed90) at pp_ctl.c:1815
#4  0x000055555563359a in Perl_vcroak (my_perl=0x5555558aa2a0, 
    pat=pat@entry=0x7ffff7934e9b "TODO test croak", args=args@entry=0x7fffffffd850)
    at util.c:1711
#5  0x00005555556337ce in Perl_croak_nocontext (
    pat=pat@entry=0x7ffff7934e9b "TODO test croak") at util.c:1745
#6  0x00007ffff7931fcb in on_free_compclassmeta (my_perl=<optimized out>, 
    sv=<optimized out>, mg=<optimized out>) at lib/Object/Pad.xs:697
#7  0x000055555563a041 in S_mg_free_struct (my_perl=my_perl@entry=0x5555558aa2a0, 
    sv=sv@entry=0x5555560be880, mg=0x5555560c2ae0) at mg.c:558
#8  0x000055555563ab71 in Perl_mg_free (my_perl=my_perl@entry=0x5555558aa2a0, 
    sv=sv@entry=0x5555560be880) at mg.c:594
#9  0x0000555555661c20 in Perl_sv_clear (my_perl=my_perl@entry=0x5555558aa2a0, 
    orig_sv=orig_sv@entry=0x555556111388) at sv.c:6599
#10 0x0000555555662396 in Perl_sv_free2 (my_perl=my_perl@entry=0x5555558aa2a0, 
    sv=0x555556111388, rc=<optimized out>) at sv.c:7093
#11 0x0000555555694e04 in S_SvREFCNT_dec (sv=<optimized out>, my_perl=0x5555558aa2a0)
    at inline.h:216
#12 Perl_leave_scope (my_perl=my_perl@entry=0x5555558aa2a0, base=base@entry=25)
    at scope.c:1350
#13 0x00005555555ab01b in Perl_block_end (my_perl=my_perl@entry=0x5555558aa2a0, 
    floor=25, seq=<optimized out>) at op.c:5253
#14 0x00005555555f62a9 in Perl_yyparse (my_perl=my_perl@entry=0x5555558aa2a0, 
    gramtype=gramtype@entry=258) at perly.y:125
#15 0x00005555555c59f3 in S_parse_body (xsinit=0x55555559c580 <xs_init>, env=0x0, 
    my_perl=<optimized out>) at perl.c:2531
#16 perl_parse (my_perl=<optimized out>, xsinit=0x55555559c580 <xs_init>, 
    argc=<optimized out>, argv=<optimized out>, env=0x0) at perl.c:1822
#17 0x000055555559c3c3 in main (argc=<optimized out>, argv=<optimized out>, 
    env=<optimized out>) at perlmain.c:126

When run on a debugperl I get a slightly more exciting failure:

TODO test croak at t/30unit-class.t line 23.
panic: leave_scope inconsistency 56 at t/30unit-class.t line 23.

The code printing that number 56 is because it looked at the next save type from the savestack and didn't recognise it. Oddly, when I wrote some savestack-debugging code relating to #17895 - before I realised the non-constant nature of SAVEt_HINTS.

What I suspect is going on here is that the free magic on my SV is being invoked at a time after Perl_leave_scope() has popped the type/ptr/i32 off the save stack but before it has popped the second pointer as part of the hints HV. The savestack now isn't in a consistent state, meaning the croak that runs inside my free magic sees an inconsistent state of the save stack, and this causes further upset.

I suspect a fix for #17895 would fix this bug.

@leonerd
Copy link
Contributor Author

leonerd commented Jun 27, 2020

PR #17904 fixes this.

karenetheridge pushed a commit to karenetheridge/B-Hooks-EndOfScope that referenced this issue Oct 10, 2021
Does not fail for me locally, but pushing the written code just in case
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant