Menu

#825 Segfault on method overloading for PHP5

closed-fixed
php (58)
5
2007-05-26
2007-05-04
No

I have some C++ code which SWIG can handle perfectly with PHP4, but trying to compile it with PHP5 causes segmentation faults (SWIG segfaulting). I have been able to isolate what seems to cause the problem: some problem handling overloaded functions. I created a very basic testcase to help (see attachements).

The following command will result in a segfault:
swig -c++ -php5 -outdir ./out/ -o ./out/output.cpp input.i

The following 2 commands will compile without a problem:
swig -c++ -php5 -noproxy -outdir ./out/ -o ./out/output.cpp input.i
swig -c++ -php -outdir ./out/ -o ./out/output.cpp input.i

I tried the latest source from SubVersion and even tried the patch for ReqID #1700788 (which had a similar faulty behavior), but it solved nothing. I might be doing something wrong, but since it works fine with PHP4, I guess not.

Discussion

  • Simon Berthiaume

    Very basinc SWIG interface file

     
  • Simon Berthiaume

    Logged In: YES
    user_id=1785307
    Originator: YES

    File Added: input.i

     
  • Olly Betts

    Olly Betts - 2007-05-04

    Logged In: YES
    user_id=14972
    Originator: NO

    You appear to have attached the .i file twice. Can you attach the header?

     
  • Simon Berthiaume

    Logged In: YES
    user_id=1785307
    Originator: YES

    Oops, my bad.
    File Added: input.h

     
  • Simon Berthiaume

    C++ header file refereced by the SWIG interface file

     
  • Olly Betts

    Olly Betts - 2007-05-04
    • assigned_to: kruland --> olly
     
  • Olly Betts

    Olly Betts - 2007-05-04

    Reduced testcase

     
  • Olly Betts

    Olly Betts - 2007-05-04

    Logged In: YES
    user_id=14972
    Originator: NO

    I can reproduce this. It does look like it's related to bug#1700788.

    I reduced the testcase a little - attached mostly so I don't lose it.

    Kevin: I'll investigate, but I'm busy with other work right now so it'll probably be a week or so. If you have more time feel free to take over this and bug#1700788 too.
    File Added: bug1712717.i

     
  • Simon Berthiaume

    Logged In: YES
    user_id=1785307
    Originator: YES

    Any updates on the matter? Is there a fix planed in the next few weeks?

    No pressure intended, I'm just curious to know, thanks.

     
  • Olly Betts

    Olly Betts - 2007-05-14

    Logged In: YES
    user_id=14972
    Originator: NO

    I've not had a chance to look at this further yet. I'm rather busy at present, so I can't make any promise as to when I will have time. It won't be this week at any rate.

    Sorry if it's a more urgent issue for you. If you want to take a look yourself and come up with a patch, or just analyse it further, that would help get this fixed sooner. My guess is it might be to do with having two functions with different return types but the same name, but that could just be completely wrong.

     
  • Simon Berthiaume

    Patch file preventing segfault

     
  • Simon Berthiaume

    Logged In: YES
    user_id=1785307
    Originator: YES

    I was able to find the point where the application was crashing and fix the null pointer deferencing causing the segfault. Now I can compile my things without SWIG crashing. Unfortunately the code generated isn't valid.

    For the overloaded functions:
    void Content( MyData *i_content);
    MyData* Content( ) const;
    The following gets generated (notice the missing class names after the "new"):
    function Content($i_content=null) {
    switch (func_num_args()) {
    case 0: $r=Document_Content($this->_cPtr); break;
    default: $r=Document_Content($this->_cPtr,$i_content);
    }
    if (!is_resource($r)) return $r;
    switch (get_resource_type($r)) {
    case "_p_MyData": return new ($r);
    default: return new ($r);
    }
    }
    Using the patch for bug #1700788 get half of the problem fixed and I get this (first "new" is now OK):
    function Content($i_content=null) {
    switch (func_num_args()) {
    case 0: $r=Document_Content($this->_cPtr); break;
    default: $r=Document_Content($this->_cPtr,$i_content);
    }
    if (!is_resource($r)) return $r;
    switch (get_resource_type($r)) {
    case "_p_MyData": return new MyData($r);
    default: return new ($r);
    }
    }

    I will keep working on this and hope to find a solution soon.
    File Added: php5-override-segfault.patch

     
  • Simon Berthiaume

    Patch for php4.cxx including bug #1700788

     
  • Simon Berthiaume

    Logged In: YES
    user_id=1785307
    Originator: YES

    I think I got it to work properly (and I hope the solution is valid since I have close to no PHP knowledge). It now generates the following (notice the last "default:" now returns "$r" instead of "new ($r)":
    function Content($i_content=null) {
    switch (func_num_args()) {
    case 0: $r=Document_Content($this->_cPtr); break;
    default: $r=Document_Content($this->_cPtr,$i_content);
    }
    if (!is_resource($r)) return $r;
    switch (get_resource_type($r)) {
    case "_p_MyData": return new MyData($r);
    default: return $r;
    }
    }
    BTW, the patch for php4.cxx also includes the bug #1700788 patch (since it is required to work properly).

    Can anyone try an comment the solution since I suck at PHP?

    File Added: php5-override.patch

     
  • Olly Betts

    Olly Betts - 2007-05-15

    Logged In: YES
    user_id=14972
    Originator: NO

    Thanks for looking into this.

    One version of the function returns `void' in C++, so indeed there's no class to be wrapped around $r in that case.

    So your generated code could well be suitable, though it's at least a little odd to be handling return values from functions returning void! And you could be generating good code for bad reasons (i.e. the patch is wrong but works in this case), but I had a quick look at it and it looks very plausible.

    Does the code generated with this patch actually work? Have you tried calling both versions of the function?

     
  • Simon Berthiaume

    Logged In: YES
    user_id=1785307
    Originator: YES

    I copied the return behavior from another getter/setter overridden method that was similar:
    class myClass
    {
    void Name( char* Name );
    char* Name( ) const;
    }
    Generating PHP code:
    class myClass
    {
    function Name($Name=null) {
    switch (func_num_args()) {
    case 0: $r=Document_Name($this->_cPtr); break;
    default: $r=Document_Name($this->_cPtr,$Name);
    }
    return $r;
    }
    }

    So it seems even "void" methods can return in PHP.

    I tested my patched copy and it worked just fine with my old scripts under PHP5. I dind't do an in-depth test, but it passed the few test cases I had.

     
  • Olly Betts

    Olly Betts - 2007-05-26
    • status: open --> closed-fixed
     
  • Olly Betts

    Olly Betts - 2007-05-26

    Logged In: YES
    user_id=14972
    Originator: NO

    Thanks for analysis and patch - now committed to SVN.

     

Log in to post a comment.