From 1bd8ecc2be7538531b601cb8ef308c4aa390e2c1 Mon Sep 17 00:00:00 2001 From: codinghuang <2812240764@qq.com> Date: Sun, 30 Jun 2019 09:26:49 +0800 Subject: [PATCH] update --- ...72\357\274\210\345\233\233\357\274\211.md" | 107 +++++++++++++++++- test.php | 12 +- 2 files changed, 113 insertions(+), 6 deletions(-) diff --git "a/docs/\343\200\212PHP\346\211\251\345\261\225\345\274\200\345\217\221\343\200\213-\345\215\217\347\250\213-\345\215\217\347\250\213\345\210\233\345\273\272\357\274\210\345\233\233\357\274\211.md" "b/docs/\343\200\212PHP\346\211\251\345\261\225\345\274\200\345\217\221\343\200\213-\345\215\217\347\250\213-\345\215\217\347\250\213\345\210\233\345\273\272\357\274\210\345\233\233\357\274\211.md" index 51c181e..bb5a6ce 100644 --- "a/docs/\343\200\212PHP\346\211\251\345\261\225\345\274\200\345\217\221\343\200\213-\345\215\217\347\250\213-\345\215\217\347\250\213\345\210\233\345\273\272\357\274\210\345\233\233\357\274\211.md" +++ "b/docs/\343\200\212PHP\346\211\251\345\261\225\345\274\200\345\217\221\343\200\213-\345\215\217\347\250\213-\345\215\217\347\250\213\345\210\233\345\273\272\357\274\210\345\233\233\357\274\211.md" @@ -360,9 +360,114 @@ $22 = "b" (gdb) ``` -OK,分析完毕。 +那我如果给创建协程的接口传递一个匿名函数会这么样呢?`PHP`脚本如下: + +```php + +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. +Type "show copying" and "show warranty" for details. +This GDB was configured as "x86_64-alpine-linux-musl". +Type "show configuration" for configuration details. +For bug reporting instructions, please see: +. +Find the GDB manual and other documentation resources online at: + . + +For help, type "help". +Type "apropos word" to search for commands related to "word"... +Reading symbols from php...(no debugging symbols found)...done. +(gdb) +``` + +我们在`zim_study_coroutine_util_create`出打断点: + +```shell +(gdb) b zim_study_coroutine_util_create +Breakpoint 1 at 0x7ffff78d62e0: file /root/codeDir/cppCode/study/study_coroutine_util.cc, line 10. +(gdb) +``` + +然后执行: + +```shell +(gdb) r test.php +Starting program: /usr/local/bin/php test.php +Breakpoint 1, zim_study_coroutine_util_create (execute_data=0x7ffff761d090, return_value=0x7fffffffb0b0) at /root/codeDir/cppCode/study/study_coroutine_util.cc:10 +(gdb) +``` +```cpp + 9│ PHP_METHOD(study_coroutine_util, create) +10├>{ +11│ zend_fcall_info fci = empty_fcall_info; +12│ zend_fcall_info_cache fcc = empty_fcall_info_cache; +13│ zval result; +14│ +15│ ZEND_PARSE_PARAMETERS_START(1, -1) +16│ Z_PARAM_FUNC(fci, fcc) +17│ Z_PARAM_VARIADIC('*', fci.params, fci.param_count) +18│ ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); +19│ +20│ fci.retval = &result; +21│ if (zend_call_function(&fci, &fcc) != SUCCESS) { +22│ return; +23│ } +24│ +25│ *return_value = result; +26│ } +``` + +我们执行到`20`行之前: + +```shell +(gdb) u 20 +zim_study_coroutine_util_create (execute_data=0x7ffff761d090, return_value=0x7fffffffb0b0) at /root/codeDir/cppCode/study/study_coroutine_util.cc:20 +(gdb) +``` + +此时,我们来查看一下`fci.function_name`: + +```shell +(gdb) p fci.function_name +$1 = {value = {lval = 140737344071552, dval = 6.9533486792693069e-310, counted = 0x7ffff7666780, str = 0x7ffff7666780, arr = 0x7ffff7666780, obj = 0x7ffff7666780, res = 0x7ffff7666780, ref = 0x7ffff766678 +0, ast = 0x7ffff7666780, zv = 0x7ffff7666780, ptr = 0x7ffff7666780, ce = 0x7ffff7666780, func = 0x7ffff7666780, ww = {w1 = 4150683520, w2 = 32767}}, u1 = {v = {type = 8 '\b', type_flags = 1 '\001', u = {c +all_info = 0, extra = 0}}, type_info = 264}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0, property_guard = 0, constant_flags = 0 +, extra = 0}} +(gdb) +``` + +因为`fci.function_name.u1.v.type`的值为8,所以它是一个对象,因为我们传递了一个闭包进去。我们通过打印如下值来进行确认: + +```shell +(gdb) p /t fcc.function_handler.op_array.fn_flags +$4 = 1000000100000000000000000000 +(gdb) +``` + +我们看到了第`21`位为`1`,所以这是一个闭包。 + +OK,分析完毕。 diff --git a/test.php b/test.php index f40ee3c..4187d7e 100644 --- a/test.php +++ b/test.php @@ -1,9 +1,11 @@