Menu

#1125 [php] undefined symbol: zend_error_noreturn

closed
php (58)
5
2012-05-12
2011-01-27
No

swig 2.0.0 fails to produce proper code for PHP 5.3.3 it uses symbol zend_error_noreturn instead of zend_error

See also this stackoverflow question:
http://stackoverflow.com/questions/2556113/swig-generated-code-fails-to-run-on-php-5-3-2-undefined-symbol-zend-error-noretu

Discussion

  • Olly Betts

    Olly Betts - 2011-02-14

    The use of zend_error_noreturn() is intentional, and works for me on Debian squeeze, which has PHP 5.3.3 and GCC 4.4.5. Architecture is x86-64.

    What's the platform and GCC version where this fails for you?

     
  • Olly Betts

    Olly Betts - 2011-02-18
    • summary: undefined symbol: zend_error_noreturn --> [php] undefined symbol: zend_error_noreturn
     
  • Mike Leahy

    Mike Leahy - 2011-03-06

    I can confirm this issue when building the PHP modules for the GDAL project (http://gdal.org)

    I've done this on Ubuntu 10.10, as well an alpha version of Ubuntu 11.04.

    Manually replacing zend_error_noreturn with zend_error then recompiling the *_wrap.cpp module seems to work fine.

     
  • Mike Leahy

    Mike Leahy - 2011-03-06

    To answer olly's question regarding GCC, on Ubuntu 10.10 I have the following version:

    gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5

     
  • Olly Betts

    Olly Betts - 2011-03-07

    mgleahy: You didn't say what architecture you're using (uname -m).

    This appears to work fine for me on Ubuntu 10.10 x86_64.

    I tested with:

    cd Examples/test-suite/php
    make wrapmacro.cpptest

    That's a random testsuite example which generates calls zend_error_noreturn.

    If you're using SWIG 2.0.2, you can compile the generated wrapper code with -DSWIG_ZEND_ERROR_NORETURN=zend_error to work around this problem (you may get some extra compiler warnings, but it should build), but it would be useful to work out what's causing the difference (my hunch is a different architecture, since there are already some special cases in the PHP headers) so we can enable this workaround automatically, and get this bug fixed in PHP itself.

     
  • Mike Leahy

    Mike Leahy - 2011-03-07

    Both 10.10 and 11.04-alpha Ubuntu environments I tried this in are x86_64, but I'm using the distributions' swig packages...I haven't compiled my own.

    10.10 has swig 1.3.40, and the 11.04-alpha, the swig version is 2.0.1 - so I'll have to compiled 2.0.2 myself to use the feature you mentioned. But maybe this is something that can I could rais to the Ubuntu package maintainers when they update to 2.0.2.

     
  • Olly Betts

    Olly Betts - 2011-03-07

    Works fine with the Ubuntu package of SWIG too for me on Ubuntu 10.10 - I tested this with:

    cd Examples/test-suite/php
    make wrapmacro.cpptest SWIG=/usr/bin/swig

    And checking the output, the system swig is indeed being used:

    /usr/bin/swig -php -cppext cxx -c++ -outcurrentdir -I../../../Examples/test-suite ../../../Examples/test-suite/wrapmacro.i

    It seems our systems are pretty much the same, so this is very odd.

    Can you download the 2.0.2 source, unpack it, and try the above commands?

     
  • Mike Leahy

    Mike Leahy - 2011-03-07

    On Ubuntu 10.10, swig 1.3.40, x86_64:

    Downloaded and unpacked source, cd'd into the source directory, had to run ./configure first, then cd'd into Examples/test-suite/php, ran make wrapmacro.cpptest SWIG=/usr/bin/swig as you suggested.

    Looking in the resulting wrapmacro_wrap.cxx file, I find three occurrences of zend_error, and three occurrences of zend_error_noreturn (this is consistent with my experience compiling GDAL's modules, which produces some of both error methods).

     
  • Olly Betts

    Olly Betts - 2011-03-07

    But did the testcase pass (which requires it to successfully compile that wrapper)?

    I already know that calls to zend_error_noreturn() are generated. But they compile fine for me on all the platforms I've been able to test this on...

    There's some symbol aliasing trickery in the PHP header file, which is presumably causing some people problems for some reason. If we can work out what that reason is, we can (a) get PHP fixed and (b) probably enable a workaround for this issue for the cases is affects.

     
  • William Fulton

    William Fulton - 2011-03-07

    I suggest you both post the preprocessed output of the _wrap.cxx file from the same version of SWIG and the same inputs. I suggest the php 'class' example in swig-2.0.1. All you need to do is go into this directory and run:

    ~/swig/swig-2.0.1/Examples/php/class$ make CFLAGS=-E > preprocessed.cxx

    then attach preprocessed.cxx. The differences in the way the php header files are being processed can then probably be worked out by diff'inig the files. You'll need to download the swig source though and build swig. Or if you want do this with swig-1.3.40 and download the source and use the system's version of SWIG, just modify the location that swig is being invoked from in the makefile. Be sure to give all version details.

     
  • Mike Leahy

    Mike Leahy - 2011-03-07

    Olly, yes it compiles, as do the GDAL modules I was trying this with...the problem is when these methods are invoked by the module when running in PHP...that's when the php reports "undefined symbol: zend_error_noreturn in Unknown on line 0". The expected outcome would instead be to see whatever error message that the module had supplied to the zend_error_noreturn method.

    wsfulton: maybe I'm blind, but I don't see a way to add attachments to this ticket...

     
  • Olly Betts

    Olly Betts - 2011-03-07

    Aha, that's the critical part that nobody had explained previously (the original reporter was very terse, and you said "when building the PHP modules for the GDAL project") - this only manifests if the module actually tries to *call* zend_error_noreturn(). So although the last thing which the test case does is to run the generated wrapmacro.php file with php, which loads the newly built module into PHP, that doesn't tickle the issue, and neither does anything else in the testsuite it would appear.

    If we were to simply change zend_error_noreturn() calls to zend_error(), we'd introduce a slew of compiler warnings when compiling the generated code with commonly used compiler warning settings, so globally changing this isn't a good option. And besides, zend_error_noreturn() is meant to work - if it doesn't, that's a bug in PHP which should be reported and fixed.

    I'll see if I can find a good way to address this for current versions of PHP.

    For future reference, to attach a file, scroll down to the end and click "Add a file", just above the blue box where the list of files would be (but which says there currently aren't any). It would be helpful if that text gave some clue it was clickable...

     
  • Olly Betts

    Olly Betts - 2011-03-07

    OK, we don't need to use zend_error_noreturn() in functions which return void, which means we can avoid these issues completely except for directed functions which return non-void. I've committed that change as r12523.

     
  • Mike Leahy

    Mike Leahy - 2011-03-08

    Looks like that has done the trick.

    For my own future reference, where would a user apply the '-DSWIG_ZEND_ERROR_NORETURN=zend_error' statement?

    Also, as noted off-ticket with wsfulton, the SF tracker doesn't allow non-admin/contributor users to attach files. :/

     
  • Olly Betts

    Olly Betts - 2012-05-11

    Sorry, I missed the question there.

    Pass -DSWIG_ZEND_ERROR_NORETURN=zend_error as an option to the compiler when you compile the generated wrapper file, e.g.:

    g++ -DSWIG_ZEND_ERROR_NORETURN=zend_error -fPIC -o foo_wrap.o foo_wrap.cxx

    (I probably missed some flags you need there, but just add the -DSWIG_ZEND_ERROR_NORETURN=zend_error to what you are passing already).

     
  • Olly Betts

    Olly Betts - 2012-05-12
    • status: open --> closed
     
  • Olly Betts

    Olly Betts - 2012-05-12

    I added a "_runme.php" for a suitable testcase in SWIG's testsuite, but it still doesn't fail.

    After poking this for a while, I can't see why this works for me but not for some other people - this code in PHP doesn't seem to have changed for years, so it's not just that I'm using PHP 5.4.

    But anyway, I've replaced these calls to zend_error_noreturn() with calls to zend_error() but wrapped in a new SWIG_FAIL() function which is annotated as "noreturn" for GCC to avoids reintroducing the warnings. This also reduces the size of the compiled wrapper (e.g. the stripped size is 6% smaller for Xapian's PHP bindings).

    Committed to trunk as r13077.

     

Log in to post a comment.