您的位置:首页 > 编程语言 > PHP开发

gdb 调试PHP

2015-12-16 17:48 531 查看
http://phpor.net/blog/post/997

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

测试脚本a.php:

12345678910<?php$a = "AAA";$b = "BBB";test("phpor");function test($name) { $m = "MMM"; $n = "NNN"; sleep(1); echo$name;}
gdb 调试命令:
———————–
gdb php
set args a.php
break sleep
r

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

1

2

3

4

5

6

7

8

9

(gdb)
print_cvs

Compiled
variables
count:
3

0
=
name

[0x9543f7c]
(refcount=2)
string(5):
"phpor"

1
=
m

[0x9543f98]
(refcount=1)
string(3):
"MMM"

2
=
n

[0x9543fb4]
(refcount=1)
string(3):
"NNN"

(gdb)

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的已编译变量

12345678910111213141516171819202122232425define print_cvs ____executor_globals set $f = $eg.current_execute_data if $argc == 1 set $j = 1 while $j < $arg0 && $f.prev_execute_data != 0 set $f = $f.prev_execute_data set $j = $j + 1 end end set $p = $f.CVs set $c = $f.op_array.last_var set $v = $f.op_array.vars set $i = 0 printf "Compiled variables count: %d\n", $c while $i < $c printf "%d = %s\n", $i, $v[$i].name if $p[$i] != 0 printzv *$p[$i] else printf "*uninitialized*\n" end set $i = $i + 1 endend
使用方法:
———————
(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变量

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

define
print_pval

____executor_globals

set
$p
=
$eg.current_execute_data.CVs

set
$c
=
$eg.current_execute_data.op_array.last_var

set
$v
=
$eg.current_execute_data.op_array.vars

set
$i
=
0

set
$name
=
$arg0

#printf
"search php var: %s c:%d\n", $name, $c

while
$i
<
$c

#printf
"name: %s\n", $name

set
$n
=
$v[$i].name

#
use strcmp but ==

if
strcmp($n,
$name)
==
0

if
$p[$i]
!=
0

printzv
*$p[$i]

#
use loop_break but break

loop_break

end

end

#printf
"i %d, %s\n", $i, $v[$i].name

set
$i
=
$i
+
1

end

if
$i
==
$c

printf
"no found var
named: %s\n",
$name

end

end

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

测试脚本a.php:

12345678910<?php$a = "AAA";$b = "BBB";test("phpor");function test($name) { $m = "MMM"; $n = "NNN"; sleep(1); echo$name;}
gdb 调试命令:
———————–
gdb php
set args a.php
break sleep
r

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

1

2

3

4

5

6

7

8

9

(gdb)
print_cvs

Compiled
variables
count:
3

0
=
name

[0x9543f7c]
(refcount=2)
string(5):
"phpor"

1
=
m

[0x9543f98]
(refcount=1)
string(3):
"MMM"

2
=
n

[0x9543fb4]
(refcount=1)
string(3):
"NNN"

(gdb)



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的已编译变量

12345678910111213141516171819202122232425define print_cvs ____executor_globals set $f = $eg.current_execute_data if $argc == 1 set $j = 1 while $j < $arg0 && $f.prev_execute_data != 0 set $f = $f.prev_execute_data set $j = $j + 1 end end set $p = $f.CVs set $c = $f.op_array.last_var set $v = $f.op_array.vars set $i = 0 printf "Compiled variables count: %d\n", $c while $i < $c printf "%d = %s\n", $i, $v[$i].name if $p[$i] != 0 printzv *$p[$i] else printf "*uninitialized*\n" end set $i = $i + 1 endend
使用方法:
———————
(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变量

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

define
print_pval

____executor_globals

set
$p
=
$eg.current_execute_data.CVs

set
$c
=
$eg.current_execute_data.op_array.last_var

set
$v
=
$eg.current_execute_data.op_array.vars

set
$i
=
0

set
$name
=
$arg0

#printf
"search php var: %s c:%d\n", $name, $c

while
$i
<
$c

#printf
"name: %s\n", $name

set
$n
=
$v[$i].name

#
use strcmp but ==

if
strcmp($n,
$name)
==
0

if
$p[$i]
!=
0

printzv
*$p[$i]

#
use loop_break but break

loop_break

end

end

#printf
"i %d, %s\n", $i, $v[$i].name

set
$i
=
$i
+
1

end

if
$i
==
$c

printf
"no found var
named: %s\n",
$name

end

end

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: