加入收藏 | 设为首页 | 会员中心 | 我要投稿 无锡站长网 (https://www.0510zz.cn/)- 运维、开发、CDN、操作系统、语音技术!
当前位置: 首页 > 教程 > 正文

教你如何使用gdb调试php!

发布时间:2022-08-11 11:27:33 所属栏目:教程 来源:互联网
导读:使用gdb调试php 简介 gdb 是c语言的代码调试工具 可以用来调试php、python、mysql等 调试主要有4种形式 gdb:启动之后用attach pid 追踪程序 gdb [options] [executable-file [core-file or process-id]] gdb [options] --args executable-file [inferior-arg
使用gdb调试php
简介
gdb 是c语言的代码调试工具
可以用来调试php、python、mysql等
调试主要有4种形式
 
 
 
gdb:启动之后用attach pid 追踪程序
 
gdb [options] [executable-file [core-file or process-id]]
 
gdb [options] --args executable-file [inferior-arguments ...]
 
gdb [options] [--python|-P] script-file [script-arguments ...]
 
常用调试命令
attach pid
例:如果向跟踪调试mysql代码
1.先找到mysql进行ID:10111
c730b25f7eef0e7a835122917a4e13f.png
 
2.再attach 10111追踪mysql
 
layout
显示源码/汇编指令
 
 
 
Layout names are:
 
   src      : Displays source and command windows. 显示源码
 
   asm      : Displays disassembly    and command windows. 显示汇编指令
 
   split : Displays source, disassembly    and command windows. 显示源码和汇编指令
 
   regs     : Displays register window. If    existing layout
 
              is source/command or    assembly/command, the
 
              register window is displayed. If the
 
              source/assembly/command (split) is displayed,
 
              the register    window is displayed with
 
              the window that has current logical focus
 
break
b 增加断点
info b 显示断点信息
delete num 删除指定断点
continue [num]
c num 执行到num个断点,num可以不填默认=1
next [num]
n num 执行到下num行,num可以不填默认=1,不进入函数内部
step [num]
s num 执行到下num行,num可以不填默认=1,不进入函数内部
backtrace
bt 查看当前调用栈
print [value]
p value 打印变量信息
help
help layout 查看命令如何使用
调试php代码
1. 新增一个php文件
 
 
<?php
 
echo date('Y-m-d', strtotime("last day of +2month", strtotime('2020-05-31')));
 
2.查看php-fpm work进程PID
我这里通过修改php-fpm配置只启动一个work进程方便追踪
 
 
 
pm = static
 
pm.max_children = 1
 
 
 
 
[root@test ~]# ps aux|grep php-fpm
 
www        1127  0.0  0.1 279352  2816 ?        S    5月12   0:00 php-fpm: pool www
 
root      12224  0.0  0.0 112736   976 pts/0    S+   17:37   0:00 grep --color=auto php-fpm
 
3.追踪PID
 
 
 
 
[root@test ~]# gdb
 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-115.el7
 
Copyright (C) 2013 Free Software Foundation, Inc.
 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 
This is free software: you are free to change and redistribute it.
 
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
 
and "show warranty" for details.
 
This GDB was configured as "x86_64-redhat-linux-gnu".
 
For bug reporting instructions, please see:
 
<http://www.gnu.org/software/gdb/bugs/>.
 
(gdb) attach 1127
 
Attaching to process 1127
 
Reading symbols from /usr/local/php/sbin/php-fpm...done.
 
Reading symbols from /usr/lib64/libcrypt.so.1...Reading symbols
 
from /usr/lib/debug/usr/lib64/libcrypt-2.17.so.debug...done.
 
done.
 
4.打断点,这里在timelib_update_ts和do_years方法打了一个断点,这里需要你看下php源码,看你需要在哪里调试代码
 
 
(gdb) b timelib_update_ts
 
Breakpoint 1 at 0x48ba90: file /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c, line 499.
 
 
 
(gdb) b do_years
 
`Breakpoint 3 at 0x48bb95: file /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c, line 381.`
 
5.请求测试文件
请求之后发现没有立刻看到返回结果,被阻塞在了这里,说明执行到了断点的地方
 
 
[root@test ~]# curl localhost/3.php
 
6.查看调试信息
通过p *time可以看到变量time里面的内容
 
 
 
(gdb) c
 
Continuing.
 
 
 
Breakpoint 1, timelib_update_ts (time=time@entry=0x7fc63ec02000, tzi=tzi@entry=0x7fc63ec75000)
 
at /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c:499
 
499    {
 
(gdb) c
 
Continuing.
 
 
 
Breakpoint 3, timelib_update_ts (time=time@entry=0x7fc63ec02000, tzi=tzi@entry=0x7fc63ec75000)
 
at /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c:505
 
505        res += do_years(time->y);
 
(gdb) s
 
do_years (year=2020) at /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c:381
 
381        eras = (year - 1970) / 40000;
 
(gdb) s
 
timelib_update_ts (time=time@entry=0x7fc63ec02000, tzi=tzi@entry=0x7fc63ec75000)
 
at /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c:504
 
504        do_adjust_special(time);
 
(gdb) p *time
 
$1 = {y = 2020, m = 7, d = 31, h = 0, i = 0, s = 0, us = 0, z = 28800, tz_abbr = 0x7fc63ec71018 "CST",
 
tz_info = 0x7fc63ec75000, dst = 0, relative = {y = 0, m = 2,
 
    d = 0, h = 0, i = 0, s = 0, us = 0, weekday = 0, weekday_behavior = 0, first_last_day_of = 2, invert = 0,
 
    days = -99999, special = {type = 0, amount = 0},
 
    have_weekday_relative = 0, have_special_relative = 0}, sse = 0, have_time = 0, have_date = 0, have_zone = 0,
 
    have_relative = 1, have_weeknr_day = 0,
 
  sse_uptodate = 0, tim_uptodate = 0, is_localtime = 1, zone_type = 3}
 
(gdb)
 
下面是do_years方法的代码
 
 
 
 
 
static timelib_sll do_years(timelib_sll year)
 
{
 
    timelib_sll i;
 
    timelib_sll res = 0;
 
    timelib_sll eras;
 
 
 
    eras = (year - 1970) / 40000;
 
    if (eras != 0) {
 
        year = year - (eras * 40000);

(编辑:无锡站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读