On 15 May 2015 at 08:56, Steve Hay <steve.m....@googlemail.com> wrote:
> On 15 May 2015 at 07:14, Jan Kaluža <jkal...@redhat.com> wrote:
>> On 05/14/2015 07:42 PM, Steve Hay wrote:
>>>
>>> On 14 May 2015 at 12:48, Jan Kaluža <jkal...@redhat.com> wrote:
>>>>
>>>> On 05/14/2015 11:24 AM, Niko Tyni wrote:
>>>>>
>>>>>
>>>>> On Sun, May 10, 2015 at 01:47:19PM +0100, Steve Hay wrote:
>>>>>>
>>>>>>
>>>>>> On 28 April 2015 at 07:51,  <jkal...@apache.org> wrote:
>>>>>>>
>>>>>>>
>>>>>>> Author: jkaluza
>>>>>>> Date: Tue Apr 28 06:51:12 2015
>>>>>>> New Revision: 1676417
>>>>>>>
>>>>>>> URL: http://svn.apache.org/r1676417
>>>>>>> Log:
>>>>>>> Initialize interp->refcnt to 1 in modperl_interp_select.
>>>>>
>>>>>
>>>>>
>>>>>> I cannot understand why, but since this patch was applied I find that
>>>>>> t\modules\proxy.t fails every time when I run the full "nmake test",
>>>>>> but it always succeeds when I run it in isolation so I'm at a loss to
>>>>>> find out what is going wrong. All other tests (apart from those known
>>>>>> Win32-specific failures documented in README) still pass. Reverting
>>>>>> the patch "fixes" the proxy.t problem, but probably isn't the right
>>>>>> solution.
>>>>
>>>>
>>>>
>>>> It's caused by Perl_croak/modperl_croak.
>>>>
>>>> Lets take modperl_run_filter as an example. When following code-path is
>>>> executed ...
>>>>
>>>>                  modperl_croak(aTHX_ MODPERL_FILTER_ERROR,
>>>>                                "a filter calling $f->read "
>>>>                                "must return OK and not DECLINED");
>>>>
>>>> ... the MP_INTERP_PUTBACK is not reached for some reason (I presume it's
>>>> because of Perl_croak, but I don't understand why it stops the execution
>>>> of
>>>> the rest of modperl_run_filter method).
>>>>
>>>> Because of that, the interp->refcnt is not decreased, and the interp is
>>>> not
>>>> freed.
>>>>
>>>> I has been able to "fix" it by attached patch, but I would like to
>>>> discuss
>>>> more generic way how to fix that problem...
>>>>
>>>> Any ideas?
>>>>
>>>
>>> modperl_croak() calls Perl_croak(), which is an XS interface to Perl's
>>> die() function, so surely you wouldn't expect anything immediately
>>> after it to be run?
>>>
>>> I'm not sure exactly where it does end up, though. It must be getting
>>> caught by some eval somewhere since we aren't exiting the process, but
>>> presumably it wouldn't be possible to do appropriate clean-up wherever
>>> it lands up unless there is some mechanism for registering required
>>> clean-up behaviour? Otherwise maybe we need to pass interp into
>>> modperl_croak(), or into a new version of that if not all cases
>>> require it, so that it can do the MP_INTERP_PUTBACK(interp, aTHX)
>>> call?
>>>
>>
>> What worries me here a bit is that we would have to MP_INTEPR_PUTBACK the
>> PerlInterp which is later used for PerlCroak, if I understand it right.
>>
>> I have found out that usually when modperl_croak is called, the refcnt of
>> the interp is above 1, so it wouldn't get freed prematurely, but still.
>>
>> I think for now we should putback the interp only when interp->refcnt > 1,
>> it wouldn't fully fix all bugs, but lot of them would be fixed by that.
>>
>> If someone knows how Perl_croak works and if it's possible to cleanup the
>> interp after that, it would be great to share that info .
>>
>
> My understanding of Perl_croak() is that it either exits the process
> (if not inside an eval()) or else calls the system's longjmp(), which
> resumes execution from immediately after where the corresponding
> setjmp() was called, having restored the process environment to the
> original state at that point too.
>
> In the perl source, the setjmp()/longjmp() of eval()/die() are done by
> the JMPENV_PUSH in Perl_eval_sv() (maybe called from Perl_eval_pv())
> and the JMPENV_JUMP in Perl_die_unwind(), called from Perl_vcroak().
> The JMPENV* macros are in cop.h, and call
> PerlProc_setjmp()/PerlProc_longjmp(), which are typically
> setjmp()/longjmp(), or maybe sigsetjmp()/siglongjmp() if you have
> them.
>
> I think you're right that we should probably check that interp->refcnt
>> 1 if we go ahead and pass interp into modperl_croak(). There aren't
> too many calls, so this may be workable; we also have a few call
> MP_RUN_CROAK()/MP_RUN_CROAK_RESET() calls to look at too. What worries
> me is the (much larger number of!) calls to Perl_croak(). They will
> also not return, so we presumably need to do cleanup before each one
> of those too? Maybe we need a little wrapper function/macro to do
> clean up and then call Perl_croak() and use that everywhere instead of
> Perl_croak() (including the call inside modperl_croak(), of course)?

The other approach I mentioned earlier was to try to do the cleanup in
the eval() where the die() has landed. If that's possible then it
might be a cleaner approach.

In this case, I think we're inside the eval_pv done in
modperl_filter_resolve_init_handler(). I only see three other eval*()s
(one more eval_pv() and two eval_sv()s) around the mod_perl C source
code so this could be worth pursuing.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@perl.apache.org
For additional commands, e-mail: dev-h...@perl.apache.org

Reply via email to