Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for PHP 7 #571

Closed
kevinlekiller opened this issue Dec 9, 2015 · 26 comments
Closed

Support for PHP 7 #571

kevinlekiller opened this issue Dec 9, 2015 · 26 comments
Labels

Comments

@kevinlekiller
Copy link

The extension API has changed in PHP 7, here's some information on it: https://wiki.php.net/phpng-upgrading

@J5lx
Copy link

J5lx commented Dec 9, 2015

I'd like to have PHP7 support, too 👍

@ojwb
Copy link
Member

ojwb commented Dec 9, 2015

I've done most of the PHP backend work recently, but this is not something I'm likely to have time to work on in the near future. I can probably make time to review a patch.

No more "me too" comments please - they just waste my time, which if anything makes it less likely I'll find time to work on this.

@nacc
Copy link

nacc commented Jan 15, 2016

Rather than a "me too", I'd like to volunteer to help out -- do you have any guidance on where to start to help with the PHP7.0 support? I'll take a look at the code and see if I can spin up some kind of patch (but I'm new to SWIG, so please be patient :)

@ojwb
Copy link
Member

ojwb commented Jan 15, 2016

There are essentially two approaches to this. Some background is probably needed for context.

The current PHP backend uses PHP's C API to wraps C++ class methods as "flat" functions which take the object as the first parameter. And it also generates a PHP file which defines PHP classes with methods which call those flat functions.

This works OK, but there's a lot of unnecessary indirection going on in PHP, so it won't win prizes for speed. How much of an issue that is depends on the API - if you're only making a few method calls and each does a lot of work, the overhead per call is not a big deal, but if there are huge numbers of method calls which return fairly quickly, you incur a lot of overhead. We've also had bugs due to the generated C++ and PHP layers not matching properly.

For PHP4, we created PHP objects directly using PHP's C API. This changed for PHP5 because the old API was no longer present - it turns out there was a new one, but it wasn't documented anywhere back then, so we didn't know about it. It is now documented, but nobody's taken the time to reimplement to use it - it was offered as a GSoC project, but nobody picked it:

https://github.com/swig/swig/wiki/GSoC-2013-ideas#Rework_PHP_backend_to_create_objects_using_the_Zend_API

For PHP7, we could either stick with the PHP5 approach - i.e. reimplement the flat file wrapping to use the PHP7 C API, and then adjust the PHP class wrapper generation for any relevant changes to the PHP language (not sure how much it's changed - I've not really had a chance to look at PHP7 yet).

Or we could go back to the PHP4 approach, and create the classes using the PHP7 C API, and then we can scrap the PHP class wrapper generation code entirely.

The second approach probably gives a better result. I'm not sure which would actually end up being more work - the current code is quite complicated to follow because it's generated two levels of wrappers in different languages, so not having to get to grips with it might balance having to actually implement more code using the PHP7 API.

SWIG has a fairly extensive testsuite, which would help here. I found when implementing the PHP5 support that a good approach was to take a copy of the current output for an testcase which didn't work, adjusting it by hand so it did work, and then getting SWIG to generate what I'd done by hand. Simply repeat until the testsuite all passes...

I'm not sure how different the PHP5 and PHP7 backend code in SWIG would end up being. If they will have a lot in common, then just patching the current backend makes sense. If they'll differ a lot (which is probably likely if we scrap the PHP class wrappers), having a separate PHP7 backend might make sense - we do after all know how long PHP5 will be around for - 1 year of Active Support (ending Dec 31, 2016), plus 2 years of Security Support (ending Dec 31, 2018) according to https://wiki.php.net/rfc/php56timeline

@nacc
Copy link

nacc commented Jan 18, 2016

Perfect! Thanks for the help! I'm not guaranteeing anything, but I'll take a stab at it. As the "maintainer", do you have a preference between the two approaches? It seems like the latter (the PHP4 approach) might be easier to maintain long-term (and eventually for supporting PHP?).

@ojwb
Copy link
Member

ojwb commented Jan 18, 2016

I think the second approach is probably where we eventually want to be (it's what we'd have done for PHP5 support had we known how to), but I wouldn't refuse a patch for PHP7 support just because it took the first approach.

@oerdnj
Copy link

oerdnj commented Jan 19, 2016

DISCLAIMER: The stuff I am writing is general as I even haven't seen swig and swig generated sources for PHP.

@nacc thank you for taking care of this

From what I have seen in native PECL extensions, the major change is zval** -> zval* and change in the string headers.

So in fact it might make sense to change the PHP5 model to generate code like this (taken from xdebug as an example):

#if PHP_VERSION_ID >= 70000
                                        if (sess_name && Z_TYPE(PG(http_globals)[TRACK_VARS_COOKIE]) == IS_ARRAY &&
                                                ((data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE]), sess_name, strlen(sess_name))) != NULL) &&
                                                Z_STRLEN_P(data) < 100 /* Prevent any unrealistically long data being set as filename */
                                        ) {
                                                strval = estrdup(Z_STRVAL_P(data));
#else
                                        if (sess_name && PG(http_globals)[TRACK_VARS_COOKIE] &&
                                                zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]), sess_name, strlen(sess_name) + 1, (void **) &data) == SUCCESS &&
                                                Z_STRLEN_PP(data) < 100 /* Prevent any unrealistically long data being set as filename */
                                        ) {
                                                strval = estrdup(Z_STRVAL_PP(data));
#endif

Also look at the https://github.com/mongodb/mongo-php-driver/blob/master/phongo_compat.h#L150

#if PHP_VERSION_ID >= 70000
# define phongo_char zend_string
# define phongo_char_pdup(str) pestrdup(filename->val, 1)
# define phongo_char_free(str) zend_string_release(str)
# define phongo_str(str) str->val
# define phongo_create_object_retval zend_object*
# define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t *)ecalloc(1, sizeof(_obj_t)+zend_object_properties_size(_class_type))
# define PHONGO_TSRMLS_FETCH_FROM_CTX(user_data)
# define SUPPRESS_UNUSED_WARNING(x)
# define DECLARE_RETURN_VALUE_USED int return_value_used = 1;
# define EXCEPTION_P(_ex, _zp) ZVAL_OBJ(&_zp, _ex)
# define PHONGO_STREAM_ID(stream) stream->res ? stream->res->handle : -1
# define ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRL(_key), _value);
# define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRL(_key), _value, _len);
# define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRL(_key), _value);
# define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len, _value, _value_len);
# define ADD_ASSOC_ZVAL_EX(_zv, _key, _value) add_assoc_zval_ex(_zv, ZEND_STRL(_key), _value);
# define ADD_ASSOC_ZVAL(_zv, _key, _value) add_assoc_zval(_zv, _key, _value);
# define ADD_ASSOC_NULL_EX(_zv, _key) add_assoc_null_ex(_zv, ZEND_STRL(_key));
# define ADD_ASSOC_BOOL_EX(_zv, _key, _value) add_assoc_bool_ex(_zv, ZEND_STRL(_key), _value);
# define ADD_INDEX_STRINGL(_zv, _ind, _value, _len) add_index_stringl(_zv, _ind, _value, _len);
# define phongo_free_object_arg zend_object
# define phongo_zpp_char_len size_t
# define ZEND_HASH_APPLY_COUNT(ht) (ht)->u.v.nApplyCount
# define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen)
# define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen)
# define PHONGO_RETURN_STRING(s) RETURN_STRING(s)
#else
# define phongo_char char
# define phongo_char_pdup(str) pestrdup(filename, 1)
# define phongo_char_free(str) _efree(str ZEND_FILE_LINE_CC ZEND_FILE_LINE_CC)
# define phongo_str(str) str
# define phongo_create_object_retval zend_object_value
# define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t *)ecalloc(1, sizeof(_obj_t))
# define PHONGO_TSRMLS_FETCH_FROM_CTX(user_data) TSRMLS_FETCH_FROM_CTX(user_data)
# define SUPPRESS_UNUSED_WARNING(x) (void)x;
# define DECLARE_RETURN_VALUE_USED
# define EXCEPTION_P(_ex, _zp) _zp = _ex
# define PHONGO_STREAM_ID(stream) stream->rsrc_id
# define ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRS(_key), _value, 1);
# define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRS(_key), _value, _len, 1);
# define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len+1, _value, _value_len, 1);
# define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRS(_key), _value);
# define ADD_ASSOC_ZVAL_EX(_zv, _key, _value) add_assoc_zval_ex(_zv, ZEND_STRS(_key), _value);
# define ADD_ASSOC_ZVAL(_zv, _key, _value) add_assoc_zval(_zv, _key, _value);
# define ADD_ASSOC_NULL_EX(_zv, _key) add_assoc_null_ex(_zv, ZEND_STRS(_key));
# define ADD_ASSOC_BOOL_EX(_zv, _key, _value) add_assoc_bool_ex(_zv, ZEND_STRS(_key), _value);
# define ADD_INDEX_STRINGL(_zv, _ind, _value, _len) add_index_stringl(_zv, _ind, _value, _len, 0);
# define Z_PHPDATE_P(object) zend_object_store_get_object(object TSRMLS_CC)
# define Z_ISUNDEF(x) !x
# define phongo_free_object_arg void
# define phongo_zpp_char_len int
# define ZEND_HASH_APPLY_COUNT(ht) (ht)->nApplyCount
# define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen, 1)
# define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen, 1)
# define PHONGO_RETURN_STRING(s) RETURN_STRING(s, 1)
# define PHP_STREAM_CONTEXT(stream) ((php_stream_context*) (stream)->context)
#endif

This with zval handling changes might provide the thin compatibility layer you are looking for.

The thinnest layer I've seen so far is in php-uuid (but that doesn't need much):

