zoukankan      html  css  js  c++  java
  • gdb 调试PHP

    扩展编译好用,通过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:

    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″ => “zend_version”
    “func_num_args″ => “func_num_args”
    “func_get_arg″ => “func_get_arg”
    “func_get_args″ => “func_get_args”
    “strlen″ => “strlen”
    “strcmp″ => “strcmp”
    “strncmp″ => “strncmp”
    “strcasecmp″ => “strcasecmp”
    “strncasecmp″ => “strncasecmp”
    “each″ => “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 ” ,executor_globals.current_execute_data->prev_execute_data->op_array->vars[1].name  
    a
    (gdb) printf “%s ” ,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″ => “zend_version”
    “func_num_args″ => “func_num_args”
    “func_get_arg″ => “func_get_arg”
    “func_get_args″ => “func_get_args”
    “strlen″ => “strlen”
    “strcmp″ => “strcmp”
    “strncmp″ => “strncmp”

    5. 打印指定的PHP变量

  • 相关阅读:
    TAM实施范例
    xmanager连接到RHEL6.
    TAM安装过程中遇到的问题
    db29.1FP2升级FP12
    WAS常见问题及解答
    在 Lotus Quickr for Domino 环境中使用 Tivoli Access Manager WebSEAL 作为反向代理服务器
    TAM包含的内容全面的指南自IBM
    Setting up the Web Admin Tool in LDAP 6.x to communicate via SSL
    oracle字符集。
    redhat中设置环境变量PATH的方法和只显示目录的Tree
  • 原文地址:https://www.cnblogs.com/breg/p/3830141.html
Copyright © 2011-2022 走看看