как побороть zend_mm_heap corrupted

Alexandre

PHPПенсионер
собственно вопрос к Тони, как специалисту по модулям:
PHP 5.3.1 (cli) (built: May 21 2010 01:15:25)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies


разрабатываю модуль обмена с noSQL БД. При использовании чтения из сокета в методе getTuple() возникает ошибка zend_mm_heap corrupted. В последствии использование сокета заменил на php_streams.Ошибка не исчезла.

Сделал иммитацию чтения, т.е. сделал метод getTupleMock() , работает все отлично.
исходники

Небольшое пояснение (test.php):
Метод select() - производит запрос к БД и читает заголовок ответа. Заголовок сохраняется в контексте модуля ( tarantool_object * ctx ).

Метод getTuple() читает из сокета один кортеж и возвращает его в в виде индексного массива array( 'a' , 'abc' , 1024 ... );

ошибка zend_mm_heap corrupted возникает при повторном вызове метода getTuple(); Тестирование производилось на данных из рекордсета с двумя кортежами.

Иммитация с использование mock методов (testLock.php)

метод selectMock() формирует данные заголовка и сохраняет их в контексте сервера. Вся логика метода select сохранена. Нет операций в/в с сокетами.

Метод getTupleMock() формирует данные одного кортежа, как буд-то они были прочитаны из сокета и возвращает его в в виде индексного массива array( 'a' , 'abc' , 1024 ... ); Вся логика работы метода getTuple сохранена. Заменены только операции работы с сокетом на предопределенные данные.
Работает нормально.

Тонни,
взгяни опытным взглядом, что я где забыл вставить или освободить?
Что может вызвать эту ошибку. По исходникам РНР - она может возникнуть в четырех или пяти разных случаях.



Ну и по ходу еще вопрос:
как правильно написать/вызвать функцию из метода (PHP_METHOD(tarantool_class, select)), в которой можно обрабатывать исключения. Если по конкретнее, не хочу дублировать кусок кода, который открывает соединение с БД (line 498-532), а вынести его в отдельную функцию.
Этот кусок будет присутствовать как минимум в 4х методах.
 

tony2001

TeaM PHPClub
taTantool?
valgrind поможет, конечно: http://bugs.php.net/bugs-getting-valgrind-log.php
хотя, я сходу вижу следующие проблемы:

https://github.com/akalend/php_tatantool/blob/master/tarantool.c#L178
long host_len = 0;
это должен быть int.

long long port=0; ??
это просто long.

https://github.com/akalend/php_tatantool/blob/master/tarantool.c#L481
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olla|sl", &id,
s - опечатка? там явно принимается long

Код:
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
"the error of parse parameter" ,0 TSRMLS_CC);
вот это вообще лишнее - zend_parse_method_parameters() и так выводит ошибки сам.
так что, у тебя будут И ошибки, И эксепшены.

Код:
if (php_stream_read(ctx->stream, (char*) buf, responseBody.size) != responseBody.size) {
ты уверен, что responseBody.size всегда меньше 256?

в любом случае, valgrind it.
 

Alexandre

PHPПенсионер
спасибо,
све замечания учту. ранее я использовал сокеты, но потом переписал на php_streams
по этому часть кода еще не доотлажена,

проинсталирую valgrind
и дебаг выложу.

у меня разработка под OsX (valgrind не поддерживается)
перенесу ее на Ubuntu ( где хостится сама БД)



ты уверен, что responseBody.size всегда меньше 256?
пока да,
в последствии заменю на emalloc(responseBody.size)

а что посоветуешь с
Ну и по ходу еще вопрос ...
пробовал объявлять как
static void my_funct( type1 p1, type2 p2 TSRMLS_DC/CC)
но в случае возникновения эксепшена (вызов zend_throw_exception() ), он не отображается
 

tony2001

TeaM PHPClub
>emalloc(responseBody.size)
тогда уж emalloc(responseBody.size+1)

>static void my_funct( type1 p1, type2 p2 TSRMLS_DC/CC)
>но в случае возникновения эксепшена (вызов zend_throw_exception() ), он не отображается
щито?
 

Alexandre

PHPПенсионер
>emalloc(responseBody.size)
тогда уж emalloc(responseBody.size+1)
зачем +1
это не строка, терминальный 0 не нужен

>static void my_funct( type1 p1, type2 p2 TSRMLS_DC/CC)
>но в случае возникновения эксепшена (вызов zend_throw_exception() ), он не отображается
щито?
я визуально не вижу сообщения эксепшена
 

Alexandre

PHPПенсионер
нет - обязательно нужен?
т.е. в данных должен, размещенных с помощью emalloc() должен быть терминальный 0?
 

Alexandre

PHPПенсионер
спасибо,
я уже в курсе

когда устанавливал последнюю версию, то обратил внимание на названия некоторых файлов ;)
решил попробовать установить под MacOs и получилось.

Просто когда я три года назад приобретал Мак, тогда этой поддержки не существовало.
 

Alexandre

PHPПенсионер
побороть zend_mm_heap corrupted мне не получилось
есть какая-то магическая взаимосвязь между использованием ht и php_stream
решил отказаться от использования array в качестве аргумента.
ошибка возникает при использовании кода
PHP:
    pht = Z_ARRVAL_P(tuple); 
    int num = zend_hash_num_elements(pht);     
    for(zend_hash_internal_pointer_reset_ex(pht, &pos); 
          zend_hash_get_current_data_ex(pht, (void **) &curr, &pos) == SUCCESS; 
          zend_hash_move_forward_ex(pht, &pos)) { 
         . . .
    }
 

tony2001

TeaM PHPClub
>есть какая-то магическая взаимосвязь между использованием ht и php_stream
дада.
она называется "подземные стуки".
 
Сверху