#if PHP_MAJOR_VERSION < 7
typedef long zend_long;
typedef int  strsize;
#define UUID_RETSTR(a)    RETURN_STRING(a,1)
#define UUID_RETSTRL(a,l) RETURN_STRINGL(a,l,1)
#else
typedef size_t strsize;
#define UUID_RETSTR(a)    RETURN_STRING(a)
#define UUID_RETSTRL(a,l) RETURN_STRINGL(a,l)
#endif

The full rewrite to PHP4 API style would be great, but it might be bigger task than the small changes you need right now.

@denisdemais
Copy link

maybe to avoid confussions

swig -php7 ...
swig -php ...

@ojwb
Copy link
Member

ojwb commented Jan 27, 2016

From what @oerdnj says, it sounds like the same generated wrapper file could just work with PHP5 and PHP7 - if so, there would be no point having a new version-specific command-line option.

@oerdnj
Copy link

oerdnj commented Apr 19, 2016

There's now https://github.com/flaupretre/pecl-compat that could be used to wrap most of the functions. That might help fixing the bug.

@ojwb
Copy link
Member

ojwb commented Jul 28, 2016

@nacc Did you manage to make any progress on this?

@nacc
Copy link

nacc commented Jul 29, 2016

@ojwb sadly not a ton of progress. I was pulled onto some other things. Let me try and work on this again on my flight back from a work trip and see what I can get you next week.

