On 28.05.2014 09:05, Thomas Bruederli wrote:
Maybe you can do some tests with finfo_open() / finfo_file() and mime_content_type() do further track down the failing component.
I have added a couple of error_log statements to the file_content_type function to narrow the problem down (see end of this message). A typical trace for PDF attachments looks like this:
Entering file_content_type Checking mime_ext array MIME type is application/pdf Start finfo_open block End finfo_open block Exiting file_content_type with mime_type application/pdf
while a typical trace for other files (i.e. PNG, XML) looks like this:
Entering file_content_type Checking mime_ext array MIME type is null Start finfo_open block m1: finfo_open exists m3: mime_magic is null m4: process finfo m5: finfo is not null m8: calling finfo_file m9: done calling finfo_file m10: calling finfo_close Entering file_content_type Checking mime_ext array MIME type is null Start finfo_open block m1: finfo_open exists m3: mime_magic is null m4: process finfo m5: finfo is not null m8: calling finfo_file m9: done calling finfo_file m10: calling finfo_close
Seems to me that the Apache child processes die in the finfo_close call, then a new child is spawned which dies there aswell (up to three times). Here is a backtrace from the Apache log, if it helps:
*** Error in `/usr/sbin/apache2': free(): invalid next size (fast): 0x00007f70207d0b40 *** ======= Backtrace: ========= /lib64/libc.so.6(+0x7403f)[0x7f7067dd303f] /lib64/libc.so.6(+0x7995e)[0x7f7067dd895e] /lib64/libc.so.6(+0x7a686)[0x7f7067dd9686] /usr/lib64/libmagic.so.1(+0x4e83)[0x7f705f921e83] /usr/lib64/apache2/modules/libphp5.so(finfo_resource_destructor+0x15)[0x7f705ec9bfe5] /usr/lib64/apache2/modules/libphp5.so(list_entry_destructor+0x52)[0x7f705eefe492] /usr/lib64/apache2/modules/libphp5.so(zend_hash_del_key_or_index+0x29d)[0x7f705eefc36d] /usr/lib64/apache2/modules/libphp5.so(_zend_list_delete+0x7d)[0x7f705eefe6cd] /usr/lib64/apache2/modules/libphp5.so(zif_finfo_close+0x6c)[0x7f705ec9c3bc] /usr/lib64/apache2/modules/libphp5.so(+0x4e6141)[0x7f705efab141] /usr/lib64/apache2/modules/libphp5.so(execute_ex+0x4b)[0x7f705ef1ad4b] /usr/lib64/apache2/modules/libphp5.so(zend_execute_scripts+0x1c3)[0x7f705eeef483] /usr/lib64/apache2/modules/libphp5.so(php_execute_script+0x20b)[0x7f705ee8208b] /usr/lib64/apache2/modules/libphp5.so(+0x4e7f1f)[0x7f705efacf1f] /usr/sbin/apache2(ap_run_handler+0x40)[0x448d20] /usr/sbin/apache2(ap_invoke_handler+0x69)[0x449279] /usr/sbin/apache2(ap_process_async_request+0x1fa)[0x45c3ba] /usr/sbin/apache2[0x4593b0] /usr/sbin/apache2(ap_run_process_connection+0x40)[0x451d60] /usr/sbin/apache2[0x4641de] /lib64/libpthread.so.0(+0x8073)[0x7f706830e073] /lib64/libc.so.6(clone+0x6d)[0x7f7067e4744d]
Finally, here is the modified function I used for debugging:
public static function file_content_type($path, $name, $failover = 'application/octet-stream', $is_stream = false, $skip_suffix = false) { error_log("Entering file_content_type"); static $mime_ext = array();
$mime_type = null;
$config = rcube::get_instance()->config;
$mime_magic = $config->get('mime_magic');
if (!$skip_suffix && empty($mime_ext)) {
foreach ($config->resolve_paths('mimetypes.php') as $fpath) {
$mime_ext = array_merge($mime_ext, (array) @include($fpath));
}
}
// use file name suffix with hard-coded mime-type map
if (!$skip_suffix && is_array($mime_ext) && $name) {
if ($suffix = substr($name, strrpos($name, '.')+1)) {
error_log("Checking mime_ext array");
$mime_type = $mime_ext[strtolower($suffix)];
error_log("MIME type is " . ($mime_type ? $mime_type : "null"));
}
}
error_log("Start finfo_open block");
// try fileinfo extension if available
if (!$mime_type && function_exists('finfo_open')) {
error_log("m1: finfo_open exists");
// null as a 2nd argument should be the same as no argument
// this however is not true on all systems/versions
if ($mime_magic) {
error_log("m2: mime_magic is not null");
$finfo = finfo_open(FILEINFO_MIME, $mime_magic);
}
else {
error_log("m3: mime_magic is null");
$finfo = finfo_open(FILEINFO_MIME);
}
error_log("m4: process finfo");
if ($finfo) {
error_log("m5: finfo is not null");
if ($is_stream) {
error_log("m6: calling finfo_buffer");
$mime_type = finfo_buffer($finfo, $path);
error_log("m7: done calling finfo_buffer");
}
else {
error_log("m8: calling finfo_file");
$mime_type = finfo_file($finfo, $path);
error_log("m9: done calling finfo_file");
}
error_log("m10: calling finfo_close");
finfo_close($finfo);
error_log("m11: done calling finfo_close");
}
}
error_log("End finfo_open block");
// try PHP's mime_content_type
if (!$mime_type && !$is_stream && function_exists('mime_content_type')) {
$mime_type = @mime_content_type($path);
}
// fall back to user-submitted string
if (!$mime_type) {
$mime_type = $failover;
}
else {
// Sometimes (PHP-5.3?) content-type contains charset definition,
// Remove it (#1487122) also "charset=binary" is useless
$mime_type = array_shift(preg_split('/[; ]/', $mime_type));
}
error_log("Exiting file_content_type with mime_type " . $mime_type);
return $mime_type;
}