[英]Call to get resource in PHP 7.3.4 intermittently returns nullptr
我正在調查我們的 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);
之前執行上下文類的一些初始化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)); ...
如果有人可以提出資源分配可能失敗的任何原因,我將不勝感激。
您是否嘗試過使用 TSRMLS_CACHE_UPDATE 而不是 ZEND_TSRMLS_CACHE_UPDATE (注意 ZEND_ 前綴)?
所以,據我所知,每個編譯單元都應該設置 TSRMLS_CACHE_DEFINE 一次。 TSRMLS_CACHE_EXTERN 應包含在其他文件中,並應在適當時調用 TSRMLS_CACHE_UPDATE。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.