@hdezela
Copy link

hdezela commented Aug 3, 2016

graphviz issue 2584

Another reference to keep in mind when this is updated

@ojwb
Copy link
Member

ojwb commented Aug 15, 2016

@nacc Did you get anywhere?

I'll probably have some time to work on this, but I don't want to waste any useful work others might have already done. So it's totally fine if you didn't - I really just want to know.

@nacc
Copy link

nacc commented Aug 15, 2016

On Aug 14, 2016 21:02, "Olly Betts" notifications@github.com wrote:

@nacc Did you get anywhere?

I'll probably have some time to work on this, but I don't want to waste
any useful work others might have already done. So it's totally fine if you
didn't - I really just want to know.

Sadly no, my work priorities have shifted. Sorry for not communicating that
sooner!

@ojwb
Copy link
Member

ojwb commented Nov 25, 2016

https://github.com/ojwb/swig/tree/php7 now has an initial version of PHP7 support which at least passes SWIG's testsuite. At this stage I really wouldn't advise using this in production or distributing packages based on this code, but I'd encourage people to try it out and report any issues.

On the branch, the PHP7 support currently entirely replaces the PHP5 support, but the next step is to address that.

Having looked at the pecl-compat stuff (or similar approaches adding compatibility stuff by hand) I concluded that wasn't the right approach here. Trying to refactor the PHP5 support to use compatibility functions is just asking to introduce bugs, whereas if we just leave it be it can die in not much over a year once PHP5 reaches end of life. It seems better to just create a new PHP7 backend (based on the PHP5 one) which can use the PHP7 C API directly. We may have to fix bugs in two places, but only for just over a year, and the rate of bug fixes in SWIG's PHP backend isn't high enough that this is a big issue. With a merged backend we'd need to test fixes against both PHP versions anyway.

