I
I
Ivan Yudin2012-12-12 06:54:21
PHP
Ivan Yudin, 2012-12-12 06:54:21

Segfault imagick+php5.4+apache2.4?

Hello!
We moved to a new hosting, and Apache began to detect persistent segfaults in the logs:
[core:notice] [pid 30135:tid 34376532416] AH00052: child pid 59717 exit signal Segmentation fault (11)
[core:notice] [pid 30135:tid 34376532416] AH00052: child pid 46485 exit signal Segmentation fault (11)
[core:notice] [pid 30135:tid 34376532416] AH00052: child pid 67188 exit signal Segmentation fault (11)
Installed gdb, did
backtrace
#0 execute (op_array=0x8034361) , tsrm_ls=0x8135ec6e0)
at /root/source/php-5.4.9/Zend/zend_vm_execute.h:363
execute_data = (zend_execute_data *) 0x0
nested = 0 '\0'
original_in_execution = 0 '\0'
#1 0x00000008027300ee in zend_execute_scripts (type=2, tsrm_ls=0x8135ec6e0,
retval=0x0, file_count=1) at /root/source/php-5.4.9/Zend/zend.c:1309
params = {0x534500}
retval2 = (zval *) 0x50
old_exception = (zval *) 0x50
files = {{gp_offset = 40, fp_offset = 0,
overflow_arg_area = 0x7ffffdff0bf0, reg_save_area = 0x7ffffdff0b00}}
i = 0
file_handle = (zend_file_handle *) 0x7ffffdff0c10
orig_op_array = (zend_op_array *) 0x0
orig_retval_ptr_ptr = (zval **) 0x0
#2 0x00000008027eb422 in php_handler (r=0x816d25698)
at /root/source/php-5.4.9/sapi/apache2handler/sapi_apache2.c:669
zfd = {type = ZEND_HANDLE_FILENAME,
filename = 0x816d26378 "/var/www/24starcom.ru/http/shop/goodimg/photo.php",
opened_path = 0x0, handle = {fd = 120, fp = 0x78, stream = {handle = 0x78,
isatty = 3, mmap = {len = 34377627512, pos = 34742621848,
map = 0x801c3cafe, buf = 0x816d26608 "php", old_handle = 0x816d23a20,
old_closer = 0}, reader = 0x816d25698, fsizer = 0x801171820,
closer = 0x816d25601}}, free_filename = 0 '\ 0 '}
__bailout = {{_sjb = {34401595561, 34742621848, 140,737,454,738,408, 1,
34742621848, 34377627248, 140,737,454,739,164, 34,732,335,816, 895, 4,387,130, 1,
34359738368}}}
ctx = (php_struct * volatile) 0x8169877c8
conf = (void *) 0x80109dd90
brigade = (apr_bucket_brigade * volatile) 0x8169766b0
bucket = <value optimized out>
rv = <value optimized out>
parent_req = (request_rec * volatile) 0x816986698
tsrm_ls = (void ***) 0x8135ec6e0
#3 0x0000000000444b6a in ap_run_handler (r=2) config.c:168
n = 1
rv = 7
#4 0x00000000004487a2 in ap_invoke_handler (r=0x816d25698) at config.c:432
handler = 0x801134568 "application/x-httpd-php"
result = 0
old_handler = 0x0
ignore = <value optimized out>
#5 0x0000000000458dea in ap_internal_redirect (new_uri=<value optimized out>,
r=<value optimized out>) at http_request.c:640
new = (request_rec *) 0x816d25698
access_status = 2400
#6 0x0000000802257510 in handler_redirect (r=0x816a820a0)
at mod_rewrite.c:5039
No locals.
# 7 0x0000000000444b6a in ap_run_handler (r = 0x816a820a0) at config.c:168
n = 0
rv = 7
# 8 0x00000000004487a2 in ap_invoke_handler (r = 0x816a820a0) at config.c: 432
handler = 0x0
result = 0
old_handler = 0x80225bf5c "redirect- handler"
ignore = <value optimized out>
#9 0x00000000004591ce in ap_process_async_request (r=0x816a820a0)
at http_request.c:317
i = 0
t_h = (const apr_array_header_t *) 0x7ffffdff0edc
t_elt = (const apr_table_entry_t *)
52c81 0x8163562c8
access_status = 0
#10 0x000000000045930f in ap_process_request (r=0x90) at http_request.c:363
bb = <value optimized out>
b = <value optimized out>
c = (conn_rec *) 0x8163562c8
rv = <value optimized out>
#11 0x0000000000455f45 in ap_process_http_connection (c=0x8163562c8)
at http_core.c:190
No locals.
#12 0x000000000044e5e2 in ap_run_process_connection (c=0x8163562c8) at connection.c
:41
n = 1 rv
= 7 = 13 csd = (apr_socket_t *) 0x8163560b0
bucket_alloc = (apr_bucket_alloc_t *) 0x816974028
last_ptrans = <value optimized out>
ptrans = (apr_pool_t *) 0x816356028
rv = <value optimized out>
is_idle = <value optimized out>
#14 0x0000000800c7d501 in ?? () from /lib/libthr.so.3
No symbol table info available.
#15 0x0000000000000000 in ?? ()
I realized from here that the problem is in photo.php, which makes thumbnails from images and adds a logo. On advice, I got rid of GD and rewrote the script using ImageMagick. The code has become more convenient, it has become slower to work (and to hell with it), but the segmentation fault has remained. The backtrace above is already using imagemagick, but they are not much different.
Script Code

