Hi
I think I've found a bug in the engine, and I think it occures only with
the latest gcc ("gcc version 4.6.1 20110819 (prerelease)"), since it
used to work with earlier versions.
For example line 867
http://lxr.php.net/opengrok/xref/PHP_5_3/Zend/zend_execute_API.c#867
should be
&& PZVAL_IS_REF((*fci->params)[i])) {
that's what has worked for me at least. Otherwise it ends with a segfault.
It may also be gcc breaking BC. So I'm not sure whose "fault" it is, but
I think [] takes precedence over * in the C specification.
Could someone please verify this issue?
Regards,
Flavius
What I cannot create, I do not understand. -- Feynman
Flavius Aspra wrote:
Hi
I think I've found a bug in the engine, and I think it occures only
with the latest gcc ("gcc version 4.6.1 20110819 (prerelease)"), since
it used to work with earlier versions.For example line 867
http://lxr.php.net/opengrok/xref/PHP_5_3/Zend/zend_execute_API.c#867
should be&& PZVAL_IS_REF((*fci->params)[i])) {
that's what has worked for me at least. Otherwise it ends with a
segfault.It may also be gcc breaking BC. So I'm not sure whose "fault" it is,
but I think [] takes precedence over * in the C specification.Could someone please verify this issue?
Regards,
Flavius
[] does take precedence over *
In this case the macro expansion would also be relevant, but it looks
like it would end up as a simple zval_isref_p
http://lxr.php.net/opengrok/s?refs=zval_isref_p&project=PHP_5_3((*fci->params)[i]);
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.
Hi
I think I've found a bug in the engine, and I think it occures only with
the latest gcc ("gcc version 4.6.1 20110819 (prerelease)"), since it
used to work with earlier versions.For example line 867
http://lxr.php.net/opengrok/xref/PHP_5_3/Zend/zend_execute_API.c#867
should be&& PZVAL_IS_REF((*fci->params)[i])) {
that's what has worked for me at least. Otherwise it ends with a segfault.
It may also be gcc breaking BC. So I'm not sure whose "fault" it is, but
I think [] takes precedence over * in the C specification.Could someone please verify this issue?
Regards,
Flavius
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 <stdio.h>
#include <stdlib.h>
#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 = i11+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