creating nested arrays from C
| From: | Dan Libby | Date: | Tue, 12 Oct 1999 05:31:58 +0000 |
| Subject: | creating nested arrays from C | ||
| Groups: | php.version4 | ||
| Request: | Send a blank email to php-version4+get-5496@lists.php.net to get a copy of this message | ||
Hi, I'm trying to create nested arrays (based on XML input parsed via Expat)
in a C extension. Based on examples in the other code, I'm adding
the arrays with zend_hash_update(). However, I've noticed some major
weirdnesses. The same weirdnesses do not happen when I create
multi-dimensional code via the php language, so I know it is at least
_possible_. I would appreciate it if someone could point me
in the right direction. thx.
-dan
The weirdness:
* Depending on the key used, I sometimes get segfaults in
zend_hash_add_or_update ( zend_hash.c:136). It looks like it
trying to use a value from the wrong hash bucket. Note that this
is *after* my stuff has been executed and is no longer on the
stack. Here is the stack:
o Starting program: /usr/local/httpd/bin/httpd -X
Program received signal SIGSEGV, Segmentation fault.
0x80af753 in zend_hash_add_or_update (ht=0x81ab420,
arKey=0x81ab4d8 "burgerking1", nKeyLength=12,
pData=0xbfffe3a4,
nDataSize=4, pDest=0x0, flag=1) at zend_hash.c:136
136 if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
(gdb) where
#0 0x80af753 in zend_hash_add_or_update (ht=0x81ab420,
arKey=0x81ab4d8 "burgerking1", nKeyLength=12,
pData=0xbfffe3a4,
nDataSize=4, pDest=0x0, flag=1) at zend_hash.c:136
#1 0x80b0a7d in zend_hash_copy (target=0x81ab420,
source=0x81ab270, pCopyConstructor=0x80ad784 <zval_add_ref>,
tmp=0xbfffe3a4, size=4) at zend_hash.c:833
#2 0x80ad896 in zval_copy_ctor (zvalue=0x81b9ae8) at
zend_variables.c:142
#3 0x80b6572 in execute (op_array=0x81a2408) at
zend_execute.c:1554
#4 0x80b621f in execute (op_array=0x81a2408) at
zend_execute.c:1448
#5 0x80b621f in execute (op_array=0x81a1ac8) at
zend_execute.c:1448
#6 0x80b700c in execute (op_array=0x819c3e0) at
zend_execute.c:1835
#7 0x80b700c in execute (op_array=0x819afd0) at
zend_execute.c:1835
#8 0x80b700c in execute (op_array=0x81998f8) at
zend_execute.c:1835
#9 0x8078760 in php_execute_script (primary_file=0xbffff8c0)
at main.c:1175
#10 0x80787d9 in apache_php_module_main (r=0x818f294,
filename=0x81906f0 "/usr/www/index.html", fd=21,
display_source_mode=0)
at main.c:1218
#11 0x8077020 in send_php ()
#12 0x8077068 in send_parsed_php ()
#13 0x80bc523 in ap_invoke_handler ()
#14 0x80cf819 in process_request_internal ()
#15 0x80cfc38 in ap_internal_redirect ()
#16 0x807083d in handle_dir ()
#17 0x80bc523 in ap_invoke_handler ()
#18 0x80cf819 in process_request_internal ()
#19 0x80cf87c in ap_process_request ()
#20 0x80c723e in child_main ()
#21 0x80c73cc in make_child ()
#22 0x80c7529 in startup_children ()
---Type <return> to continue, or q <return> to quit---
#23 0x80c7b56 in standalone_main ()
#24 0x80c82d3 in main ()
#25 0x400fbcb3 in __libc_start_main (main=0x80c7f9c <main>,
argc=2, argv=0xbffffaf4, init=0x805bb60 <_init>,
fini=0x810100c <_fini>, rtld_fini=0x4000a350 <_dl_fini>,
stack_end=0xbffffaec) at ../sysdeps/generic/libc-start.c:78
(gdb)
* Even when no crashes occur (IE, I choose a key that doesn't cause a
crash, or use indexes instead), it sometimes "loses" the
sub-array. By this, I mean that if I do a list($key, $val) =
each($my_array), then $key will have a value, and $val will not. I
have a recursive php function that walks the tree and prints all
the keys and values, and one time I will get this output:
o stuff => Array
burgerking =>
0 => BAR
1 => 10
2 => 3.45
0 => THAT
and the next I will get:
o stuff => Array
burgerking => Array
0 => lettuce, pickles, onion, tomatoes
0 => BAR
1 => 10
2 => 3.45
0 => THAT
Running the same tree-walking function on a nested array
created via the php language works every single time, no
exceptions.
* I've also tried some of the other macros, eg
zend_hash_update_ptr(), with the same result.
I've checked my code very closely for memory errors, etc. I do not
believe there to be any. In fact, I created the following very simple
test case which exhibits the same random behavior:
int i;
pval* array = return_value;
pval* array2;
array_init(array);
for (i=0; i < 15; i++) {
array2 = emalloc(sizeof(pval));
array_init(array2);
add_long(array, "depth", i);
add_string(array2, "hi", "there", 1);
zend_hash_update(array, "sub_array", strlen("sub_array")+1, (void
*) &array2, sizeof(pval *), NULL);
array = array2;
}
return;