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 @@