persistent memory management

php.internals

Alexey Zakhlestin

19 years ago
Hi. I am trying to make my first php extension :) I am sorry, if the question would be too newbiesh, but I just couldn't find a more correct place to ask here is the code: http://loccache.googlecode.com/svn/trunk/loccache.c I am trying to do the following: at the minit-phase I am allocating a persistent HashTable extension has 4 funcitons: * loc_set($namespace, $varname, $value); // stores $value * loc_get($namespace, $varname) // returns $value from storage * loc_isset($namespace, $varname) // returns bool * loc_unset($namespace, $varname) // removes varname from storage during loc_set, I chech if there is "$namespace" item in my persistent hashtable, and if there isn't, I create it as a child hashtable $varname is a key in that second HashTable and $value is the value something like: $big_persistent_hash = array( $namespace => array( $varname => $value ) ); extension build and even tends to work... kinda.. unfortunately, persistent values are not too persistent in my case, and i keep getting memory errors. I would be grateful for any help. the source code is not too big :)

Andrey Hristov

19 years ago
Hi, Alexey Zakhlestin wrote:
> Hi. > > I am trying to make my first php extension :) > I am sorry, if the question would be too newbiesh, but I just couldn't > find a more correct place to ask > > here is the code: > http://loccache.googlecode.com/svn/trunk/loccache.c > > I am trying to do the following: > at the minit-phase I am allocating a persistent HashTable > extension has 4 funcitons: > * loc_set($namespace, $varname, $value); // stores $value > * loc_get($namespace, $varname) // returns $value from storage > * loc_isset($namespace, $varname) // returns bool > * loc_unset($namespace, $varname) // removes varname from storage > during loc_set, I chech if there is "$namespace" item in my persistent > hashtable, and if there isn't, I create it as a child hashtable > $varname is a key in that second HashTable and $value is the value > > something like: > $big_persistent_hash = array( > $namespace => array( > $varname => $value > ) > ); > > extension build and even tends to work... kinda.. > > unfortunately, persistent values are not too persistent in my case, and > i keep getting memory errors. > I would be grateful for any help. the source code is not too big :)
Tried running the web server under memory checker like valgrind? Maybe instead of peamlloc() just do malloc() Andrey

Alexey Zakhlestin

19 years ago
On 12/3/06, Andrey Hristov <php@hristov.com> wrote:
> Tried running the web server under memory checker like valgrind?
Valgrind is linux only.. But I guess I still have one linux box.. I will give it a try.
> Maybe instead of peamlloc() just do malloc()
well.. I can do that for clarity, but zend_alloc.h has this: #define pemalloc(size, persistent) ((persistent)?malloc(size):emalloc(size)) so, it basically maps
-- Alexey Zakhlestin http://blog.milkfarmsoft.com/

Alexey Zakhlestin

19 years ago
Here is valgrind output. It definitely shows that there is a problem, but I still can't guess where it is. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ==25913== Invalid read of size 4 ==25913== at 0x82AC068: zend_hash_exists (in /usr/bin/php5) ==25913== by 0x404EE42: zif_loc_isset (loccache.c:147) ==25913== by 0x82CF6CE: (within /usr/bin/php5) ==25913== by 0x82BF0C7: execute (in /usr/bin/php5) ==25913== by 0x82A029B: zend_execute_scripts (in /usr/bin/php5) ==25913== by 0x825B6E1: php_execute_script (in /usr/bin/php5) ==25913== by 0x832F43D: main (in /usr/bin/php5) ==25913== Address 0x4B00B90 is 0 bytes after a block of size 40 alloc'd ==25913== at 0x401C38B: malloc (vg_replace_malloc.c:149) ==25913== by 0x82AB82A: _zend_hash_add_or_update (in /usr/bin/php5) ==25913== by 0x404EDB0: zif_loc_set (loccache.c:86) ==25913== by 0x82CF6CE: (within /usr/bin/php5) ==25913== by 0x82BF0C7: execute (in /usr/bin/php5) ==25913== by 0x82A029B: zend_execute_scripts (in /usr/bin/php5) ==25913== by 0x825B6E1: php_execute_script (in /usr/bin/php5) ==25913== by 0x832F43D: main (in /usr/bin/php5) ==25913== ==25913== Invalid read of size 4 ==25913== at 0x82AC06D: zend_hash_exists (in /usr/bin/php5) ==25913== by 0x404EE42: zif_loc_isset (loccache.c:147) ==25913== by 0x82CF6CE: (within /usr/bin/php5) ==25913== by 0x82BF0C7: execute (in /usr/bin/php5) ==25913== by 0x82A029B: zend_execute_scripts (in /usr/bin/php5) ==25913== by 0x825B6E1: php_execute_script (in /usr/bin/php5) ==25913== by 0x832F43D: main (in /usr/bin/php5) ==25913== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==25913== ==25913== Process terminating with default action of signal 11 (SIGSEGV) ==25913== Access not within mapped region at address 0x0 ==25913== at 0x82AC06D: zend_hash_exists (in /usr/bin/php5) ==25913== by 0x404EE42: zif_loc_isset (loccache.c:147) ==25913== by 0x82CF6CE: (within /usr/bin/php5) ==25913== by 0x82BF0C7: execute (in /usr/bin/php5) ==25913== by 0x82A029B: zend_execute_scripts (in /usr/bin/php5) ==25913== by 0x825B6E1: php_execute_script (in /usr/bin/php5) ==25913== by 0x832F43D: main (in /usr/bin/php5) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-- Alexey Zakhlestin http://blog.milkfarmsoft.com/

Alexey Zakhlestin

19 years ago
And here is the command I used: valgrind `which php` -n tests/3.php

Antony Dovgal

19 years ago
On 12/03/2006 09:29 PM, Alexey Zakhlestin wrote:
> Here is valgrind output. It definitely shows that there is a problem, > but I still can't guess where it is. > > =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > ==25913== Invalid read of size 4 > ==25913== at 0x82AC068: zend_hash_exists (in /usr/bin/php5) > ==25913== by 0x404EE42: zif_loc_isset (loccache.c:147) > ==25913== by 0x82CF6CE: (within /usr/bin/php5) > ==25913== by 0x82BF0C7: execute (in /usr/bin/php5) > ==25913== by 0x82A029B: zend_execute_scripts (in /usr/bin/php5) > ==25913== by 0x825B6E1: php_execute_script (in /usr/bin/php5) > ==25913== by 0x832F43D: main (in /usr/bin/php5)
--enable-debug would help to get some more info.
-- Wbr, Antony Dovgal

Alexey Zakhlestin

19 years ago
I know. but it will be very problematic to build debug-version of php there. and that is the only linux machine around. :-( On 12/3/06, Antony Dovgal <antony@zend.com> wrote:
> On 12/03/2006 09:29 PM, Alexey Zakhlestin wrote: > > Here is valgrind output. It definitely shows that there is a problem, > > but I still can't guess where it is. > > > > =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > ==25913== Invalid read of size 4 > > ==25913== at 0x82AC068: zend_hash_exists (in /usr/bin/php5) > > ==25913== by 0x404EE42: zif_loc_isset (loccache.c:147) > > ==25913== by 0x82CF6CE: (within /usr/bin/php5) > > ==25913== by 0x82BF0C7: execute (in /usr/bin/php5) > > ==25913== by 0x82A029B: zend_execute_scripts (in /usr/bin/php5) > > ==25913== by 0x825B6E1: php_execute_script (in /usr/bin/php5) > > ==25913== by 0x832F43D: main (in /usr/bin/php5) > > --enable-debug would help to get some more info. > > -- > Wbr, > Antony Dovgal >
-- Alexey Zakhlestin http://blog.milkfarmsoft.com/

Alexey Zakhlestin

19 years ago
I believe, I sorted out most of the issues. Now, the last problem: what is the official way to deep-copy non-persistent zval into persistent zval? I expected zval_copy_ctor to have a flag. Unfortunately, it doesn't have one. the way I see it: void zval_copy_ctor(zval *value, zend_bool persistent) such declaration would break compatibility, so, probably, there's a need to introduce zval_pcopy_ctor(zval *value, zend_bool persistent) { //… } and #define zval_copy_ctor(v) zval_pcopy_ctor(v, 0) similiar to how it is done with *alloc functions -- Alexey Zakhlestin http://blog.milkfarmsoft.com/

Antony Dovgal

19 years ago
On 12/02/2006 11:07 PM, Alexey Zakhlestin wrote:
> Hi. > > I am trying to make my first php extension :) > I am sorry, if the question would be too newbiesh, but I just couldn't > find a more correct place to ask
No need to use _exists here, zend_hash_find() returns FAILURE if it's failed to find the value. You're doing the hash lookup twice here: if (!zend_hash_exists(ht, ns_name, ns_len + 1)) { return NULL; } zend_hash_find(ht, ns_name, ns_len + 1, (void**)&res); Just this is enough: if (zend_hash_find() == SUCCESS) { return res; } return NULL; And Andrey is right, valgrind is priceless when it comes to debugging memory errors.
-- Wbr, Antony Dovgal

Alexey Zakhlestin

19 years ago
thanks. fixed it in subversion On 12/3/06, Antony Dovgal <antony@zend.com> wrote:
> No need to use _exists here, zend_hash_find() returns FAILURE if it's failed to find the value. > You're doing the hash lookup twice here: > > if (!zend_hash_exists(ht, ns_name, ns_len + 1)) { > return NULL; > } > > zend_hash_find(ht, ns_name, ns_len + 1, (void**)&res); > > Just this is enough: > > if (zend_hash_find() == SUCCESS) { > return res; > } > return NULL; > > And Andrey is right, valgrind is priceless when it comes to debugging memory errors. > > -- > Wbr, > Antony Dovgal >
-- Alexey Zakhlestin http://blog.milkfarmsoft.com/