Я расследую сбой, который происходит, когда наша программа на C ++ вызывает ts_resource (0) в PHP 7.3.4.
Код был написан разработчиком, который с тех пор покинул компанию, и я очень мало знаю PHP. Первоначальный код был написан для PHP 5.3 и отлично работал в течение многих лет, но когда PHP был обновлен до 7.3.4, наша программа начала периодически падать.
Я обнаружил, что сбой вызван вызовом tsrm_get_ls_cache (), который возвращает nullptr. Я добавил проверку для nullptr и остановил сбой, но я хотел бы знать, почему вызов для получения ресурса возвращает nullptr и что я могу сделать, чтобы предотвратить его. Я предполагаю, что проблема связана с памятью, так как она прерывистая.
Я не уверен, какой код показывать, поскольку вызовы PHP в нашем коде обширны. PHP скомпилирован с поддержкой ZTS, поэтому он многопоточный.
На этапе инициализации менеджер безопасного потока запускается с:
tsrm_startup(128, 1, 0, NULL);
ts_resource(0);
ZEND_TSRMLS_CACHE_UPDATE();
и наша функция Execute, которая вызывается при каждом вызове PHP-кода, начинается с:
ts_resource(0);
ZEND_TSRMLS_CACHE_UPDATE();
if (tsrm_get_ls_cache() == nullptr)
return false;
ExecuteContext context;
context.pOutputStream = pOutputStream;
SG(server_context) = (void*)&context;
Затем перед вызовом выполняется некоторая инициализация класса контекста.
php_request_startup(TSRMLS_C);
При сбое вызова для получения ресурса происходит сбой, потому что происходит сбой malloc:
Вызов ts_resource (0) в начале функции Execute вызывает следующую функцию PHP для выделения нового ресурса:
allocate_new_resource(&thread_resources->next, thread_id);
и этот вызов malloc завершается ошибкой выделения
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
{
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
...
Если кто-нибудь может предложить какие-либо причины, по которым распределение ресурсов может быть неудачным, я был бы очень признателен.