rovast 5年前

修改理由:

markdown语法修正

此投稿已在 5年前 合并。

内容修改:

红色背景 为原始内容

绿色背景 为新增或者修改的内容

OldNewDifferences
2121
2222### 1、使用 docker 拉取环境
2323
24 ```bash
 24```bash
2525# 拉取准备好的环境
2626git clone https://github.com/rovast/docker-examples.git
2727
 
3030
3131# 启动,会经历一个漫长又不太漫长的等待,看你网速
3232docker-compose up -d
33 ```
 33```
3434
3535> 关于容器内的环境,大家可以看看 【dockerfile](https://github.com/rovast/docker-autobuild/blob/master/gdb-php-src/7.0.0/Dockerfile)
3636>
 
3838
3939显示如下
4040
41 ```text
 41```text
4242Creating network "gdb-php-src_default" with the default driver
4343Creating gdb-php-src ... done
44 ```
 44```
4545
4646### 2、进入容器
4747
48 ```bash
 48```bash
4949docker exec -it gdb-php-src bash
5050
5151### 显示下面的东西,表示你已经进入到容器内了 ####
5252root@71a98d1bc1a6:/home#
53 ```
 53```
5454
5555我们看看容器内的环境(php 以及 gdb)
5656
57 ```bash
 57```bash
5858### 我们在容器内看看环境
5959root@71a98d1bc1a6:/home# ls
6060php-7.0.0 start.md
 
8181Copyright (c) 1997-2015 The PHP Group
8282Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies
8383root@71a98d1bc1a6:/home#
84 ```
 84```
8585
8686## 开火(请在容器内操作)
8787
8888### 1、新建测试文件
8989
90 ```bash
 90```bash
9191root@71a98d1bc1a6:/home# vi test.php
92 ```
 92```
9393
9494输入以下内容
95 ```php
 95```php
9696<?php
9797
9898strval(1234);
99 ```
 99```
100100
101101这个文件干的事情就比较简单了,就是把 -1234[整形] 转换为 -1234[字符串]
102102
 
107107
108108输入 `gdb php`,开始调试
109109
110 ```bash
 110```bash
111111root@71a98d1bc1a6:/home# gdb php
112112GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
113113Copyright (C) 2016 Free Software Foundation, Inc.
 
125125Type "apropos word" to search for commands related to "word"...
126126Reading symbols from php...done.
127127(gdb)
128 ```
 128```
129129
130130### 3、打一些断点(敲命令时可以用 tab 补全)
131131
132 ```bash
 132```bash
133133(gdb) b zend_long_to_str
134134Breakpoint 1 at 0x810423: file /home/php-7.0.0/Zend/zend_operators.c, line 2743.
135135(gdb) b zend_print_ulong_to_buf
136136Breakpoint 2 at 0x5f387b: zend_print_ulong_to_buf. (13 locations)
137137(gdb)
138 ```
 138```
139139
140140这里在关键函数 `zend_long_to_str` 和 `zend_print_ulong_to_buf` 打了断点。
141141
 
143143
144144### 4、执行,查看断点值
145145
146 ```bash
 146```bash
147147(gdb) r test.php # 执行我们刚才的那个 PHP 文件
148148Starting program: /usr/local/bin/php test.php
149149[Thread debugging using libthread_db enabled]
 
162162Breakpoint 1, zend_long_to_str (num=-1234) at /home/php-7.0.0/Zend/zend_operators.c:2743
1631632743     char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
164164(gdb)
165 ```
 165```
166166
167167看的好像不明了嘛, `ctrl` + `x` 后再按 `a` 进入 gui 模式看看
168168
169 ```bash
 169```bash
170170  ┌──/home/php-7.0.0/Zend/zend_operators.c────────────────────────────────────────────────────────────────────────────────────────────────┐
171171  │2731   ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */                                  │
172172  │2732   {                                                                                                                             │
 
200200
201201
202202(gdb)
203 ```
 203```
204204
205205有点意思了,函数在 2743 行断住了,我们来看看 num 的值
206206
207 ```bash
 207```bash
208208(gdb) p num
209209$1 = -1234
210210(gdb)
211 ```
 211```
212212
213213对嘛,这个就是我们要处理的值,我们全速运行到 `zend_print_long_to_buf` 里看看
214214
215 ```bash
 215```bash
216216(gdb) c
217217Continuing.
218 ```
 218```
219219
220220显示如下
221221
222 ```bash
 222```bash
223223(gdb) c
224224 ┌──/home/php-7.0.0/Zend/zend_operators.h────────────────────────────────────────────────────────────────────────────────────────────────┐
225225  │781            else                                                                                                  \              │
 
251251  │807            } else {                                                                                                              │
252252  └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
253253multi-thre Thread 0x7ffff7fe37 In: zend_print_ulong_to_buf                                                              L793 PC: 0x8041fd
254 ```
 254```
255255
256256接下来,我们来进行一些单步调试,看看内存里的值
257257
258 ```bash
 258```bash
259259Breakpoint 1, zend_long_to_str (num=-1234) at /home/php-7.0.0/Zend/zend_operators.c:2743
260260(gdb) c #-------------> 表示继续执行
261261Continuing.
 
2732730x7fffffffafe0: 49 '1' 50 '2' 51 '3' 52 '4' 0 '\000'       0 '\000'       0 '\000'       0 '\000'
2742740x7fffffffafe8: 0 '\000'       65 'A'
275275(gdb)
276 ```
 276```
277277
278278我们看到,函数返回的 buf 是字符串类型的 '1234'
279279