<?php
     header("Content-Type: image/jpeg");
     header("Accept-Ranges: bytes");
     define('abspath', '[censoured]');

    preg_match("|([a-z]*)([0-9]*)(.*)|", $_GET['file'], $res);
    $prefix = $res[1];
    $photoid = $res[2];
    http_cache_etag(substr(md5($prefix.$photoid), 0, 12));
    header("Expires: " . gmdate ("D, d M Y H:i:s", time() + (30 * 24 * 60 * 60)) . " GMT");

  $fname = abspath.$prefix.'/'.$photoid.'.jpg';
  $orig = abspath.'orig/'.$photoid.'.jpg';
  
 	if (is_file($fname)) {
 		header("Content-Length: ".filesize($fname));
    die(file_get_contents($fname));
  }
  
  $base = array(
    'p'		=> array (90,	90),	// preview
    'f'		=> array (400,	400),	// full
    'sm'		=> array (160,	160),	// shop mainblock
    'sp'		=> array (120,	120),	// shop preview
    'sf' 		=> array (300, 	300),	// shop full
    'sfp' 		=> array (700, 	700),	// shop full preview
  );
  
  /*
  function ResizeImageGD($file,$out,$mw,$mh,$rotate=false,$logo=false) {
    $oi = imagecreatefromjpeg($file);
    if (!$oi) die();
    if ($rotate!=0)
    		    $oi = imagerotate($oi, 354, 0xFFFFFF);
    $ow = imagesx($oi);
    $oh = imagesy($oi);
    $c = min($mw/$ow,$mh/$oh);
    if ($c<1) {
      $nh = round($c*$oh); $nw = round($c*$ow);
    } else {
      $nh = $oh; $nw = $ow;
    }
    $image = imagecreatetruecolor($nw,$nh);
    imagecopyresampled($image,$oi,0,0,0,0,$nw,$nh,$ow,$oh);
    if (($logo) && (imagesy($image)>100)) {
      $logo = ImageCreateFromPNG('/var/www/24starcom.ru/http/shop/images/logo_trans.png');
      ImageCopy($image, $logo, imagesx($image)-110, imagesy($image)-30, 0, 0, imagesx($logo), imagesy($logo));
      imagedestroy($logo);
    }
    imagejpeg($image,$out,90);
    imagedestroy($oi);
    imagedestroy($image);
  }
  */
  
  function ResizeImageIM($file,$out,$mw,$mh,$rotate=false,$logo=false) {
    $thumb = new Imagick();
    $thumb->readImage($file);
    if ($rotate)
      $thumb->rotateImage(new ImagickPixel('#FFFFFFFF'), 6);
    $ow = $thumb->getImageWidth();
    $oh = $thumb->getImageHeight();
    $c = min($mw/$ow,$mh/$oh);
    if ($c<1) {	$nh = round($c*$oh); $nw = round($c*$ow); }
    else { $nh = $oh; $nw = $ow; }
    $thumb->thumbnailImage($nw, $nh);
    if ($logo && ($nw>110) && ($nh>30)) {
      $watermark = new Imagick();
      $watermark->readImage('[censoured]');
      $thumb->compositeImage($watermark, Imagick::COMPOSITE_OVER, $nw-110, $nh-30);
    }	
    $thumb->writeImage($out);
  }	

  if (is_file($orig)) {
    $rotate = false;
    if ((in_array($prefix, array('f', 'sf', 'sfp'))) && ($photoid!=0))
      $rotate = true;
 		ResizeImageIM($orig, $fname, $base[$prefix][0], $base[$prefix][1], $photoid, $rotate);
 		header("Content-Length: ".filesize($fname));
 		die (file_get_contents($fname));
  }

?>

What to do next? Where to dig?
System
and versions amd64/compile/ISPSYSTEM amd64
24starcom# httpd -V
Server version: Apache/2.4.3 (Unix)
Server built: Dec 7 2012 08:22:06
Server's Module Magic Number: 20120211:6
Server loaded: APR 1.4.6, APR -UTIL 1.5.1
Compiled using: APR 1.4.6, APR-UTIL 1.5.1
Architecture: 64-bit
Server MPM: worker
threaded: yes (fixed thread count)
forked: yes (variable process count)
Server compiled with…
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
APR_HAVE_IPV6 -D (IPv4-mapped addresses enabled)
-D APR_USE_FLOCK_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT = 256
-D HTTPD_ROOT = "/ usr / local / apache2.4"
-D SUEXEC_BIN = "/ usr/local/apache2.4/bin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime. types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
24starcom# php -v
PHP 5.4.9 (cli) (built: Dec 11 2012 14:43:47)
Copyright © 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright © 1998-2012 Zend Technologies
with XCache v3.0.0, Copyright © 2005-2012, by mOo
with XCache Optimizer v3.0.0, Copyright © 2005-2012, by mOo
with XCache Cacher v3.0.0, Copyright © 2005-2012 by mOo

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey Venediktov, 2012-12-12
@sven

I think that the problem is in "Server MPM: worker ".
This mpm uses threads.
Most likely some Apache module is not thread-safe. Try switching to prefork if you can.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question