Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: XS Error: Segfault with B::HooksAtRuntime

by dave_the_m (Monsignor)
on Aug 06, 2022 at 15:08 UTC ( #11145981=note: print w/replies, xml ) Need Help??


in reply to XS Error: Segfault with B::HooksAtRuntime

Well the crash is happening at the point where the perl interpreter has just finished executing the body of a require'd file (the require occurring as part of a 'use'). The interpreter is popping the CXt_EVAL context frame off the context stack (which was pushed on when the require'd file was about to be compiled). One step of popping the context is to decrement the recount of a temporary SV pointed to from within the context struct (which happens to hold the name of the file being compiled - or possibly the package name; can't remember which). The pointer stored in the context struct is obviously corrupt - it looks like part of the context struct has been overwritten with the text "nstance", as has been pointed out.

What the cause of this is, I don't know. Given that you're doing weird stuff with delaying execution, my initial instinct was that the context stack pointer has been decremented and then some other code has pushed a new context frame on, overwriting the eval context - all before the interpreter has actually returned from doing the require, However in this case, I would expect a new context frame (even of a different type than CXt_EVAL) to be mainly full of pointers and the like - not full of literal text. So it looks like a deeper problem with a rouge string pointer somewhere.

Dave.

  • Comment on Re: XS Error: Segfault with B::HooksAtRuntime

Replies are listed 'Best First'.
Re^2: XS Error: Segfault with B::HooksAtRuntime
by haj (Priest) on Aug 06, 2022 at 16:15 UTC

    I can't solve the problem, but that info turned out to be sufficient for me to guess where to poke. I can reproduce a segfault in just 7 lines of code.

    File: mx_segfault.pl
    use lib '.'; use Demo;
    File: Demo.pm
    package Demo; use MooseX::Extended; require Stuff;
    File: Stuff.pm
    package Stuff; use MooseX::Extended;
    With this code, perl -wc mx_segfault.pl segfaults, and valgrind throws a 455-line tantrum.
      In general terms, that valgrind output shows that the calling of a sub while running code via call_after() (which requires a new CXt_SUB context sub to be pushed) grows the context stack (by reallocating it). Sometime later when exiting a use/require, the Cxt_EVAL frame is accessed using the old context stack address (the smaller stack that was freed when a larger one was allocated). So maybe something is holding on to a context stack pointer when it shouldn't - either in core or XS.

      Dave.

Re^2: XS Error: Segfault with B::HooksAtRuntime
by dave_the_m (Monsignor) on Aug 07, 2022 at 12:52 UTC
    I've now fully diagnosed the issue and have a small reproducible test case. The issue is the context stack being reallocated when deeply nests sub calls are made from after_runtime(), which is called from a destructor while exiting the eval scope from the require. That exiting code isn't expecting the context stack to be reallocated from under it. Normally when perl itself calls out to code from things like destructors, tied method calls etc, it uses a new temporary set of stacks (argument, context etc). after_runtime() needs to do something similar. This is achieved via the PUSHSTACKi() macro. Look at a distribution like Async-Interrupt for an example.

    Here's the reproducible code. The recursive sub is called enough times to trigger a context stack grow/realloc.

    ------------------------- test.pl: use lib '.'; use Foo; ------------------------- Foo.pm: package Foo; use Bar; 1; ------------------------- Bar.pm: package Bar; use B::Hooks::AtRuntime 'after_runtime'; sub recurse { my $depth = shift; return if $depth < 0; recurse($depth -1); } sub import { after_runtime { recurse(20); } }
    If this is run against a perl that has been built with -DDEBUGGING, you'll see the following assertion failure, which is Perl_cx_popeval() detecting that the current cx pointer has changed underneath it.
    perl: inline.h:2921: Perl_cx_popeval: Assertion `CxTYPE(cx) == CXt_EVA +L' failed.

    Dave.

        https://github.com/mauzo/B-Hooks-AtRuntime/issues/2

        Dave.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11145981]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2022-09-25 21:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (116 votes). Check out past polls.

    Notices?