扩展编译好用,通过php编码测试报“段错误",如果是c语言都是用gdb进行设置,那php扩展要如何进行调试呢?搜索了下,虽然是php扩展但是core是php 的core不是单个so扩展的coredump
这里使用ulimit -c unlimited来开启core文件,使用gdb来对core文件进行调试演示一下。
 
root@debian:~/php# php a.php 
段错误
root@debian:~/php# ulimit -c unlimited
root@debian:~/php# php a.php
段错误 (core dumped)
root@debian:~/php# ls
a.php core
root@debian:~/php# apt-get install gdb
root@debian:~/php# gdb php -c core
Core was generated by `php a.php'.
Program terminated with signal 11, Segmentation fault.
#0 0xb6a7bfb8 in zif_smtpmail_connect (ht=5, return_value=0xb6f149dc, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1) at /root/php/php-5.4.7/ext/smtpmail/smtpmail.c:281
281 if(strcmp(substring(lastmessage, 1, 3), hen) !=0 || strlen(lastmessage)==0) {
(gdb) (gdb) source ./php-5.4.7/.gdbinit
(gdb) zbacktrace
[0xb6efb030] smtpmail_connect("smtp.qq.com", "xxxx", "xxx", "xxxx@qq.com", 25) /root/php/a.php:5

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

<?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
<?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变量, 如:

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

使用方法:
———————
(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
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

gdb 调试PHP的更多相关文章

  1. GDB调试命令小结

    1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...

  2. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  3. gdb调试器的使用

    想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车    是运行上一个命令 ...

  4. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  5. gdb调试PHP扩展错误

    有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...

  6. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

  7. gdb调试

    ·代码(实验楼中的代码,改了部分数值)命名为test.c int g(int x) { return x + 7; } int f(int x) { return g(x); } int main(v ...

  8. 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析

    20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...

  9. GDB调试汇编堆栈

    GDB调试汇编堆栈 分析过程 C语言源代码 int g(int x) { return x+6; } int f(int x) { return g(x+1); } int main(void) { ...

  10. 赵文豪 GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 使用gdb调 ...

随机推荐

  1. iOS开发之Documentation.build/Script-BC552B3A15.sh:

    /Users/hbbhao/Library/Developer/Xcode/DerivedData/AWLive-dmbegyhgamayzudqqdentwngdpkr/Build/Intermed ...

  2. canvas实现点击带水纹的按钮

    咱今天在闲逛网页时,看到一个点击带水纹的按钮特效,尼玛,写的还挺好,先看效果: 于是就奔着升级版的拿来主义,别人的好东西,咱都要拿来滴,so,扒代码! 完整代码在最后,是经过我的改进优化滴. 在这里先 ...

  3. mysql数据库( 基础篇加破解)

    1.数据库(Database,DB)是按照数据结构来组织.存储和管理数据的,并且是建立在计算机存储设备上的仓库 2.什么是数据库:(用来存储数据的仓库) 数据库:(cs架构套接字) 数据库管理软件分类 ...

  4. Python之struct

    struct是Python中的内建模块,用来在C语言中的结构体与Python中的字符串之间进行转换,数据一般来自文件或网络 1. 功能 (1) 按照指定格式将Python数据转换为字符串(该字符串为字 ...

  5. 关于altera的fft核使用问题记录

    altera的fft核使用比较特别,今天我做了一下仿真,发现一些问题,现做记录如下: 1,ip配置 parameters选项卡主要是fft变换的长度和数据长度,旋转因子长度,需要注意的是“Twiddl ...

  6. 一步一步建立 webpack 4 项目

    一步一步建立 webpack 4 项目 cnpm init -y cnpm i webpack --save-dev cnpm i webpack-cli --save-dev 修改 package. ...

  7. Delphi 连接 Paradox

    应用TDataBase控件把DataBase的DriveName设为STANDARD,然后设置DataBase的Params中设置PATH=*.db文件地点目录DEFAULT DRIVER=PARAD ...

  8. bzoj 3501 PA2008 Cliquers Strike Back——贝尔数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3501 用贝尔三角形 p^2 地预处理 p 以内的贝尔数.可以模(mod-1)(它是每个分解下 ...

  9. 第17篇 shell编程基础(2)

    shell study 1.Exit StatusIf the command executed successfully (or true), the value of $? is zero. If ...

  10. 多线程使用信号量sem_init,sem_wait,sem_post

    信号量的主要函数有: int sem_init(sem_t *sem,int pshared,unsigned int value); int sem_wait(sem_t *sem); int se ...