Edit report at https://bugs.php.net/bug.php?id=31749&edit=1
ID: 31749
Updated by: jpauli@php.net
Reported by: phpbug2 at mailinator dot com
Summary: deadlock due to libc mutexes not released when
timeout signal is delivered
Status: Re-Opened
Type: Bug
Package: Scripting Engine problem
Operating System: Linux 2.4.28, 2.4.21-SMP
PHP Version: 5CVS, 4CVS (2005-06-19)
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
Interesting as well as weird bug.
I have nothing to say about it that would move things forward but that signal
handling have been rewritten in PHP5.4. It might handle such cases, see with
contributors.
You should have a look at http://lxr.php.net/xref/PHP_5_4/Zend/zend_signal.c
and
try to reproduce the bug on a 5.4 basis.
Previous Comments:
------------------------------------------------------------------------
[2011-11-17 01:34:38] tstarling@php.net
I added a workaround to our custom error handler:
https://www.mediawiki.org/wiki/Special:Code/MediaWiki/103433
------------------------------------------------------------------------
[2011-11-16 10:22:13] tstarling@php.net
The suggested patch is an improvement, but it still calls zend_timeout() when the "hard
timeout" is reached, which will usually deadlock if a libc mutex such as the one for malloc()
is held. The only safe way to handle this situation is to kill the process without calling any
non-signal-safe functions, e.g. by calling abort(). If you return control to Apache using longjmp()
(like what zend_bailout() does), Apache will deadlock instead. I haven't found any robust way
to display an error message, it would look the same as a segfault to the user.
------------------------------------------------------------------------
[2010-06-08 13:27:41] michael at makeweb dot no
I have the same problem, reproduced on php 4.4.9 and 5.3.0.
Basically pseudocode to reproduce is set_time_limit(1); do { ... } until time passed = 1 second.
This will create a race condition where sometimes a libc lock will prevent zend_timeout to process
properly.
Script to reproduce on 5.3.0: ($limit is not 1, because php seems to not break accurately on time -
this value must be adjusted so the error "PHP Fatal error: Maximum execution time of 1 second
exceeded in Unknown on line 0" frequently appears. The script should fail within 100 runs (lock
up).
<?php
echo "Trying to break php...\n";
set_time_limit(1);
$limit = 1.235;
$start = array_sum(explode(' ',$x = microtime()));
$a = array();
for ($cnt = 0; $cnt < 10; $cnt++) {
for ($cntb = 0; $cntb < 100; $cntb++) {
for ($cntc = 0; $cntc < 100; $cntc++) {
$end = array_sum(explode(' ',$y = microtime()));
$a[$cnt][$cntb][$cntc] = md5($cnt.$cntb.$cntc);
if ($end >= $start+$limit) break;
}
if ($end >= $start+$limit) break;
}
if ($end >= $start+$limit) break;
}
echo "$x - $y (".($end-$start).")\n";
?>
run with: while [ true ]; do php break.php; done
Though this scenario is unlikely, there are other cases where it can happen very often, however I
fail to come up with a short example of it. The reason for generating a multidimensional array is
that in php4, the hang is very likely to happen within zend_shutdown, as the resources are freed
(hangs within 1-10 cycles)
Keep in mind error logging has to be enabled (this is when there's calls for libc "get
time" which causes the locking issue within zend_timeout)
pstack for php 5.3.0:
# pstack 1565
#0 0x00319402 in __kernel_vsyscall ()
#1 0x001dede3 in __lll_lock_wait_private () from /lib/libc.so.6
#2 0x0016e6f6 in _L_lock_15330 () from /lib/libc.so.6
#3 0x0016dbb4 in free () from /lib/libc.so.6
#4 0x0012067c in setlocale () from /lib/libc.so.6
#5 0x08084586 in seek_to_tz_position ()
#6 0x08084664 in timelib_timezone_id_is_valid ()
#7 0x0806575c in guess_timezone ()
#8 0x080657a5 in get_timezone_info ()
#9 0x08067f35 in php_format_date ()
#10 0x082ab96e in php_log_err ()
#11 0x082abe17 in php_error_cb ()
#12 0x082f9fe8 in zend_error_noreturn ()
#13 0x082ec745 in zend_timeout ()
#14 <signal handler called>
#15 0x00169c49 in _int_free () from /lib/libc.so.6
#16 0x0016dbc0 in free () from /lib/libc.so.6
#17 0x082ac6df in php_conv_fp ()
#18 0x082ad409 in strx_printv ()
#19 0x082ad804 in ap_php_snprintf ()
#20 0x082565f2 in _php_gettimeofday ()
#21 0x08342509 in zend_do_fcall_common_helper_SPEC ()
#22 0x08319f3d in execute ()
#23 0x082f8e47 in zend_execute_scripts ()
#24 0x082a92be in php_execute_script ()
#25 0x08378457 in main ()
Any suggestions how to patch php4 be greatly appreciated!
Michael
------------------------------------------------------------------------
[2008-07-21 01:00:00] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
------------------------------------------------------------------------
[2008-07-13 15:51:47] jani@php.net
Please try using this CVS snapshot:
http://snaps.php.net/php5.2-latest.tar.gz
For Windows (zip):
http://snaps.php.net/win32/php5.2-win32-latest.zip
For Windows (installer):
http://snaps.php.net/win32/php5.2-win32-installer-latest.msi
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=31749
--
Edit this bug report at https://bugs.php.net/bug.php?id=31749&edit=1