Summary: | libphp5.so exports symbols which conflict with modules loaded by mod_perl | ||
---|---|---|---|
Product: | Gentoo Linux | Reporter: | Nicholas Vinen <hb> |
Component: | [OLD] Server | Assignee: | PHP Bugs <php-bugs> |
Status: | RESOLVED FIXED | ||
Severity: | normal | ||
Priority: | High | ||
Version: | 2005.1 | ||
Hardware: | x86 | ||
OS: | Linux | ||
URL: | http://bugs.php.net/36208 | ||
Whiteboard: | watch-php-bugzilla | ||
Package list: | Runtime testing required: | --- | |
Attachments: |
php-5.0.5-gd-compat-backport.patch
Patch to fix include errors. Fixed/merged patch php-5.1.2-gd-compat.patch |
Description
Nicholas Vinen
2006-01-30 00:10:23 UTC
Not really sure what kind of fix do you expect from us, both things link against media-libs/gd, so they export the same symbols... I worked around this problem by doing the following: USE="gd-external -gd -tiff" emerge =dev-lang/php-5.0.5-r5 This builds php-5.0.5-r5 without linking to libgd statically. Because it's dynamically linked, it imports the symbols rather than exporting them, and thus does not confuse the dynamic linker. I still think this is a problem, though. Firstly, this took me hours to track down and fix, and if it's going to be a serious problem the "gd" option of php should proably be removed and replaced with gd-external only. (I'm not sure what the advantage of statically linking it is - speed?) Or else a big warning should be put there. Secondly, for some reason I have to disable TIFF support in PHP since it thinks it needs gd to build TIFF support, even though gd-external is being used. Ideally this should be fixed so you can link the module either way and it should work. I think this might need a change/fix to glibc/the dynamic linker to achieve. Well, if you are not willing to fix the base problem, perhaps you know who to notify about this? It was a giant pain and time-waster for me to have to track this down, and I know how to debug C programs. I can't imagine how many problems this would cause a newbie. They'd be tearing their hair out. So I would suggest: * Find a way to work-around this so it can't happen. For example, somehow make the "gd" option from libphp5 hard to enable. For example, if it's enabled, print a big warning saying "ABANDON HOPE ALL YE WHO ENTER HERE - If you really, really want to do this (explain why it's a bad idea) use the gd-force-php5 flag" and then exit. This way people can't accidentally fall into this trap. * Let the glibc people know this is broken. I can do this if you want. In my opinion this is a serious failure of the dynamic linker system as a robust tool. OK, I think I now understand exactly what is going on. The problem is that PHP contains its own implementation of GD, but they didn't change the symbol names so they won't collide: hb@nexus /var/tmp/portage/php-5.1.1/work $ find . -name *gd* ./php-5.1.1/ext/gd/libgd ./php-5.1.1/ext/gd/libgd/gd.c ./php-5.1.1/ext/gd/libgd/gd.h ./php-5.1.1/ext/gd/libgd/gdtables.c ... These are obviously not properly compatible with libgd. Yet the symbol names are the same. So if two .so files are loaded into the same application space, one uses libgd and the other uses libphp5, gd will break. The best solution would be, in my opinion, for PHP to use only libgd under Gentoo. Gentoo portage can automatically pull the library in and keep it up to date. This removes the advantage of packaging them together, IMO. Is there an advantage to using the built-in one over libgd? If not, my recommendations are: * Gentoo fix: libphp5 ALWAYS uses libgd, never built-in gd. * PHP fix: Notify PHP team of the problem. Recommend they prefix the symbols in the built-in version to avoid this conflict in future. Or else use library versioning so that the linker will not confuse the symbols. * GLIBC fix: Recommend to GNU that future dynamic linker spits out an error in the case where a process loads the same symbol from multiple different locations and the data at the symbol does not match. Otherwise this kind of problem has the potential for happening. (In reply to comment #4) > * Gentoo fix: libphp5 ALWAYS uses libgd, never built-in gd. No. The GD that PHP bundles is specifically enhanced to work with PHP (new features, changed stuff, performance), so it will remain as an option (and it should be used by default). > * PHP fix: Notify PHP team of the problem. Recommend they prefix the symbols > in the built-in version to avoid this conflict in future. Or else use library > versioning so that the linker will not confuse the symbols. This is imo the only correct fix, please open a bug at http://bugs.php.net/ about it and link it back here, so we can implement the patch in Gentoo's PHP once upstream has done it (IF they will). Try to get that fix in both PHP4 and PHP5, as I assume PHP4 has it too, since it uses the bundled library too. > * GLIBC fix: Recommend to GNU that future dynamic linker spits out an error in > the case where a process loads the same symbol from multiple different > locations and the data at the symbol does not match. Otherwise this kind of > problem has the potential for happening. Don't know about this, anyway still an upstream question, ask glibc people.$ Best regards, CHTEKK. Ups sorry, reopen as it's not assigned to us and so that glibc maintainer can comment wrt the possible glibc change/fix... Best regards, CHTEKK. I agree, if this is fixed in PHP then the built-in GD can continue to be used as default. Here is the bug report I have submitted: http://bugs.php.net/36208 I do think it's a problem that the dynamic loader will happily associate the symbols wrong. The PHP people should have renamed or changed the version of the symbols, but ideally this bug should be caught and reported, rather than causing random crashes. Perhaps the dynamic linker can check if it expects to be pulling in dynamic symbols from libgd.so and it finds them in a different .so, and print a warning message. I realize there are situations where you might actually want this, but can they be somehow distinguished so that these incorrect occasions are caught? Perhaps it's too difficult but I think it would be beneficial overall. Re-assign (it's been assigned to vapier as media-libs/gd maintainer, but there's nothing wrong with that one it appears.) (In reply to comment #7) > Here is the bug report I have submitted: > > http://bugs.php.net/36208 Thanks. > I do think it's a problem that the dynamic loader will happily associate the > symbols wrong. CCing toolchain if they wish to comment on this. you dont need to rename them, just mark them with hidden visibility Marking this upstream, will be fixed when upstream fixes the issue. The PHP people are refusing to fix this (see http://bugs.php.net/36208). What do I do now? If I come up with a patch which stops these symbols being exported from PHP can we put it into portage? Alternatively, perhaps we can make the PHP and PERL ebuilds detect this problem and warn the user about it. However, I prefer a fix which stops this from happening without affecting the user's options, which the patch should provide. Uhm, while we could fix the issue for Gentoo (when someone produces the patch), this is really of no use for other PHP users, it really needs to go upstream. We won't be forcing gd-external on people, that's not a solution and mod_perl is just one of the the examples where this may screw things up... Anyway, looks fixed upstream in >=5.1.1 at least... This should be backported upstream for 4.4.x, I highly doubt they will fix 5.0.x, as there won't be 5.0.6 release ever, AFAIK. Ah, it may be fixed in 5.1.1 but that is not marked as stable on x86, hence when I install dev-lang/php I get 5.0.5-r5 which presumably still has this bug. Perhaps it would therefore be worth putting a patch in Gentoo until 5.1.1 is marked as stable? I will try installing dev-lang/php-5.1.1 and see if the problem is gone. Strange though that 5.1.1 fixes it??? As there were no changes to main/php_compat.h and to the gd libs/ext that would "fix" this, at least I could fine none in CVS. But indeed in 5.1.1: 08153cf7 T php_gd_gdImagePng 08153be3 T php_gd_gdImagePngCtx 08153223 T php_gd_gdImagePngCtxEx 08153d45 T php_gd_gdImagePngEx 08153c85 T php_gd_gdImagePngPtr 08153c13 T php_gd_gdImagePngPtrEx 08152328 T php_gd_gdImagePngToSink So they get correctly prefixed... But in PHP 4.4.1 they aren't, still need to test 4.4.2, but there are others that aren't prefixed yet... I'll see to fix those. Best regards, CHTEKK. Update: I checked the sources a little more, it seems that PHP 4.X (all) and PHP 5.0.X (all) do not have any of those GD prefixes, they were only introduced with PHP 5.1.1 (see line 127+ of main/php_compat.h of PHP 5.1.X). So the fix will have to be backported to older PHP versions, I'll test this this evening, as I'm not sure if it will break other stuff, but it shouldn't. Best regards, CHTEKK. Created attachment 78631 [details, diff] php-5.0.5-gd-compat-backport.patch Please, test this patch and report back. Download the attached patch to dev-lang/php/files and modify the ebuild: --- php-5.0.5-r5.ebuild.orig 2006-01-26 01:06:18.000000000 +0100 +++ php-5.0.5-r5.ebuild 2006-02-01 11:28:52.000000000 +0100 @@ -87,6 +87,7 @@ # patch to fix safe_mode bypass in GD extension, bug #109669 if use gd || use gd-external ; then epatch "${WORKDIR}/${PV}/php${PV}-gd-safe_mode.patch" + epatch "${FILESDIR}/php-5.0.5-gd-compat-backport.patch" fi # patch open_basedir directory bypass, bug #102943 Let us know how it goes... I think you're on to the right track but I get this when building after the patch: ext/gd/gd.o: In function `zif_imagecreatefromstring': gd.c:(.text+0x29a7): undefined reference to `php_gd_gdImageCreateFromWBMPCtx' ext/gd/gd.o: In function `zif_imagecreatefromwbmp': gd.c:(.text+0x8271): undefined reference to `php_gd_gdImageCreateFromWBMPCtx' gd.c:(.text+0x8276): undefined reference to `php_gd_gdImageCreateFromWBMP' ext/gd/gd.o: In function `zif_imagecreatefromgd': gd.c:(.text+0x829d): undefined reference to `php_gd_gdImageCreateFromGdCtx' gd.c:(.text+0x82a2): undefined reference to `php_gd_gdImageCreateFromGd' ext/gd/gd.o: In function `zif_imagegif': gd.c:(.text+0x8349): undefined reference to `php_gd_gdImageGifCtx' ext/gd/gd.o: In function `zif_imagewbmp': gd.c:(.text+0x83c1): undefined reference to `php_gd_gdImageWBMPCtx' ext/gd/gd.o: In function `zif_imagegd': gd.c:(.text+0x83e9): undefined reference to `php_gd_gdImageGd' ext/gd/gd.o: In function `_php_image_output': gd.c:(.text+0x9778): undefined reference to `php_gd_gdImageWBMP' gd.c:(.text+0x98a5): undefined reference to `php_gd_gdImageWBMP' ext/gd/gd.o: In function `_php_image_type': gd.c:(.text+0x9a22): undefined reference to `php_gd_gdGetC' gd.c:(.text+0x9a33): undefined reference to `php_gd_gdGetC' ext/gd/gd.o: In function `_php_image_convert': gd.c:(.text+0xa088): undefined reference to `php_gd_gdImageWBMP' ext/gd/gd.o: In function `php_find_gd_font': gd.c:(.text+0xa967): undefined reference to `php_gd_gdFontTiny' gd.c:(.text+0xa96f): undefined reference to `php_gd_gdFontSmall' gd.c:(.text+0xa977): undefined reference to `php_gd_gdFontMediumBold' gd.c:(.text+0xa97f): undefined reference to `php_gd_gdFontLarge' gd.c:(.text+0xa987): undefined reference to `php_gd_gdFontGiant' gd.c:(.text+0xa9ad): undefined reference to `php_gd_gdFontGiant' gd.c:(.text+0xa9b6): undefined reference to `php_gd_gdFontTiny' ext/gd/gd.o: In function `_php_image_bw_convert': gd.c:(.text+0x7f9c): undefined reference to `php_gd_gdImageWBMPCtx' ext/gd/libgd/gd.o: In function `php_gd_gdImageFilledArc': gd.c:(.text+0x21b1): undefined reference to `php_gd_gdCosT' gd.c:(.text+0x21c9): undefined reference to `php_gd_gdSinT' ext/gd/libgd/gd_gd.o: In function `gdImageCreateFromGdCtx': gd_gd.c:(.text+0x1e7): undefined reference to `gdImageDestroy' ext/gd/libgd/gd_gd.o: In function `gdImageCreateFromGd': gd_gd.c:(.text+0x1ff): undefined reference to `gdNewFileCtx' ext/gd/libgd/gd_gd.o: In function `gdImageCreateFromGdPtr': gd_gd.c:(.text+0x229): undefined reference to `gdNewDynamicCtxEx' ext/gd/libgd/gd_gd.o: In function `gdImageGd': gd_gd.c:(.text+0x2e7): undefined reference to `gdNewFileCtx' ext/gd/libgd/gd_gd.o: In function `gdImageGdPtr': gd_gd.c:(.text+0x35c): undefined reference to `gdNewDynamicCtx' gd_gd.c:(.text+0x3bc): undefined reference to `gdDPExtractData' ext/gd/libgd/gd_gd.o: In function `_gdCreateFromFile': gd_gd.c:(.text+0x438): undefined reference to `gdImageCreateTrueColor' gd_gd.c:(.text+0x443): undefined reference to `gdImageCreate' gd_gd.c:(.text+0x460): undefined reference to `gdImageDestroy' ext/gd/libgd/gd_gd2.o: In function `php_gd_gdImageCreateFromGd2Ctx': gd_gd2.c:(.text+0x174): undefined reference to `php_gd_gdTell' gd_gd2.c:(.text+0x183): undefined reference to `php_gd_gdSeek' gd_gd2.c:(.text+0x193): undefined reference to `php_gd_gdGetBuf' gd_gd2.c:(.text+0x24e): undefined reference to `php_gd_gdGetInt' gd_gd2.c:(.text+0x27c): undefined reference to `php_gd_gdGetByte' ext/gd/libgd/gd_gd2.o: In function `php_gd_gdImageCreateFromGd2PartCtx': gd_gd2.c:(.text+0x4ca): undefined reference to `php_gd__gdGetColors' gd_gd2.c:(.text+0x5da): undefined reference to `php_gd_gdTell' gd_gd2.c:(.text+0x69e): undefined reference to `php_gd_gdSeek' gd_gd2.c:(.text+0x6ea): undefined reference to `php_gd_gdTell' gd_gd2.c:(.text+0x6f9): undefined reference to `php_gd_gdSeek' gd_gd2.c:(.text+0x709): undefined reference to `php_gd_gdGetBuf' gd_gd2.c:(.text+0x785): undefined reference to `php_gd_gdGetInt' gd_gd2.c:(.text+0x794): undefined reference to `php_gd_gdGetC' ext/gd/libgd/gd_gd2.o: In function `_gd2GetHeader': gd_gd2.c:(.text+0xa73): undefined reference to `php_gd_gdGetC' gd_gd2.c:(.text+0xaad): undefined reference to `php_gd_gdGetWord' gd_gd2.c:(.text+0xad0): undefined reference to `php_gd_gdGetWord' gd_gd2.c:(.text+0xae4): undefined reference to `php_gd_gdGetWord' gd_gd2.c:(.text+0xaf8): undefined reference to `php_gd_gdGetWord' gd_gd2.c:(.text+0xb1c): undefined reference to `php_gd_gdGetWord' ext/gd/libgd/gd_gd2.o:gd_gd2.c:(.text+0xb3b): more undefined references to `php_gd_gdGetWord' follow ext/gd/libgd/gd_gd2.o: In function `_gd2GetHeader': gd_gd2.c:(.text+0xb92): undefined reference to `php_gd_gdGetInt' gd_gd2.c:(.text+0xba1): undefined reference to `php_gd_gdGetInt' ext/gd/libgd/gd_gd2.o: In function `_gd2CreateFromFile': gd_gd2.c:(.text+0xc39): undefined reference to `php_gd__gdGetColors' ext/gd/libgd/gd_gd2.o: In function `_gdImageGd2': gd_gd2.c:(.text+0xd36): undefined reference to `php_gd_gdPutC' gd_gd2.c:(.text+0xd48): undefined reference to `php_gd_gdPutWord' gd_gd2.c:(.text+0xd5a): undefined reference to `php_gd_gdPutWord' gd_gd2.c:(.text+0xd6c): undefined reference to `php_gd_gdPutWord' gd_gd2.c:(.text+0xd7b): undefined reference to `php_gd_gdPutWord' gd_gd2.c:(.text+0xd8a): undefined reference to `php_gd_gdPutWord' ext/gd/libgd/gd_gd2.o:gd_gd2.c:(.text+0xd99): more undefined references to `php_gd_gdPutWord' follow ext/gd/libgd/gd_gd2.o: In function `_gdImageGd2': gd_gd2.c:(.text+0xe2b): undefined reference to `php_gd_gdTell' gd_gd2.c:(.text+0xe4e): undefined reference to `php_gd_gdSeek' gd_gd2.c:(.text+0xe75): undefined reference to `php_gd__gdPutColors' gd_gd2.c:(.text+0xf9a): undefined reference to `php_gd_gdPutInt' gd_gd2.c:(.text+0xfb3): undefined reference to `php_gd_gdPutC' gd_gd2.c:(.text+0x100b): undefined reference to `php_gd_gdTell' gd_gd2.c:(.text+0x1031): undefined reference to `php_gd_gdPutBuf' gd_gd2.c:(.text+0x108b): undefined reference to `php_gd_gdTell' gd_gd2.c:(.text+0x109a): undefined reference to `php_gd_gdSeek' gd_gd2.c:(.text+0x10b3): undefined reference to `php_gd_gdPutInt' gd_gd2.c:(.text+0x10c5): undefined reference to `php_gd_gdPutInt' gd_gd2.c:(.text+0x10d8): undefined reference to `php_gd_gdSeek' ext/gd/libgd/gd_ss.o: In function `gdImagePngToSink': gd_ss.c:(.text+0x8): undefined reference to `gdNewSSCtx' gd_ss.c:(.text+0x14): undefined reference to `gdImagePngCtx' ext/gd/libgd/gd_ss.o: In function `gdImageCreateFromPngSource': gd_ss.c:(.text+0x2d): undefined reference to `gdNewSSCtx' gd_ss.c:(.text+0x35): undefined reference to `gdImageCreateFromPngCtx' ext/gd/libgd/gd_png.o: In function `php_gd_gdImageCreateFromPngCtx': ... I think perhaps some files are not including php_compat.h, probably just ext/gd/gd.c. Since, notice that some files have undefined references to php_gd_* (meaning they include php_compat.h, but not the file that defines those symbols) and some have undefined references to gd* (meaning they probably don't include php_compat.h). Created attachment 78633 [details, diff]
Patch to fix include errors.
This should fix those, please test, thanks!
Best regards, CHTEKK.
Created attachment 78638 [details, diff]
Fixed/merged patch
OK, I attached the patch I merged from the two you provided which seems to work. I also added six more renamed function calls for gd, which were still being exported to the .so file. Everything seems fine now. The only remaining issue may be to get those six patched in the next release of PHP 5.1.x. I'll try to do that tomorrow. They do not seem to cause any problems but it's hard to be sure, as it may only be because I'm not calling them in my test case. (In reply to comment #21) Uhm, I'd say don't bother with that, it's upstream job really - just forward the patch upstream so that they can fix their stuff, instead of requesting a backtrace, huh. Thanks for testing and help. Created attachment 78639 [details, diff]
php-5.1.2-gd-compat.patch
Adding those 6 additional compatibility symbols to main/php_compat.h in php-5.1.2
This was now fixed upstream in 5.1.3RC1, but will afaik not be fixed in the PHP 4.X series. I backported the various patches to all our PHP relases now, emerge --sync in a couple of hours and you should get them, PHP 4.4.2 and PHP 5.1.2 were added to the Portage tree including those fixes (as I also added them to our PHP 4.X releases). Best regards, CHTEKK. |