Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:55384 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 70001 invoked from network); 12 Sep 2011 12:34:41 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 12 Sep 2011 12:34:41 -0000 Authentication-Results: pb1.pair.com smtp.mail=flavius.as@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=flavius.as@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.215.45 as permitted sender) X-PHP-List-Original-Sender: flavius.as@gmail.com X-Host-Fingerprint: 209.85.215.45 mail-ew0-f45.google.com Received: from [209.85.215.45] ([209.85.215.45:51691] helo=mail-ew0-f45.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 50/A0-62506-F5CFD6E4 for ; Mon, 12 Sep 2011 08:34:40 -0400 Received: by ewy24 with SMTP id 24so2049167ewy.18 for ; Mon, 12 Sep 2011 05:34:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=/421a9BaPBWBmY8nRvPM+1vomqU8LkkDlrH8uFOtvQQ=; b=sBhLVt8jObuVhlqDR1oAl2pNOd7+VAhlfZ9A43P4odt488NZbSpV72LFwNFjDCFHmc WpVlW/ykLUuUDH5bq8UfWZPDgkBmQY/9gZfyn8b4B1pzc7YmSh1mWNau/iUJOadOIIiK DIFjwgzKA5BqM56jPhsXmSKNWnCUXn5OrZ1bc= Received: by 10.223.48.141 with SMTP id r13mr175133faf.115.1315830832856; Mon, 12 Sep 2011 05:33:52 -0700 (PDT) Received: from [192.168.2.3] (chello080109207086.1.graz.surfer.at [80.109.207.86]) by mx.google.com with ESMTPS id d22sm8891865fak.10.2011.09.12.05.33.51 (version=SSLv3 cipher=OTHER); Mon, 12 Sep 2011 05:33:51 -0700 (PDT) Message-ID: <4E6DFBEF.2050204@gmail.com> Date: Mon, 12 Sep 2011 14:32:47 +0200 User-Agent: I am harmful. Fear me please :-) Mnenhy/0.7.6.666 MIME-Version: 1.0 To: Dmitry Stogov CC: flavius@php.net, internals@lists.php.net References: <4E6C8CF6.3080509@php.net> <4E6DAA72.4070808@zend.com> In-Reply-To: <4E6DAA72.4070808@zend.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] ZE2 broken by newer gcc From: flavius.as@gmail.com (Flavius Aspra) On 09/12/2011 08:45 AM, Dmitry Stogov wrote: > Hi Flavius, > > Unfortunately, the proposed fix is wrong. > It changes the operators precedence and it's definitely wrong. > I suppose the crash caused by side effect of some other bug. > > Try to run the same script with valgrind. > > Thanks. Dmitry. > > Please test the following POC with gcc 4.6.1 on x64 first (perhaps slightly earlier versions behave the same, but this one is for sure), the dump_container() function simulates what the ZE does in zend_call_function() and many other places. You can also look at what valgrind says too and compare. I haven't dwelt on it at the ASM level, but certainly something has changed. My bet is that GCC has had wrong the operator precedence, and now they've fixed it. I'm not speaking from my imagination, I'm speaking from what I've seen and what I've tested, in practice. No theory. In the "meta" extension I am calling zend_call_function(), which is how I've discovered this. The POC resembles what is happenning as close as possible. #include #include #define NUMS 10 /* a "zval" */ typedef struct _foo { char *t; int i; } foo; /* a "zend_fcall_info" */ typedef struct _foo_container { foo ***foos; } container; foo** init_foos(void) { foo** f, *f2; int i; f = malloc(sizeof(foo*)*NUMS); for(i=0; i < NUMS; i++) { f2 = malloc(sizeof(foo)); printf("allocated %p ", f2); f[i] = f2; f[i]->i = i*11+1; printf("with value %d\n", i*11+1); } return f; } void dump_container(container *c) { int i; for(i=0; i < NUMS; i++) { //working: printf("foo[%d]=%d at %p\n", i, (*c->foos)[i]->i, (*c->foos)[i]); //similar to ZE, crashing (not at i=0, but on my machine at i=1 it already delivers garbage, at i=2 it finnaly crashes //if you're lucky, increase NUMS at the top printf("foo[%d]=%d at %p\n", i, (*c->foos)[i]->i, *c->foos[i]); } } int main(void) { container c; foo **foos; foos = init_foos(); c.foos = &foos; int i; for(i=0; i < NUMS; i++) { printf("%d %d at %p\n", i, foos[i]->i, foos[i]); } printf("------------------\n"); dump_container(&c); free(foos); return EXIT_SUCCESS; } -- What I cannot create, I do not understand. -- Feynman