gdb 调试PHP

来源:互联网 发布:淘宝为啥不能买彩票了 编辑:程序博客网 时间:2024/06/10 01:45

http://phpor.net/blog/post/997




PHP的代码包中提供了一个 .gdbinit 的gdb脚本文件,里面提供了20多个 gdb 的自定义命令,用于方便PHP的调试,下面举几个例子:
测试脚本a.php:

 

gdb 调试命令:
———————–
gdb php
set args a.php
break sleep
r

———————–

1. print_cvs 打印当前执行环境中已编译的PHP变量, 如:


2. printzv 打印指定的PHP变量, 需要指定地址, 如:

(gdb) printzv 0x9543f98
[0x9543f98] (refcount=1) string(3): “MMM”
(gdb)

3. 打印PHP的函数调用栈, 如:
(gdb) zbacktrace 
[0x95770a4] sleep(1) /usr/home/junjie2/a.php:11
[0x9576fe0] test(“phpor”) /usr/home/junjie2/a.php:7
(gdb)

4. print_ft 打印函数表( HashTable )
(gdb) set $eg = executor_globals
(gdb) print $eg.function_table  

$6 = (HashTable *) 0xa5bd450
(gdb) print_ft $eg.function_table 
[0xa5bd450] {
“zend_version\0” => “zend_version”
“func_num_args\0” => “func_num_args”
“func_get_arg\0” => “func_get_arg”
“func_get_args\0” => “func_get_args”
“strlen\0” => “strlen”
“strcmp\0” => “strcmp”
“strncmp\0” => “strncmp”
“strcasecmp\0” => “strcasecmp”
“strncasecmp\0” => “strncasecmp”
“each\0” => “each”

学习
1. 通过阅读 print_cvs 命令的实现,可以知道可以通过prev_execute_data来打印上一执行空间的PHP变量,如:
(gdb) printzv *executor_globals.current_execute_data->prev_execute_data->CVs[1]  
[0x9543408] (refcount=1) string(3): “AAA”
(gdb) printzv *executor_globals.current_execute_data->prev_execute_data->CVs[2]  
[0x95433ec] (refcount=1) string(3): “BBB”
(gdb)

2. 通过 op_array->vars 来找到对应的变量的名字
(gdb) printf “%s\n” ,executor_globals.current_execute_data->prev_execute_data->op_array->vars[1].name  
a
(gdb) printf “%s\n” ,executor_globals.current_execute_data->prev_execute_data->op_array->vars[2].name  
b

3. 修改了一下 print_cvs 命令,通过参数来获取每个执行空间的PHP的已编译变量


 

使用方法:
———————
(gdb) zbacktrace  #查看PHP的调用栈
[0x8ce2078] sleep(1) /usr/home/junjie2/a.php:9
[0x8ce1fe0] test(“phpor”) /usr/home/junjie2/a.php:5
(gdb) print_cvs #查看当前执行空间中的PHP变量
Compiled variables count: 3
0 = name
[0x8cae3d0] (refcount=2) string(5): “phpor”
1 = m
[0x8cae93c] (refcount=1) string(3): “MMM”
2 = n
[0x8cae958] (refcount=1) string(3): “NNN”
(gdb) print_cvs 2 # 查看指定执行空间中的PHP变量, 这个参数给大了也没关系,最多打印最外层的PHP变量
Compiled variables count: 2
0 = a
[0x8cae408] (refcount=1) string(3): “AAA”
1 = b
[0x8cae3ec] (refcount=1) string(3): “BBB”
(gdb)
———————

4. 有时候需要借助环境变量,如:
(gdb) print_ft (HashTable *)0xa5bd450
A syntax error in expression, near `’.
(gdb) set $phpor=(HashTable *)0xa5bd450
(gdb) print_ft $phpor
[0xa5bd450] {
“zend_version\0” => “zend_version”
“func_num_args\0” => “func_num_args”
“func_get_arg\0” => “func_get_arg”
“func_get_args\0” => “func_get_args”
“strlen\0” => “strlen”
“strcmp\0” => “strcmp”
“strncmp\0” => “strncmp”

 

5. 打印指定的PHP变量

 


PHP的代码包中提供了一个 .gdbinit 的gdb脚本文件,里面提供了20多个 gdb 的自定义命令,用于方便PHP的调试,下面举几个例子:
测试脚本a.php:

 

gdb 调试命令:
———————–
gdb php
set args a.php
break sleep
r

———————–

1. print_cvs 打印当前执行环境中已编译的PHP变量, 如:


2. printzv 打印指定的PHP变量, 需要指定地址, 如:

(gdb) printzv 0x9543f98
[0x9543f98] (refcount=1) string(3): “MMM”
(gdb)

3. 打印PHP的函数调用栈, 如:
(gdb) zbacktrace 
[0x95770a4] sleep(1) /usr/home/junjie2/a.php:11
[0x9576fe0] test(“phpor”) /usr/home/junjie2/a.php:7
(gdb)

4. print_ft 打印函数表( HashTable )
(gdb) set $eg = executor_globals
(gdb) print $eg.function_table  

$6 = (HashTable *) 0xa5bd450
(gdb) print_ft $eg.function_table 
[0xa5bd450] {
“zend_version\0” => “zend_version”
“func_num_args\0” => “func_num_args”
“func_get_arg\0” => “func_get_arg”
“func_get_args\0” => “func_get_args”
“strlen\0” => “strlen”
“strcmp\0” => “strcmp”
“strncmp\0” => “strncmp”
“strcasecmp\0” => “strcasecmp”
“strncasecmp\0” => “strncasecmp”
“each\0” => “each”

学习
1. 通过阅读 print_cvs 命令的实现,可以知道可以通过prev_execute_data来打印上一执行空间的PHP变量,如:
(gdb) printzv *executor_globals.current_execute_data->prev_execute_data->CVs[1]  
[0x9543408] (refcount=1) string(3): “AAA”
(gdb) printzv *executor_globals.current_execute_data->prev_execute_data->CVs[2]  
[0x95433ec] (refcount=1) string(3): “BBB”
(gdb)

2. 通过 op_array->vars 来找到对应的变量的名字
(gdb) printf “%s\n” ,executor_globals.current_execute_data->prev_execute_data->op_array->vars[1].name  
a
(gdb) printf “%s\n” ,executor_globals.current_execute_data->prev_execute_data->op_array->vars[2].name  
b

3. 修改了一下 print_cvs 命令,通过参数来获取每个执行空间的PHP的已编译变量


 

使用方法:
———————
(gdb) zbacktrace  #查看PHP的调用栈
[0x8ce2078] sleep(1) /usr/home/junjie2/a.php:9
[0x8ce1fe0] test(“phpor”) /usr/home/junjie2/a.php:5
(gdb) print_cvs #查看当前执行空间中的PHP变量
Compiled variables count: 3
0 = name
[0x8cae3d0] (refcount=2) string(5): “phpor”
1 = m
[0x8cae93c] (refcount=1) string(3): “MMM”
2 = n
[0x8cae958] (refcount=1) string(3): “NNN”
(gdb) print_cvs 2 # 查看指定执行空间中的PHP变量, 这个参数给大了也没关系,最多打印最外层的PHP变量
Compiled variables count: 2
0 = a
[0x8cae408] (refcount=1) string(3): “AAA”
1 = b
[0x8cae3ec] (refcount=1) string(3): “BBB”
(gdb)
———————

4. 有时候需要借助环境变量,如:
(gdb) print_ft (HashTable *)0xa5bd450
A syntax error in expression, near `’.
(gdb) set $phpor=(HashTable *)0xa5bd450
(gdb) print_ft $phpor
[0xa5bd450] {
“zend_version\0” => “zend_version”
“func_num_args\0” => “func_num_args”
“func_get_arg\0” => “func_get_arg”
“func_get_args\0” => “func_get_args”
“strlen\0” => “strlen”
“strcmp\0” => “strcmp”
“strncmp\0” => “strncmp”

 

5. 打印指定的PHP变量

 

0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 瑶柱蒸丝瓜 瑶柱营养价值 瑶柱炒蛋 蚝豉瑶柱粥 鲜瑶柱的做法 节瓜焖瑶柱 瑶柱玉米粥 瑶柱炒鸡蛋 瑶柱蒸冬瓜 花胶瑶柱煲汤 泡瑶柱 干贝和瑶柱的区别 儿童可以吃瑶柱吗 瑶柱虾 瑶柱冬瓜排骨汤 瑶柱花生粥的做法 蒸瑶柱 瑶柱粥怎么煮 瑶柱鸡肉粥 蒜子瑶柱脯 瑶柱豆腐羹 瑶柱瘦肉粥的做法 瑶柱萝卜糕 瑶柱属于海鲜吗 花胶瑶柱煲鸡 蒜子瑶柱豆苗 瑶柱糯米鸡 瑶池 西王母瑶池 瑶池圣母 瑶池李商隐 瑶池旅游 瑶池网 瑶池女使 瑶池公交 瑶池禽兽的日记 苏州瑶池丽水 楚天瑶池温泉度假村 楚天瑶池温泉度假村旅游 瑶池是什么意思 银川瑶池198好还是298好