Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:69123 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 67952 invoked from network); 13 Sep 2013 20:11:01 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 13 Sep 2013 20:11:01 -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.215.42 as permitted sender) X-PHP-List-Original-Sender: lazy404@gmail.com X-Host-Fingerprint: 209.85.215.42 mail-la0-f42.google.com Received: from [209.85.215.42] ([209.85.215.42:35035] helo=mail-la0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B1/64-40600-35173325 for ; Fri, 13 Sep 2013 16:11:00 -0400 Received: by mail-la0-f42.google.com with SMTP id ep20so1445396lab.1 for ; Fri, 13 Sep 2013 13:10:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=hx8Ic7FbsFrNjXhvSB2Y364cna0MlkrCdOg2AqhxU9s=; b=i4WwKCdnW75DlUo1yzoibIbEyIizltloWwXqzWpm0gxyhOyY+EyXgLHA1BuYq4o6eF OAQMcKFmBQ7SYs7tc8SKJTCgNAiEKD32otmdFYa1KJOC3mkExPCVQMULenIknBtQz1RS hiuKUkXnM5VbOM+lNuph5sexurhcv43W8AM5Fvnq8MNmJhrpBz/8v0Yy6EEc6ylq/Awl 4JdJQwAukRbkAKWVmKaJkIoBPvGjUc3V7mF5uww4Y+xNeHASSNCSV/KcoHaFGzg8WqB4 uCS0V8B3JgySl3DT9+UTWnz/NiGH+nZqm6cz0m1iLEJmC4rMbS/3wkdU5g3n1cBJ0tF4 AmYw== MIME-Version: 1.0 X-Received: by 10.152.121.3 with SMTP id lg3mr2906731lab.33.1379103056950; Fri, 13 Sep 2013 13:10:56 -0700 (PDT) Received: by 10.152.134.233 with HTTP; Fri, 13 Sep 2013 13:10:56 -0700 (PDT) Date: Fri, 13 Sep 2013 22:10:56 +0200 Message-ID: To: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1 Subject: free deadlock in timeout signal handler From: lazy404@gmail.com (Lazy) Hello internals, I'm trying to fix deadlock in an ancient php 5.2.17, php hangs on internal libc lock. Backtrace follows #0 0x0000030b555024cb in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x0000030b554986b8 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x0000030b55496aa1 in free () from /lib/x86_64-linux-gnu/libc.so.6 #3 0x0000000000734989 in php_error_cb (type=1, error_filename=0x100013bbf18 "xxx", error_lineno=7, format=, args=) at main/main.c:837 #4 0x0000000000623e15 in soap_error_handler (error_num=1, error_filename=0x100013bbf18 "/class.cbase.php", error_lineno=7, format=0xa749c0 "Maximum execution time of %d second%s exceeded", args=0x3a2de4d3fa0) at //ext/soap/soap.c:2115 #5 0x0000000000777066 in zend_error (type=1, format=0xa749c0 "Maximum execution time of %d second%s exceeded") at /Zend/zend.c:976 #6 #7 0x0000030b55493302 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #8 0x0000030b55496aac in free () from /lib/x86_64-linux-gnu/libc.so.6 #9 0x0000030b57f817c5 in free_root () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 #10 0x0000030b57f65a34 in free_rows () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 #11 0x0000030b57f6620d in mysql_free_result () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 #12 0x000000000058cd1c in _free_mysql_result (rsrc=) at ext/mysql/php_mysql.c:275 #13 0x000000000078340e in list_entry_destructor (ptr=0x5074760) at Zend/zend_list.c:184 From my understanding free is not safe to use in a signal handler, and this seems to be the issue here. http://marc.info/?l=php-internals&m=121999390109071&w=2 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=31749 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) = type; 846 PG(last_error_message) = 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. Thanks, Michal Grzedzicki