Bug #68486 [Com]: PHP SegFault zend_hash_find
| From: | php at bof dot de | Date: | Thu, 19 Mar 2015 07:52:54 +0000 |
| Subject: | Bug #68486 [Com]: PHP SegFault zend_hash_find | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-191459@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=68486&edit=1
ID: 68486
Comment by: php at bof dot de
Reported by: wattwood at tcstire dot com
Summary: PHP SegFault zend_hash_find
Status: Open
Type: Bug
Package: Apache2 related
Operating System: Ubuntu 14.04.1 LTS
PHP Version: 5.5.19
Block user comment: N
Private report: N
New Comment:
Everything is running smoothly with the one-line patch attached yesterday (thanks again gmoniker!).
That is on two different (same load) production boxes, one with Apache 2.2 and one with Apache 2.4.
No segfaults, no CPU usage or memory usage or latency issues (I've got them covered pretty
thoroughly in Nagios).
I think this is ready to go into the next 5.5.x, 5.6.x, and master.
Previous Comments:
------------------------------------------------------------------------
[2015-03-18 22:39:33] gmoniker at gmail dot com
@bof, Thanks for your hard work!
I still don't know exactly when the first request pool is destroyed by the EOR bucket. It might
be when the output of the next request begins to run. Anyway this is a very necessary patch for
using Apache 2.4.
------------------------------------------------------------------------
[2015-03-18 15:29:10] php at bof dot de
Production test of the one-liner patch, using Apache 2.4, ran flawlessly, now for five hours
straight.
Just to be sure it's good, I'll run a second build under Apache 2.2 + put that on one of
my not-yet-upgraded production servers tomorrow.
But I think this patch is good to go in. I added it now as a patch to this bug report, for that
reason.
------------------------------------------------------------------------
[2015-03-18 09:39:52] php at bof dot de
Re: [2015-03-17 23:22 UTC] gmoniker at gmail dot com
Jep, I think your one line fix to the end of php_handler(), fixes the immediate problem here.
Initial testing confirms. I'll test in production later today.
I didn't realize before (but now confirmed in apache sources), that apr_pool_cleanup_run()
_cancels_ an exact same previously set cleanup callback.
Reentry by virtual() still dumps core (even with ap_rflush removed there), as probably will the
other funny reentry cases. But as far as I can see, all those can only be triggered by suitable PHP
code, and not at will by external requests - so they are better handled separately in new bug
reports.
------------------------------------------------------------------------
[2015-03-18 04:45:33] phpdev at ehrhardt dot nl
I applied http://bei.bof.de/php/sapi_apache2.noreentry.v3.patch
on my Centos6 development server with Apache 2.4.12 with PHP 5.6.6 as mod_php. Result: the segfaults
did not happen anymore, so the patch seems to be OK.
Limesurvey, Drupal7 and Piwik ran fine after applying the patch. Especially Piwik is worth
mentioning because it seems to stress PHP to the max. After patch v3 it produced an occasional
'zend_mm_heap corrupted' (like it always does), but no segfault.
------------------------------------------------------------------------
[2015-03-17 23:22:47] gmoniker at gmail dot com
It seems to me that it will be hard to revalidate this handler if it is changed extensively.
Just did some testing with a one line adjustment to the code of
"sapi/apache2handler/sapi_apache2.c".
Towards the end of php_handler(request_rec *r) I included the line:
apr_pool_cleanup_run(r->pool, (void *)&SG(server_context),
php_server_context_cleanup);
So it becomes:
if (!parent_req) {
php_apache_request_dtor(r TSRMLS_CC);
ctx->request_processed = 1;
bucket = apr_bucket_eos_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
rv = ap_pass_brigade(r->output_filters, brigade);
if (rv != APR_SUCCESS || r->connection->aborted) {
zend_first_try {
php_handle_aborted_connection();
} zend_end_try();
}
apr_brigade_cleanup(brigade);
apr_pool_cleanup_run(r->pool, (void *)&SG(server_context),
php_server_context_cleanup);
} else {
ctx->r = parent_req;
}
It seems to me this solves the missing automatic request pool destruction after a request in Apache
2.4 leading the php_handler routine to consider independent follow-on requests a subrequest of the
first request when they are not. The request pool can continue on, but without the php_struct in it.
I am afraid the Apache 2.4 handling of these pipelines can cause memory bloat of the server process,
but that belongs in Apaches corner.
------------------------------------------------------------------------
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=68486
--
Edit this bug report at https://bugs.php.net/bug.php?id=68486&edit=1