@wsfulton
Copy link
Member

Sounds good. How will the two co-exist? Will PHP7 be invoked by a command -php7 and -php will always be PHP5? How about -php (PHP5) and -php7 for swig-3.1 and -php switches to mean -php7 in swig-3.2 when PHP5 support could be dropped. Or maybe just drop PHP5 support in swig-3.1 altogether and -php means php7 in swig-3.1.

@ojwb
Copy link
Member

ojwb commented Nov 26, 2016

I'd not really thought about that part yet, but I guess -php7 is probably the way to go (and there's actually already a -php5 option which aliases -php, which has been around since we had PHP4 and PHP5 support).

Do we have even a rough estimate of a date for SWIG 3.1 to become a stable release? I think I'd prefer not to drop PHP5 support until it reaches EOL upstream (and it's useful to at least me to be able to generate bindings for both PHP5 and PHP7 from a single SWIG build).

@ojwb
Copy link
Member

ojwb commented Nov 28, 2016

It seems there's something wrong in the director code, but I'm failing to work out exactly what so far.

But if run under valgrind (using make check-php-test-suite RUNTOOL=valgrind), two testcases throw up issues:

director_basic

checking php testcase director_basic (with run test)
==17921== Memcheck, a memory error detector
==17921== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17921== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==17921== Command: php7.0 -n -q -d extension_dir=. -d safe_mode=Off ./director_basic_runme.php
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F6F3: zend_hash_find_bucket (zend_hash.c:493)
==17921==    by 0x37F6F3: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A5954: zend_std_read_property (zend_object_handlers.c:537)
==17921==    by 0x3D87E6: ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31564)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F704: zend_hash_find_bucket (zend_hash.c:496)
==17921==    by 0x37F704: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A5954: zend_std_read_property (zend_object_handlers.c:537)
==17921==    by 0x3D87E6: ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31564)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F754: zend_hash_find_bucket (zend_hash.c:498)
==17921==    by 0x37F754: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A5954: zend_std_read_property (zend_object_handlers.c:537)
==17921==    by 0x3D87E6: ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31564)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F779: zend_hash_find_bucket (zend_hash.c:504)
==17921==    by 0x37F779: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A5954: zend_std_read_property (zend_object_handlers.c:537)
==17921==    by 0x3D87E6: ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31564)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Conditional jump or move depends on uninitialised value(s)
==17921==    at 0x3A6761: zend_std_write_property (zend_object_handlers.c:649)
==17921==    by 0x3CDFA3: zend_assign_to_object (zend_execute.c:1226)
==17921==    by 0x3CDFA3: ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31849)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921==    by 0x3F0F5F: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F6F3: zend_hash_find_bucket (zend_hash.c:493)
==17921==    by 0x37F6F3: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A676F: zend_std_write_property (zend_object_handlers.c:655)
==17921==    by 0x3CDFA3: zend_assign_to_object (zend_execute.c:1226)
==17921==    by 0x3CDFA3: ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31849)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F704: zend_hash_find_bucket (zend_hash.c:496)
==17921==    by 0x37F704: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A676F: zend_std_write_property (zend_object_handlers.c:655)
==17921==    by 0x3CDFA3: zend_assign_to_object (zend_execute.c:1226)
==17921==    by 0x3CDFA3: ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31849)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F754: zend_hash_find_bucket (zend_hash.c:498)
==17921==    by 0x37F754: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A676F: zend_std_write_property (zend_object_handlers.c:655)
==17921==    by 0x3CDFA3: zend_assign_to_object (zend_execute.c:1226)
==17921==    by 0x3CDFA3: ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31849)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F779: zend_hash_find_bucket (zend_hash.c:504)
==17921==    by 0x37F779: zend_hash_find (zend_hash.c:1983)
==17921==    by 0x3A676F: zend_std_write_property (zend_object_handlers.c:655)
==17921==    by 0x3CDFA3: zend_assign_to_object (zend_execute.c:1226)
==17921==    by 0x3CDFA3: ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER (zend_vm_execute.h:31849)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x35D26E: zend_call_function (zend_execute_API.c:856)
==17921==    by 0x35D5A8: call_user_function_ex (zend_execute_API.c:675)
==17921==    by 0x35D5DC: call_user_function (zend_execute_API.c:657)
==17921==    by 0x9C096B6: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F942: zend_hash_str_find_bucket (zend_hash.c:517)
==17921==    by 0x37F942: zend_hash_str_find (zend_hash.c:1995)
==17921==    by 0x9C0852C: SWIG_ConvertPtr(_zval_struct*, void**, swig_type_info*, int) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C096E5: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921==    by 0x3F0F5F: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x3F109C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:800)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F96A: zend_hash_str_find_bucket (zend_hash.c:521)
==17921==    by 0x37F96A: zend_hash_str_find (zend_hash.c:1995)
==17921==    by 0x9C0852C: SWIG_ConvertPtr(_zval_struct*, void**, swig_type_info*, int) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C096E5: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921==    by 0x3F0F5F: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x3F109C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:800)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x37F971: zend_hash_str_find_bucket (zend_hash.c:522)
==17921==    by 0x37F971: zend_hash_str_find (zend_hash.c:1995)
==17921==    by 0x9C0852C: SWIG_ConvertPtr(_zval_struct*, void**, swig_type_info*, int) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C096E5: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921==    by 0x3F0F5F: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x3F109C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:800)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921== 
==17921== Conditional jump or move depends on uninitialised value(s)
==17921==    at 0x9C08538: SWIG_ConvertPtr(_zval_struct*, void**, swig_type_info*, int) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C096E5: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921==    by 0x3F0F5F: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x3F109C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:800)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x400456: zend_execute (zend_vm_execute.h:458)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x9C0854A: SWIG_ConvertPtr(_zval_struct*, void**, swig_type_info*, int) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C096E5: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921==    by 0x3F0F5F: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x3F109C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:800)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x400456: zend_execute (zend_vm_execute.h:458)
==17921== 
==17921== Use of uninitialised value of size 8
==17921==    at 0x9C0855B: SWIG_ConvertPtr(_zval_struct*, void**, swig_type_info*, int) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C096E5: SwigDirector_MyClass::vmethod(Bar) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0E032: MyClass::cmethod(Bar const&) (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x9C0CBCE: _wrap_MyClass_cmethod (in /home/olly/git/swig/Examples/test-suite/php/director_basic.so)
==17921==    by 0x35B6F9: dtrace_execute_internal (zend_dtrace.c:107)
==17921==    by 0x3F0F5F: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x3F109C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:800)
==17921==    by 0x3AC1BA: execute_ex (zend_vm_execute.h:414)
==17921==    by 0x35B697: dtrace_execute_ex (zend_dtrace.c:83)
==17921==    by 0x400456: zend_execute (zend_vm_execute.h:458)
==17921== 
==17921== Invalid read of size 1
==17921==    at 0x3A3340: zend_object_std_dtor (zend_objects.c:59)
==17921==    by 0x3A81AF: zend_objects_store_free_object_storage (zend_objects_API.c:99)
==17921==    by 0x35C162: shutdown_executor (zend_execute_API.c:357)
==17921==    by 0x36B4BA: zend_deactivate (zend.c:967)
==17921==    by 0x30A0D5: php_request_shutdown (main.c:1833)
==17921==    by 0x40149F: do_cli (php_cli.c:1141)
==17921==    by 0x1ED15D: main (php_cli.c:1344)
==17921==  Address 0xffeffc125 is on thread 1's stack
==17921==  5403 bytes below stack pointer
==17921== 
==17921== Invalid read of size 4
==17921==    at 0x3A3346: zend_object_std_dtor (zend_objects.c:60)
==17921==    by 0x3A81AF: zend_objects_store_free_object_storage (zend_objects_API.c:99)
==17921==    by 0x35C162: shutdown_executor (zend_execute_API.c:357)
==17921==    by 0x36B4BA: zend_deactivate (zend.c:967)
==17921==    by 0x30A0D5: php_request_shutdown (main.c:1833)
==17921==    by 0x40149F: do_cli (php_cli.c:1141)
==17921==    by 0x1ED15D: main (php_cli.c:1344)
==17921==  Address 0xffeffc120 is on thread 1's stack
==17921==  5408 bytes below stack pointer
==17921== 
==17921== Invalid write of size 4
==17921==    at 0x3A334D: zend_object_std_dtor (zend_objects.c:60)
==17921==    by 0x3A81AF: zend_objects_store_free_object_storage (zend_objects_API.c:99)
==17921==    by 0x35C162: shutdown_executor (zend_execute_API.c:357)
==17921==    by 0x36B4BA: zend_deactivate (zend.c:967)
==17921==    by 0x30A0D5: php_request_shutdown (main.c:1833)
==17921==    by 0x40149F: do_cli (php_cli.c:1141)
==17921==    by 0x1ED15D: main (php_cli.c:1344)
==17921==  Address 0xffeffc120 is on thread 1's stack
==17921==  5408 bytes below stack pointer
==17921== 
==17921== 
==17921== HEAP SUMMARY:
==17921==     in use at exit: 1,126 bytes in 21 blocks
==17921==   total heap usage: 12,158 allocs, 12,137 frees, 1,473,113 bytes allocated
==17921== 
==17921== LEAK SUMMARY:
==17921==    definitely lost: 0 bytes in 0 blocks
==17921==    indirectly lost: 0 bytes in 0 blocks
==17921==      possibly lost: 0 bytes in 0 blocks
==17921==    still reachable: 1,126 bytes in 21 blocks
==17921==         suppressed: 0 bytes in 0 blocks
==17921== Rerun with --leak-check=full to see details of leaked memory
==17921== 
==17921== For counts of detected and suppressed errors, rerun with: -v
==17921== Use --track-origins=yes to see where uninitialised values come from
==17921== ERROR SUMMARY: 18 errors from 18 contexts (suppressed: 0 from 0)

