调用PHP 7.3.4中的获取资源间歇性返回nullptr

时间:2019-07-01 15:41:40

标签: php php-7.3 zts

我正在调查当我们的C ++程序在PHP 7.3.4中调用ts_resource(0)时发生的崩溃。

代码是由一个离开公司的开发人员编写的,而我对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();

以及每次调用PHP代码时都会调用的Execute函数,其开头为:

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失败: 在Execute函数开始时对ts_resource(0)的调用将调用以下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)); ...

如果有人可以提出资源分配失败的任何原因,我将非常感激。

1 个答案:

答案 0 :(得分:0)

您是否尝试使用TSRMLS_CACHE_UPDATE而不是ZEND_TSRMLS_CACHE_UPDATE(注意ZEND_前缀)?

因此,据我了解,TSRMLS_CACHE_DEFINE应该为每个编译单元设置一次。 应该将TSRMLS_CACHE_EXTERN包含在其他文件中,并在适当时调用TSRMLS_CACHE_UPDATE。