Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:64397 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 2637 invoked from network); 21 Dec 2012 06:15:32 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 21 Dec 2012 06:15:32 -0000 Authentication-Results: pb1.pair.com header.from=php@bof.de; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=brianofish@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.83.42 as permitted sender) X-PHP-List-Original-Sender: brianofish@gmail.com X-Host-Fingerprint: 74.125.83.42 mail-ee0-f42.google.com Received: from [74.125.83.42] ([74.125.83.42:55019] helo=mail-ee0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A4/D1-20281-08EF3D05 for ; Fri, 21 Dec 2012 01:15:29 -0500 Received: by mail-ee0-f42.google.com with SMTP id c41so2129977eek.15 for ; Thu, 20 Dec 2012 22:15:26 -0800 (PST) X-Received: by 10.14.173.65 with SMTP id u41mr29322143eel.13.1356070526003; Thu, 20 Dec 2012 22:15:26 -0800 (PST) Received: from rofl.localnet ([213.135.15.139]) by mx.google.com with ESMTPS id f49sm19673298eep.12.2012.12.20.22.15.24 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 20 Dec 2012 22:15:25 -0800 (PST) To: internals@lists.php.net Cc: Stas Malyshev , Jani Ollikainen Date: Fri, 21 Dec 2012 07:15:22 +0100 Message-ID: <5952719.MaJMSR3yMW@rofl> User-Agent: KMail/4.9.4 (Linux/3.6.11-k10-bof; KDE/4.9.4; x86_64; ; ) In-Reply-To: <50D35BA0.5010301@sugarcrm.com> References: <50D1D9B9.4060505@mmd.net> <50D30656.8090207@mmd.net> <50D35BA0.5010301@sugarcrm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Subject: Re: [PHP-DEV] Crashes in lex_scan at Zend/zend_language_scanner.c / BUG #52752 From: php@bof.de (Patrick Schaaf) On Thursday 20 December 2012 10:40:32 Stas Malyshev wrote: > Hi! > > > > if ($argv[1] > 0) { > > > > while ($argv[1]--) file_put_contents('test.tpl', " > > > #".str_repeat('A', mt_rand(4000, 5000))." ?>\n", LOCK_EX); > > } else { > > > > $p2 = popen("sapi/cli/php -n test3.php 100", "r"); > > while (1) include 'test.tpl'; > > > > } > > ?> > > Yes, I can now reproduce this on my machine too. Not sure what I did > wrong last time, but now I get bus error. I suspect there's some race > condition between mmap and rewriting the file that creates the problem. > The error seems to happen at offset exactly 0x1000 from the start of the > map, which leads me to thinking that maybe the problem is that the page > needs to be loaded, but since the file is not there, being overwritten, > it can not be loaded anymore. Is include supposed to take a LOCK_EX somehow? I can neither see that in php- src (5.4.9) nor APC-trunk, doing a cursory grepping. APC takes a LOCK_EX in exactly one place, apc_bin_dumpfile(), which does not look to me like it's related to "include". The usage there is fishy anyway, not exactly sure, but I think the open that happens before taking LOCK_EX, will have truncated the file already, leading to the same type of problem as discussed above wrt concurrent readers. The only chance to get the above piece of code to work reliably in theory, would be for the "include" to take a LOCK_EX before looking at anything related to the file structure, including the stat call that determines how much to mmap. The prudent approach, which should avoid the problem altogether and not need any LOCK_EX, dictates to ALWAYS write a temporary file (new inode), then rename it when the write completely succeeds. Otherwise any reader, like "include", runs the chance of seeing a partially written file, and even without include using mmap internally, syntax errors would happen from time to time. So, my conclusion would be that it is the code snippet above, and not any part of PHP or the kernel, that is at fault. best regards Patrick