From 2b609e5c5d5c6dcf0e65b1e405275d7f75fb5a13 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 11 Nov 2022 13:00:24 +0100 Subject: [PATCH 1/2] Fix run-tests.php hanging when a worker process dies without notice run-tests.php with `-jN` can hang if a parallel worker dies without notice. This can happen due to fatal errors in the worker, or if the worker is killed. - run-tests.php (main process) \_ run-tests.php (worker #0) // main process hangs if this one crashes \_ test-001.php (test-001.phpt) --- run-tests.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/run-tests.php b/run-tests.php index 32de2a11d1b2..b4cfd3431668 100755 --- a/run-tests.php +++ b/run-tests.php @@ -1555,6 +1555,10 @@ function run_all_tests_parallel(array $test_files, array $env, $redir_tested): v kill_children($workerProcs); error("Could not find worker stdout in array of worker stdouts, THIS SHOULD NOT HAPPEN."); } + if (feof($workerSock)) { + kill_children($workerProcs); + error("Worker $i died unexpectedly"); + } while (false !== ($rawMessage = fgets($workerSock))) { // work around fgets truncating things if (($rawMessageBuffers[$i] ?? '') !== '') { From 44b92ad1c0a36938fc6addb8922aed8be967115c Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 11 Nov 2022 14:31:13 +0100 Subject: [PATCH 2/2] crash --- Zend/zend_alloc.c | 5 +++++ Zend/zend_vm_def.h | 5 +++-- Zend/zend_vm_execute.h | 26 ++++++++++---------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index d0e28dca0daa..0fc0123beeba 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -58,6 +58,7 @@ #include "zend_multiply.h" #include "zend_bitset.h" #include "zend_mmap.h" +#include "zend_execute.h" #include #ifdef HAVE_UNISTD_H @@ -2553,6 +2554,7 @@ ZEND_API void ZEND_FASTCALL _efree_huge(void *ptr, size_t size) ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { + zend_get_executed_lineno(); // may crash #if ZEND_MM_CUSTOM if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { return _malloc_custom(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); @@ -2563,6 +2565,7 @@ ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { + zend_get_executed_lineno(); // may crash #if ZEND_MM_CUSTOM if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { _efree_custom(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); @@ -2574,6 +2577,7 @@ ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_OR ZEND_API void* ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { + zend_get_executed_lineno(); // may crash #if ZEND_MM_CUSTOM if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { return _realloc_custom(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); @@ -2584,6 +2588,7 @@ ZEND_API void* ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_API void* ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { + zend_get_executed_lineno(); // may crash #if ZEND_MM_CUSTOM if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { return _realloc_custom(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a4f1b4fb03a6..72b9f6be2fd5 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -378,6 +378,7 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + SAVE_OPLINE(); if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -430,8 +431,6 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_ } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -8404,6 +8403,8 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST, CACHE_SLOT) ZEND_VM_REPEATABLE_OPCODE + SAVE_OPLINE(); + varname = Z_STR_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 60a83b380095..4326644c139d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -8526,6 +8526,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + SAVE_OPLINE(); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -8578,8 +8579,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -10891,6 +10890,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z op1 = RT_CONSTANT(opline, opline->op1); op2 = EX_VAR(opline->op2.var); + SAVE_OPLINE(); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -10943,8 +10943,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -14921,6 +14919,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); op2 = RT_CONSTANT(opline, opline->op2); + SAVE_OPLINE(); if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -14973,8 +14972,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -16357,6 +16354,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + SAVE_OPLINE(); if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -16409,8 +16407,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -18044,6 +18040,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER( op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); op2 = EX_VAR(opline->op2.var); + SAVE_OPLINE(); if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -18096,8 +18093,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER( } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -39788,6 +39783,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); + SAVE_OPLINE(); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -39840,8 +39836,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -43284,6 +43278,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_C ZEND_VM_REPEATABLE_OPCODE + SAVE_OPLINE(); + varname = Z_STR_P(RT_CONSTANT(opline, opline->op2)); /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ @@ -43599,6 +43595,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER( op1 = EX_VAR(opline->op1.var); op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + SAVE_OPLINE(); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -43651,8 +43648,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER( } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } @@ -48892,6 +48887,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND op1 = EX_VAR(opline->op1.var); op2 = EX_VAR(opline->op2.var); + SAVE_OPLINE(); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -48944,8 +48940,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND } ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); }