static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *retval_ptr;
zval *return_value;
zend_free_op free_op1;
retval_ptr = EX_CONSTANT(opline->op1);
return_value = EX(return_value);
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
SAVE_OPLINE();
retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
if (return_value) {
ZVAL_NULL(return_value);
}
} else if (!return_value) {
//進入這裡不做處理
if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) {
SAVE_OPLINE();
zval_dtor_func(Z_COUNTED_P(free_op1));
}
}
} else {
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
//常量,複製值
ZVAL_COPY_VALUE(return_value, retval_ptr);
if (IS_CONST == IS_CONST) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
Z_ADDREF_P(return_value);
}
}
} else if (IS_CONST == IS_CV) {
if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
ZVAL_COPY_VALUE(return_value, retval_ptr);
if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) {
ZVAL_NULL(retval_ptr);
} else {
Z_ADDREF_P(return_value);
}
} else {
retval_ptr = Z_REFVAL_P(retval_ptr);
ZVAL_COPY(return_value, retval_ptr);
}
} else {
ZVAL_COPY_VALUE(return_value, retval_ptr);
}
} else /* if (IS_CONST == IS_VAR) */ {
if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
retval_ptr = Z_REFVAL_P(retval_ptr);
ZVAL_COPY_VALUE(return_value, retval_ptr);
if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
efree_size(ref, sizeof(zend_reference));
} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
Z_ADDREF_P(retval_ptr);
}
} else {
ZVAL_COPY_VALUE(return_value, retval_ptr);
}
}
}
//直接到這
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
}
gdb 走的程式碼:
ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER () at /php-7.1.26/Zend/zend_vm_execute.h:41202
41202 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
(gdb) s
41203 }
(gdb) n
execute_ex (ex=0x7ffff4013030) at /php-7.1.26/Zend/zend_vm_execute.h:430
430 if (UNEXPECTED(!OPLINE)) {
(gdb) n
429 ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
(gdb) n
Breakpoint 5, ZEND_RETURN_SPEC_CONST_HANDLER () at /php-7.1.26/Zend/zend_vm_execute.h:2857
2857 retval_ptr = EX_CONSTANT(opline->op1);
(gdb) p opline
Missing ELF symbol "opline".
(gdb) p retval_ptr
$25 = (zval *) 0x7ffff4013080
(gdb) p *retval_ptr
$26 = {value = {lval = 140737287435600, dval = 6.9533458810814867e-310, counted = 0x7ffff4063550, str = 0x7ffff4063550, arr = 0x7ffff4063550,
obj = 0x7ffff4063550, res = 0x7ffff4063550, ref = 0x7ffff4063550, ast = 0x7ffff4063550, zv = 0x7ffff4063550, ptr = 0x7ffff4063550, ce = 0x7ffff4063550,
func = 0x7ffff4063550, ww = {w1 = 4094047568, w2 = 32767}}, u1 = {v = {type = 8 '\b', type_flags = 12 '\f', const_flags = 0 '\000',
reserved = 0 '\000'}, type_info = 3080}, u2 = {next = 0, cache_slot = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0,
property_guard = 0, extra = 0}}
(gdb) n
2858 return_value = EX(return_value);
(gdb) p return_value
$27 = (zval *) 0x555555ba3d3c <ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER+106>
(gdb) p *return_value
$28 = {value = {lval = 5255851728548759880, dval = 2.3048279784435938e+43, counted = 0x48f0894ce8458948, str = 0x48f0894ce8458948,
arr = 0x48f0894ce8458948, obj = 0x48f0894ce8458948, res = 0x48f0894ce8458948, ref = 0x48f0894ce8458948, ast = 0x48f0894ce8458948,
zv = 0x48f0894ce8458948, ptr = 0x48f0894ce8458948, ce = 0x48f0894ce8458948, func = 0x48f0894ce8458948, ww = {w1 = 3896871240, w2 = 1223723340}}, u1 = {
v = {type = 139 '\213', type_flags = 0 '\000', const_flags = 72 'H', reserved = 131 '\203'}, type_info = 2202534027}, u2 = {next = 2303271104,
cache_slot = 2303271104, lineno = 2303271104, num_args = 2303271104, fe_pos = 2303271104, fe_iter_idx = 2303271104, access_flags = 2303271104,
property_guard = 2303271104, extra = 2303271104}}
(gdb) n
2865 } else if (!return_value) {
(gdb) n
2912 ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
(gdb) s
zend_leave_helper_SPEC () at /php-7.1.26/Zend/zend_vm_execute.h:481
481 uint32_t call_info = EX_CALL_INFO();
(gdb) n
483 if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
(gdb) n
515 } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
(gdb) n
553 } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
(gdb) n
570 if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
(gdb) n
584 zend_array *symbol_table = EX(symbol_table);
(gdb) p *symbol_table
$29 = {gc = {refcount = 4094047568, u = {v = {type = 255 '\377', flags = 127 '\177', gc_info = 0}, type_info = 32767}}, u = {v = {flags = 8 '\b',
nApplyCount = 12 '\f', nIteratorsCount = 0 '\000', consistency = 0 '\000'}, flags = 3080}, nTableMask = 0, arData = 0x0, nNumUsed = 0,
nNumOfElements = 0, nTableSize = 0, nInternalPointer = 0, nNextFreeElement = 0, pDestructor = 0x0}
(gdb) n
586 zend_detach_symbol_table(execute_data);
(gdb) s
zend_detach_symbol_table (execute_data=0x7ffff4013030) at /php-7.1.26/Zend/zend_execute_API.c:1630
1630 zend_op_array *op_array = &execute_data->func->op_array;
(gdb) n
1631 HashTable *ht = execute_data->symbol_table;
(gdb) n
1634 if (EXPECTED(op_array->last_var)) {
(gdb) p *ht
$30 = {gc = {refcount = 1, u = {v = {type = 7 '\a', flags = 0 '\000', gc_info = 0}, type_info = 7}}, u = {v = {flags = 10 '\n', nApplyCount = 0 '\000',
nIteratorsCount = 0 '\000', consistency = 0 '\000'}, flags = 10}, nTableMask = 4294967232, arData = 0x7ffff4059100, nNumUsed = 8, nNumOfElements = 8,
nTableSize = 64, nInternalPointer = 0, nNextFreeElement = 0, pDestructor = 0x555555ae1fbf <_zval_ptr_dtor_wrapper>}
(gdb) p *op_array
$31 = {type = 2 '\002', arg_flags = "\000\000", fn_flags = 134217728, function_name = 0x0, scope = 0x0, prototype = 0x0, num_args = 0,
required_num_args = 0, arg_info = 0x0, refcount = 0x7ffff4001028, last = 5, opcodes = 0x7ffff40790c0, last_var = 1, T = 4, vars = 0x7ffff4001050,
last_live_range = 0, last_try_catch = 0, live_range = 0x0, try_catch_array = 0x0, static_variables = 0x0, filename = 0x7ffff40577c0, line_start = 1,
line_end = 6, doc_comment = 0x0, early_binding = 4294967295, last_literal = 3, literals = 0x7ffff4063500, cache_size = 8,
run_time_cache = 0x7ffff4001078, reserved = {0x0, 0x0, 0x0, 0x0}}
(gdb) p *op_array->opcodes
$32 = {handler = 0x555555b4c981 <ZEND_NOP_SPEC_HANDLER>, op1 = {constant = 0, var = 0, num = 0, opline_num = 0, jmp_offset = 0}, op2 = {constant = 0,
var = 0, num = 0, opline_num = 0, jmp_offset = 0}, result = {constant = 0, var = 0, num = 0, opline_num = 0, jmp_offset = 0}, extended_value = 0,
lineno = 3, opcode = 0 '\000', op1_type = 8 '\b', op2_type = 8 '\b', result_type = 8 '\b'}
(gdb) n
1635 zend_string **str = op_array->vars;
(gdb) p **str
$33 = {gc = {refcount = 1, u = {v = {type = 8 '\b', flags = 0 '\000', gc_info = 0}, type_info = 8}}, h = 1, len = 140737287036952, val = ""}
(gdb) n
1636 zend_string **end = str + op_array->last_var;
(gdb) p **end
Cannot access memory at address 0xc0400000008
(gdb) n
1637 zval *var = EX_VAR_NUM(0);
(gdb) n
1640 if (Z_TYPE_P(var) == IS_UNDEF) {
(gdb) n
1643 zend_hash_update(ht, *str, var);
(gdb) n
1644 ZVAL_UNDEF(var);
(gdb) n
1646 str++;
(gdb) n
1647 var++;
(gdb) n
1648 } while (str != end);
(gdb) n
1650 }
(gdb) n
zend_leave_helper_SPEC () at /php-7.1.26/Zend/zend_vm_execute.h:587
587 old_execute_data = EX(prev_execute_data);
(gdb) n
588 while (old_execute_data) {
(gdb) n
597 EG(current_execute_data) = EX(prev_execute_data);
(gdb) n
598 ZEND_VM_RETURN();
本作品採用《CC 協議》,轉載必須註明作者和本文連結