|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2007-08-24 16:17 UTC] baco at infomaniak dot ch
Description:
------------
Reproductible with PHP 4.4.7
or with the last Snap 4.4-dev
on Apache2 using MPM worker.
Apache2 process get locked when calling
imagettftext() after calling imagecreate()
every call of such code result of another
dead locked Apache2 processes.
Workarounds :
- Use imagecreatetruecolor() instead of imagecreate()
- Don't use bundled gdlib compile PHP with external gdlib
- Upgrade 5.2.3 who don't have this issue
Reproductible with
configure \
--with-gd \
--with-png-dir=/usr \
--with-freetype-dir=/usr \
--with-ttf \
--enable-gd-native-ttf \
...
Unreproductible with external gd
configure \
--with-gd=/opt/misc/gd \
--with-png-dir=/usr \
--with-jpeg-dir=/usr \
--with-freetype-dir=/usr \
--with-ttf \
--enable-gd-native-ttf \
...
Reproduce code:
---------------
$crash = 1;
$text = 'Bug';
$font = $_SERVER['DOCUMENT_ROOT'] . '/fonts' .'/'. 'arial.ttf';
if ($crash == 1) {
$image = imagecreate(64, 32);
} else {
$image = imagecreatetruecolor(64, 32);
}
$white = imagecolorallocate($image, 255, 255, 255);
/* LOCK APACHE2 PROCESS AFTER THIS POINT IF crash == 1
* => if imagecreate() used but not if imagecreatetruecolor()
*/
imagettftext($image, 20, 0, 8, 24, $white, $font, $text);
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
Expected result:
----------------
Display "Bug" white text on black background
Actual result:
--------------
Apache2 process get locked and browser wait for the
image forever.
After it is a matter of time for Apache2 to have
all processes locked depending on your ServerLimit
and ThreadsPerChild values.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 01 19:00:02 2025 UTC |
see diff in gdImageCreate() --- php-4.4.7/ext/gd/libgd/gd.c 2007-08-24 19:39:33.999613335 +0200 +++ php-5.2.3/ext/gd/libgd/gd.c 2007-08-24 19:39:53.052804086 +0200 @@ -5,8 +5,8 @@ im = (gdImage *) gdMalloc(sizeof(gdImage)); memset(im, 0, sizeof(gdImage)); /* Row-major ever since gd 1.3 */ - im->pixels = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0); - im->AA_opacity = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0); + im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); + im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); im->polyInts = 0; im->polyAllocated = 0; im->brush = 0;Yes, our customers are using both freetype 1.x and 2.x calls. We can't stop support old calls. If you disable both "--with-ttf" and "--enable-gd-native-ttf" apache2 are also locked by calling imagefttext() when imagecreate() is used. We are a web hosting provider and some of our customers are using PHP scripts who are not (yet) compatible with PHP 5 so we need to provide both PHP5 or PHP4 web servers until the end of this year. Apache2 MPM use less memory. We want to use it on all PHP5 and PHP4 servers to handle more simultaneous web connections. For info, the bug is not present when tpixels/TrueColor is used in gdImageCreate another patch (for testing purpose only) make my sample script avoid locking Apache2 but the bug is related to proper mutex in font calls so the best patch is my previous unix_gd_mutex.patch. --- ext/gd/libgd/gd.c 2007-04-14 19:38:38.000000000 +0200 +++ ext/gd/libgd/gd.c 2007-08-27 11:46:21.648861476 +0200 @@ -120,12 +120,13 @@ gdImagePtr gdImageCreate (int sx, int sy) { + int x, y, white; int i; gdImagePtr im; im = (gdImage *) gdMalloc(sizeof(gdImage)); memset(im, 0, sizeof(gdImage)); /* Row-major ever since gd 1.3 */ - im->pixels = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0); + im->tpixels = (int **) safe_emalloc(sizeof(int *), sy, 0); im->AA_opacity = (unsigned char **) safe_emalloc(sizeof(unsigned char *), sy, 0); im->polyInts = 0; im->polyAllocated = 0; @@ -134,29 +135,27 @@ im->style = 0; for (i = 0; i < sy; i++) { /* Row-major ever since gd 1.3 */ - im->pixels[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char)); + im->tpixels[i] = (int *) gdCalloc(sx, sizeof(int)); im->AA_opacity[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char)); } im->sx = sx; im->sy = sy; - im->colorsTotal = 0; im->transparent = (-1); im->interlace = 0; im->thick = 1; im->AA = 0; im->AA_polygon = 0; - for (i = 0; i < gdMaxColors; i++) { - im->open[i] = 1; - im->red[i] = 0; - im->green[i] = 0; - im->blue[i] = 0; - } - im->trueColor = 0; - im->tpixels = 0; + im->trueColor = 1; im->cx1 = 0; im->cy1 = 0; im->cx2 = im->sx - 1; im->cy2 = im->sy - 1; + white = gdImageColorAllocate (im, 255, 255, 255); + for (x = 0; x < sx; x++) { + for (y = 0; y < sy; y++) { + gdImageSetPixel(im, x, y, white); + } + } return im; }