gdb 脚本 php,gdb 调试PHP

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

测试脚本a.php:

$a = "AAA";

$b = "BBB";

test("phpor");

function test($name) {

$m = "MMM";

$n = "NNN";

sleep(1);

echo$name;

}

1

2

3

4

5

6

7

8

9

10

$a="AAA";

$b="BBB";

test("phpor");

functiontest($name){

$m="MMM";

$n="NNN";

sleep(1);

echo$name;

}

gdb 调试命令:

———————–

gdb php

set args a.php

break sleep

r

———————–

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

(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)

1

2

3

4

5

6

7

8

9

(gdb)print_cvs

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

define 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

end

end

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

define 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

end

end

define 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         end end

1

defineprint_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变量

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

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

defineprint_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

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

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

# use strcmp but ==

ifstrcmp($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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值