director_pass_by_value

checking php testcase director_pass_by_value (with run test)
==18174== Memcheck, a memory error detector
==18174== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18174== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==18174== Command: php7.0 -n -q -d extension_dir=. -d safe_mode=Off ./director_pass_by_value_runme.php
==18174== 
==18174== Invalid read of size 1
==18174==    at 0x3A3340: zend_object_std_dtor (zend_objects.c:59)
==18174==    by 0x3A81AF: zend_objects_store_free_object_storage (zend_objects_API.c:99)
==18174==    by 0x35C162: shutdown_executor (zend_execute_API.c:357)
==18174==    by 0x36B4BA: zend_deactivate (zend.c:967)
==18174==    by 0x30A0D5: php_request_shutdown (main.c:1833)
==18174==    by 0x40149F: do_cli (php_cli.c:1141)
==18174==    by 0x1ED15D: main (php_cli.c:1344)
==18174==  Address 0xffeffc115 is on thread 1's stack
==18174==  5387 bytes below stack pointer
==18174== 
==18174== Invalid read of size 4
==18174==    at 0x3A3346: zend_object_std_dtor (zend_objects.c:60)
==18174==    by 0x3A81AF: zend_objects_store_free_object_storage (zend_objects_API.c:99)
==18174==    by 0x35C162: shutdown_executor (zend_execute_API.c:357)
==18174==    by 0x36B4BA: zend_deactivate (zend.c:967)
==18174==    by 0x30A0D5: php_request_shutdown (main.c:1833)
==18174==    by 0x40149F: do_cli (php_cli.c:1141)
==18174==    by 0x1ED15D: main (php_cli.c:1344)
==18174==  Address 0xffeffc110 is on thread 1's stack
==18174==  5392 bytes below stack pointer
==18174== 
==18174== Invalid write of size 4
==18174==    at 0x3A334D: zend_object_std_dtor (zend_objects.c:60)
==18174==    by 0x3A81AF: zend_objects_store_free_object_storage (zend_objects_API.c:99)
==18174==    by 0x35C162: shutdown_executor (zend_execute_API.c:357)
==18174==    by 0x36B4BA: zend_deactivate (zend.c:967)
==18174==    by 0x30A0D5: php_request_shutdown (main.c:1833)
==18174==    by 0x40149F: do_cli (php_cli.c:1141)
==18174==    by 0x1ED15D: main (php_cli.c:1344)
==18174==  Address 0xffeffc110 is on thread 1's stack
==18174==  5392 bytes below stack pointer
==18174== 
==18174== 
==18174== HEAP SUMMARY:
==18174==     in use at exit: 1,126 bytes in 21 blocks
==18174==   total heap usage: 11,980 allocs, 11,959 frees, 1,429,250 bytes allocated
==18174== 
==18174== LEAK SUMMARY:
==18174==    definitely lost: 0 bytes in 0 blocks
==18174==    indirectly lost: 0 bytes in 0 blocks
==18174==      possibly lost: 0 bytes in 0 blocks
==18174==    still reachable: 1,126 bytes in 21 blocks
==18174==         suppressed: 0 bytes in 0 blocks
==18174== Rerun with --leak-check=full to see details of leaked memory
==18174== 
==18174== For counts of detected and suppressed errors, rerun with: -v
==18174== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

@ojwb
Copy link
Member

ojwb commented Nov 28, 2016

So I stopped poking it and soon realised where the issue likely was, and my hunch was right - the branch now passes the test suite under valgrind too. There are a few "definitely leaked" allocations, but from the small sample I checked those look to be in the testcases themselves.

@robert-scheck
Copy link

I think I'd prefer not to drop PHP5 support until it reaches EOL upstream (and it's useful to at least me to be able to generate bindings for both PHP5 and PHP7 from a single SWIG build).

May I kindly ask to keep PHP 5 support in SWIG longer than until EOL at its upstream? Linux distributions with long term support (such as RHEL/CentOS or SLES) still have to support PHP 5 for multiple years from now, while upstreams using SWIG in their build chains might prefer a recent SWIG release anyway…

@ojwb
Copy link
Member

ojwb commented Nov 29, 2016

May I kindly ask to keep PHP 5 support in SWIG longer than until EOL at its upstream?

It needs someone who is actually going to actively maintain that support, which isn't something I have any interest in beyond the upstream EOL. In fact my distro already dropped PHP5, so the only reason I can currently test PHP5 it is because I still have the packages installed from before they did, but those packages aren't getting security updates...

If the PHP5 support is just going to sit and bitrot, it's more honest to just remove it. Upstream EOL is a natural point to do that.

I'll note we also dropped PHP4 support at PHP4 EOL (2008-08-08, last SWIG release to support it was 1.3.36 on 2008-06-24) and I've not seen anyone complain about that decision at all.

@wsfulton
Copy link
Member

http://php.net/supported-versions.php shows PHP5 EOL is Jan 2019, so no doubt we can get maintained packages to test until this date from distros that will support it until EOL. We ought to have swig-3.1.x out by then, so swig-3.1.x would support both php5 and php7 until we release swig-3.2 which is probably going to be after 2019.

Regarding the leaks, if the tests can be easily fixed to not leak, please do so.

@oerdnj
Copy link

oerdnj commented Nov 29, 2016

The distributions that will carry PHP 5 over EOL will also carry swig with php5 support, so I wouldn't worry so much. With my Debian PHP hat on, I am perfectly fine with swig dropping php5 support at the same as php 5.6 EOL (end of 2018).

@ojwb
Copy link
Member

ojwb commented Nov 29, 2016

With my Debian PHP hat on, I am perfectly fine with swig dropping php5 support at the same as php 5.6 EOL (end of 2018)

From a Debian perspective, the correct question is not really whether we keep PHP5 support in new releases of SWIG, but rather whether there's PHP5 support in the version of SWIG which Debian has in the last stable release to have PHP5 packages.

@ojwb ojwb closed this as completed in 1169874 Nov 30, 2016
@ojwb
Copy link
Member

ojwb commented Nov 30, 2016

@wsfulton: I'm not sure how to enable the CI builds for this. It looks like they use Ubuntu trusty (at least mostly - not all seem to specify dist: trusty), and trusty doesn't have PHP7 packages, but there is a PPA: https://launchpad.net/~ondrej/+archive/ubuntu/php Or can we just specify xenial instead of trusty?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants