Hello,
I'm trying to create an ArrayList as an extension. I'm currently
implementing ArrayList::contains(mixed $element) but I'm running into a
blocking issue.
It's currently causing a segfault when you call contains. I've tried to
track down what I'm doing wrong, but I've had no luck with it.
When running gdb this is what I get:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x00000000000000000x00000001005812ca in
_zend_is_inconsistent
/* {{{ proto public boolean ArrayList::contain(mixed $element[, boolean
strict])
Returns true if this list contains the specified element. */
ZEND_METHOD(arraymap_class, contains) {
zval element;
zend_bool strict = 0; / strict comparison or not */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &element,
&strict) == FAILURE) {
RETURN_FALSE;
}
zval *this = getThis();
arraylist_object *intern;
intern = (arraylist_object *) zend_object_store_get_object(this
TSRMLS_CC);
/* Don't use "ht" as a variable, it's already being used. All ZEND_METHOD
have "ht" defined. */
HashTable *hash_table = Z_ARRVAL_P(intern->elements);
HashPosition pos;
zval *current;
zval res; / comparison result */
int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) =
is_equal_function;
if (strict) {
is_equal_func = is_identical_function;
}
zend_hash_internal_pointer_reset_ex(hash_table, &pos);
while (zend_hash_get_current_data_ex(hash_table, (void **)¤t, &pos)
== SUCCESS) {
is_equal_func(&res, element, *current TSRMLS_CC);
if (Z_LVAL(res)) {
RETURN_TRUE;
}
zend_hash_move_forward_ex(hash_table, &pos);
}
RETURN_FALSE;
}
I can't seem to spot any errors with this implementation. The next thing I
thought that could be wrong is how I'm creating elements pointer, but that
seems correct too:
static zend_object_value create_arraylist_object(zend_class_entry ce
TSRMLS_DC) / {{{ */
{
zend_object_value retval;
arraylist_object *intern;
intern = emalloc(sizeof(arraylist_object));
intern->size = 0;
zend_object_std_init(&intern->std, ce TSRMLS_CC);
ALLOC_INIT_ZVAL(intern->elements);
array_init(intern->elements);
intern->std.ce = ce;
object_properties_init(&intern->std, ce);
retval.handle = zend_objects_store_put(intern, NULL,
destroy_arraylist_object, NULL
TSRMLS_CC);
retval.handlers = &arraylist_object_handlers;
return retval;
}
/* }}} */
I'm not getting any compilation errors or any type of warnings. Everything
seems to be glueing itself correctly.
I'm hoping someone can see what I'm doing wrong so that I can move forward
with this.
thanks!
Hi:
you can core dump the backtrace, then exam the related hash table to
find out what's going wrong there.
and some maybe un-relevant issues:
- plz put all var declarations at the begining of a block (C89)
- do not use "this" keyword as variable name (it's C++ keyword)
thanks
On Tue, Apr 17, 2012 at 2:12 PM, Yader Hernandez
yader.hernandez@gmail.com wrote:
Hello,
I'm trying to create an ArrayList as an extension. I'm currently
implementing ArrayList::contains(mixed $element) but I'm running into a
blocking issue.It's currently causing a segfault when you call contains. I've tried to
track down what I'm doing wrong, but I've had no luck with it.When running gdb this is what I get:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x00000000000000000x00000001005812ca in
_zend_is_inconsistent/* {{{ proto public boolean ArrayList::contain(mixed $element[, boolean
strict])
Returns true if this list contains the specified element. */
ZEND_METHOD(arraymap_class, contains) {
zval element;
zend_bool strict = 0; / strict comparison or not */if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &element,
&strict) == FAILURE) {
RETURN_FALSE;
}zval *this = getThis();
arraylist_object *intern;intern = (arraylist_object *) zend_object_store_get_object(this
TSRMLS_CC);/* Don't use "ht" as a variable, it's already being used. All ZEND_METHOD
have "ht" defined. */
HashTable *hash_table = Z_ARRVAL_P(intern->elements);
HashPosition pos;
zval *current;
zval res; / comparison result */int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) =
is_equal_function;if (strict) {
is_equal_func = is_identical_function;
}zend_hash_internal_pointer_reset_ex(hash_table, &pos);
while (zend_hash_get_current_data_ex(hash_table, (void **)¤t, &pos)
== SUCCESS) {
is_equal_func(&res, element, *current TSRMLS_CC);if (Z_LVAL(res)) {
RETURN_TRUE;
}zend_hash_move_forward_ex(hash_table, &pos);
}RETURN_FALSE;
}I can't seem to spot any errors with this implementation. The next thing I
thought that could be wrong is how I'm creating elements pointer, but that
seems correct too:static zend_object_value create_arraylist_object(zend_class_entry ce
TSRMLS_DC) / {{{ */
{
zend_object_value retval;
arraylist_object *intern;intern = emalloc(sizeof(arraylist_object));
intern->size = 0;
zend_object_std_init(&intern->std, ce TSRMLS_CC);
ALLOC_INIT_ZVAL(intern->elements);
array_init(intern->elements);intern->std.ce = ce;
object_properties_init(&intern->std, ce);
retval.handle = zend_objects_store_put(intern, NULL,
destroy_arraylist_object,NULL
TSRMLS_CC);
retval.handlers = &arraylist_object_handlers;return retval;
}
/* }}} */I'm not getting any compilation errors or any type of warnings. Everything
seems to be glueing itself correctly.I'm hoping someone can see what I'm doing wrong so that I can move forward
with this.thanks!
--
Laruence Xinchen Hui
http://www.laruence.com/
Hi:
you can core dump the backtrace, then exam the related hash table to
find out what's going wrong there.
So the problem doesn't seem to be with contains() at all. The problem is
actually coming from another method I implemented called
ArrayList::append(mixed $element). I figured it out by calling contains
first and I noticed it didn't cause a segfault. appends() seems rather
trivial but I guess I was wrong:
/* {{{ proto public boolean ArrayList::append(mixed $element)
Add an element to the end of the list */
ZEND_METHOD(arraymap_class, append) {
zval *object = getThis();
zval *element;
arraylist_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &element) ==
FAILURE) {
RETURN_FALSE;
}
intern = (arraylist_object *) zend_object_store_get_object(object
TSRMLS_CC);
if (add_next_index_zval(intern->elements, element) == SUCCESS) {
Z_ADDREF_P(element); /* increases ref count */
intern->size++;
RETURN_TRUE;
}
RETURN_FALSE;
}
This method returns true, as expected.
and some maybe un-relevant issues:
- plz put all var declarations at the begining of a block (C89)
- do not use "this" keyword as variable name (it's C++ keyword)
fixed.
thanks
On Tue, Apr 17, 2012 at 2:12 PM, Yader Hernandez
yader.hernandez@gmail.com wrote:Hello,
I'm trying to create an ArrayList as an extension. I'm currently
implementing ArrayList::contains(mixed $element) but I'm running into a
blocking issue.It's currently causing a segfault when you call contains. I've tried to
track down what I'm doing wrong, but I've had no luck with it.When running gdb this is what I get:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x00000000000000000x00000001005812ca in
_zend_is_inconsistent/* {{{ proto public boolean ArrayList::contain(mixed $element[, boolean
strict])
Returns true if this list contains the specified element. */
ZEND_METHOD(arraymap_class, contains) {
zval element;
zend_bool strict = 0; / strict comparison or not */if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &element,
&strict) == FAILURE) {
RETURN_FALSE;
}zval *this = getThis();
arraylist_object *intern;intern = (arraylist_object *) zend_object_store_get_object(this
TSRMLS_CC);/* Don't use "ht" as a variable, it's already being used. All
ZEND_METHOD
have "ht" defined. */
HashTable *hash_table = Z_ARRVAL_P(intern->elements);
HashPosition pos;
zval *current;
zval res; / comparison result */int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) =
is_equal_function;if (strict) {
is_equal_func = is_identical_function;
}zend_hash_internal_pointer_reset_ex(hash_table, &pos);
while (zend_hash_get_current_data_ex(hash_table, (void **)¤t,
&pos)
== SUCCESS) {
is_equal_func(&res, element, *current TSRMLS_CC);if (Z_LVAL(res)) {
RETURN_TRUE;
}zend_hash_move_forward_ex(hash_table, &pos);
}RETURN_FALSE;
}I can't seem to spot any errors with this implementation. The next thing
I
thought that could be wrong is how I'm creating elements pointer, but
that
seems correct too:static zend_object_value create_arraylist_object(zend_class_entry ce
TSRMLS_DC) / {{{ */
{
zend_object_value retval;
arraylist_object *intern;intern = emalloc(sizeof(arraylist_object));
intern->size = 0;
zend_object_std_init(&intern->std, ce TSRMLS_CC);
ALLOC_INIT_ZVAL(intern->elements);
array_init(intern->elements);intern->std.ce = ce;
object_properties_init(&intern->std, ce);
retval.handle = zend_objects_store_put(intern, NULL,
destroy_arraylist_object,NULL
TSRMLS_CC);
retval.handlers = &arraylist_object_handlers;return retval;
}
/* }}} */I'm not getting any compilation errors or any type of warnings.
Everything
seems to be glueing itself correctly.I'm hoping someone can see what I'm doing wrong so that I can move
forward
with this.thanks!
--
Laruence Xinchen Hui
http://www.laruence.com/