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.
Very basinc SWIG interface file
Logged In: YES
user_id=1785307
Originator: YES
File Added: input.i
Logged In: YES
user_id=14972
Originator: NO
You appear to have attached the .i file twice. Can you attach the header?
Logged In: YES
user_id=1785307
Originator: YES
Oops, my bad.
File Added: input.h
C++ header file refereced by the SWIG interface file
Reduced testcase
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
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.
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.
Patch file preventing segfault
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
Patch for php4.cxx including bug #1700788
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
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?
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.
Logged In: YES
user_id=14972
Originator: NO
Thanks for analysis and patch - now committed to SVN.