Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:69230 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 87995 invoked from network); 19 Sep 2013 09:51:15 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Sep 2013 09:51:15 -0000 Authentication-Results: pb1.pair.com header.from=lazy404@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=lazy404@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.212.41 as permitted sender) X-PHP-List-Original-Sender: lazy404@gmail.com X-Host-Fingerprint: 209.85.212.41 mail-vb0-f41.google.com Received: from [209.85.212.41] ([209.85.212.41:42339] helo=mail-vb0-f41.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 7F/3A-29009-119CA325 for ; Thu, 19 Sep 2013 05:51:14 -0400 Received: by mail-vb0-f41.google.com with SMTP id g17so6429979vbg.0 for ; Thu, 19 Sep 2013 02:51:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=8rKucmk9p37+eR39Nc9K5LpT8ne5EChrBvE2xRXV6Sc=; b=PzZXhmvhx8ueZcIPS+NODMgnJ1y3WnL5Cj76cxKSqxQIV+fnVsbSym9ktD3k+CWo5F NjuWzSpeOUffh3h6zgVpCrp7iZjx4Wa6x72uEfW0qfN5Q7X4rDCQ1g5ph8zUn+QU57Uy dkBt3eS24Yvan6qdXuX56nqxEYShcQ2+dGAdTKY8NV8AsxKkCHKFKdOjXCEVGHH3x/sj V1iHfCnZ1qb2fOVFDob/Zj2NjBdRWfKNU2HPtw2yZW1sTNL4j9Zxfxkd4OOUaM2pY9nw J7TDe63qWoVMAC2a93A0sxEneR1vwJbqXK7kYS7qCJChwvA+9hHdJcUEce0aFK/MeRPK yYDA== MIME-Version: 1.0 X-Received: by 10.220.105.199 with SMTP id u7mr395003vco.1.1379584271309; Thu, 19 Sep 2013 02:51:11 -0700 (PDT) Received: by 10.58.6.212 with HTTP; Thu, 19 Sep 2013 02:51:11 -0700 (PDT) In-Reply-To: <523A047B.3040509@gmail.com> References: <523A047B.3040509@gmail.com> Date: Thu, 19 Sep 2013 11:51:11 +0200 Message-ID: To: =?ISO-8859-1?Q?=C1ngel_Gonz=E1lez?= Cc: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] free deadlock in timeout signal handler From: lazy404@gmail.com (Lazy) 2013/9/18 =C1ngel Gonz=E1lez : > On 13/09/13 22:10, Lazy wrote: >> >> Hello internals, >> >> I'm trying to fix deadlock in an ancient php 5.2.17, php hangs on >> internal libc lock. >> From my understanding free is not safe to use in a signal handler, and >> this seems to be the issue here. > > No, it's not. > > >> http://marc.info/?l=3Dphp-internals&m=3D121999390109071&w=3D2 seems to >> address this issue but it's not present in 5.3 or later releases. >> >> Very similar deadlock but with time() instead of free(), >> https://bugs.php.net/bug.php?id=3D31749 > > Are you sure it's with time() ? I do see a free() in that call stack (and= no > time), > as I would expect, as time() is required by POSIX.1-2004 to be > Async-signal-safe. time() refers to https://bugs.php.net/bug.php?id=3D31749, You are right this deadlock is related to free() >> Current php also uses free() in php_error_cb() and external >> destructors in list_entry_destructor() aren't protected by >> HANDLE_BLOCK_INTERRUPTIONS() (which seems to be a noop in fastcgi >> mode), so I suspect 5.5 may also contain this deadlock. >> >> main/main.c >> php_error_cb() >> 835 if (display) { >> 836 if (PG(last_error_message)) { >> 837 free(PG(last_error_message)); >> ... ^^^^^^ deadlock if previous free was >> interrupted by a timeout signal >> 845 PG(last_error_type) =3D type; >> 846 PG(last_error_message) =3D strdup(buffer); >> >> I'm thinking about "fixing" this by leaking memory pointed by >> PG(last_error_message) if php called when a timeout is pending >> (timeouts are usually very rare, php processes will eventually be >> restarted so this little memory waste won't have time to make any >> impact. >> >> Is this issue fixed in modern php ? If so I would be grateful for some >> information about the way it was done. This would save me a lot of >> time trying to trigger >> a non existing confition. >> >> I will try to reproduce this in a modern version of php. > > It probably isn't. PG(last_error_message) is only modified in main.c, I > would try to use a separate arena for PG(last_error_message) and > PG(last_error_file). For instance it could be a static buffer reused duri= ng > the whole execution and extended with mmap(2) in the unlikely case it tur= ns > out to be too small. I suspect it would also make the error handler faste= r, > as it would avoid the free() + malloc() thank You I didn't notice that it is used only there, i will try to use a static buffer. I managed to produce a segfault on current php version (php heap corruption), bug report https://bugs.php.net/bug.php?id=3D65674 spprintf() allocating memory is also not safe. I will try to fix this by using a static buffer. Thanks, Michal Grzedzicki