[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Segfault in Perl bindings when commit touches a large number of files

From: Roderich Schupp <roderich.schupp_at_gmail.com>
Date: Sat, 6 Jun 2015 17:09:02 +0200

On Wed, Jun 3, 2015 at 5:54 PM, Roderich Schupp <roderich.schupp_at_gmail.com>
wrote:

> On Wed, May 27, 2015 at 7:56 PM, Roderich Schupp <
> roderich.schupp_at_gmail.com> wrote:
>
>> I've dug a little deeper and think I've found a serious flaw in how the
>> Perl bindings handle
>> the Perl arguments and return values stack.
>>
>
> I've committed a series of patches (r1683261:1683271) to address this
> problem:
>

However... This fixes only the obvious cause why the local Perl call stack
of a Swig generated
wrapper may get out of sync with the global Perl stack: calling a helper
function that
(transitively) calls back into Perl.
But things may get more complicated. The wrapped Subversion function itself
may call
a callback function that is actually a Perl sub (via some thunkery).
For real life examples, just run some tests in
subversion/binding/swig/perl/native under GDB.
Since "calling back into Perl" always happens by calling
svn_swig_pl_callback_thunk,
you can simply set a breakpoint there, look upwards in the C call stack
for a function named _wrap_svn_* , then check the function immediately
below it:

This is from running "perl -Mblib t/1repost.t":

Breakpoint 1, svn_swig_pl_callback_thunk (
    caller_func=caller_func_at_entry=CALL_SV, func=func_at_entry=0x846bd0,
    result=result_at_entry=0x0, fmt=fmt_at_entry=0x7ffff4704f33 "srS")
    at subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c:528
528 {
(gdb) where
#0 svn_swig_pl_callback_thunk (caller_func=caller_func_at_entry=CALL_SV,
    func=func_at_entry=0x846bd0, result=result_at_entry=0x0,
    fmt=fmt_at_entry=0x7ffff4704f33 "srS")
    at subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c:528
#1 0x00007ffff4702c99 in svn_swig_pl_thunk_history_func (
    baton=baton_at_entry=0x846bd0, path=0x7ffff7ef1100 "/tags/foo/filea",
    revision=2, pool=pool_at_entry=0x7ffff7ef1028)
    at subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c:1093
#2 0x00007ffff511935a in svn_repos_history2 (fs=fs_at_entry=0x7ffff7ff0428,
    path=path_at_entry=0xd5d6b0 "tags/foo/filea",
    history_func=0x7ffff4702c30 <svn_swig_pl_thunk_history_func>,
    history_baton=history_baton_at_entry=0x846bd0,
    authz_read_func=authz_read_func_at_entry=0x0,
    authz_read_baton=authz_read_baton_at_entry=0x0, start=0, end=<optimized
out>,
    cross_copies=1, pool=0x7ffff7fef028)
    at subversion/libsvn_repos/rev_hunt.c:275
#3 0x00007ffff51044bc in svn_repos_history (fs=fs_at_entry=0x7ffff7ff0428,
<======
    path=path_at_entry=0xd5d6b0 "tags/foo/filea", history_func=<optimized
out>,
    history_baton=history_baton_at_entry=0x846bd0, start=start_at_entry=0,
    end=end_at_entry=2, cross_copies=1, pool=0x7ffff7fef028)
    at subversion/libsvn_repos/deprecated.c:585
#4 0x00007ffff03bdb6e in _wrap_svn_repos_history (my_perl=<optimized
out>,
    cv=<optimized out>) at svn_repos.c:8974
#5 0x00000000004bd3fa in Perl_pp_entersub (my_perl=0x7d1010) at
pp_hot.c:3270
#6 0x00000000004b6296 in Perl_runops_standard (my_perl=0x7d1010) at
run.c:41
#7 0x00000000004439b9 in S_run_body (oldscope=1, my_perl=0x7d1010)
    at perl.c:2448
#8 perl_run (my_perl=0x7d1010) at perl.c:2371
#9 0x000000000041cbdb in main (argc=3, argv=0x7fffffffe228,
    env=0x7fffffffe248) at perlmain.c:116

In the wrapper (_wrap_svn_repos_history) this is the line

{
      result = (svn_error_t *)svn_repos_history(arg1,(char const
*)arg2,arg3,arg4,arg5,arg6,arg7,arg8);
}

so this call should be bracketed (though I don't know how to tell Swig)

{
      PUTBACK;
      result = (svn_error_t *)svn_repos_history(arg1,(char const
*)arg2,arg3,arg4,arg5,arg6,arg7,arg8);
      SPAGAIN;
}

Here's another one from running "perl -Mblib t/7editor.t":

Breakpoint 1, svn_swig_pl_callback_thunk (
    caller_func=caller_func_at_entry=CALL_SV, func=0xf0a618,
    result=result_at_entry=0x0, fmt=fmt_at_entry=0x7ffff491e064 "rss")
    at subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c:528
528 {
(gdb) where
#0 svn_swig_pl_callback_thunk (caller_func=caller_func_at_entry=CALL_SV,
    func=0xf0a618, result=result_at_entry=0x0, fmt=fmt_at_entry=0x7ffff491e064
"rss")
    at subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c:528
#1 0x00007ffff491be2e in svn_swig_pl_thunk_commit_callback (
    new_revision=<optimized out>, date=<optimized out>,
    author=<optimized out>, baton=<optimized out>)
    at subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c:1132
#2 0x00007ffff53195f3 in invoke_commit_cb (
    commit_cb=0x7ffff4b69490 <commit_wrapper_callback>,
    commit_baton=0x7ffff7fcc1b0, fs=0x7ffff7ff0428, revision=1,
    post_commit_errstr=post_commit_errstr_at_entry=0x0,
    scratch_pool=scratch_pool_at_entry=0x7ffff7fef028)
    at subversion/libsvn_repos/commit.c:232
#3 0x00007ffff531a57d in close_edit (edit_baton=0x7ffff7fe70a0,
    pool=0x7ffff7fef028) at subversion/libsvn_repos/commit.c:875
#4 0x00007ffff013b7db in svn_delta_editor_invoke_close_edit ( <======
    _obj=0x7ffff7fcc3a0, scratch_pool=0x7ffff7fef028,
    edit_baton=<optimized out>) at svn_delta.c:2046
#5 _wrap_svn_delta_editor_invoke_close_edit (my_perl=<optimized out>,
    cv=<optimized out>) at svn_delta.c:7253
#6 0x00000000004bd3fa in Perl_pp_entersub (my_perl=0x7d1010) at
pp_hot.c:3270
#7 0x00000000004b6296 in Perl_runops_standard (my_perl=0x7d1010) at
run.c:41
#8 0x00000000004439b9 in S_run_body (oldscope=1, my_perl=0x7d1010)
    at perl.c:2448
#9 perl_run (my_perl=0x7d1010) at perl.c:2371
#10 0x000000000041cbdb in main (argc=3, argv=0x7fffffffe228,
    env=0x7fffffffe248) at perlmain.c:116

Cheers, Roderich
Received on 2015-06-06 17:09:14 CEST

This is an archived mail posted to the Subversion Dev mailing list.