您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

教你如何使用gdb调试php!

2026/2/21 8:24:46发布13次查看
本文给大家介绍关于如何使用gdb调试php(gdb 是c语言的代码调试工具,可以用来调试php、python、mysql等),希望对需要的朋友有所帮助!
使用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
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
breakb 增加断点info b 显示断点信息delete num 删除指定断点continue [num]c num 执行到num个断点,num可以不填默认=1next [num]n num 执行到下num行,num可以不填默认=1,不进入函数内部step [num]s num 执行到下num行,num可以不填默认=1,不进入函数内部backtracebt 查看当前调用栈print [value]p value 打印变量信息helphelp layout 查看命令如何使用调试php代码1. 新增一个php文件<?phpecho date('y-m-d', strtotime("last day of +2month", strtotime('2020-05-31')));
2.查看php-fpm work进程pid我这里通过修改php-fpm配置只启动一个work进程方便追踪
pm = staticpm.max_children = 1
[root@test ~]# ps aux|grep php-fpmwww 1127 0.0 0.1 279352 2816 ? s 5月12 0:00 php-fpm: pool wwwroot 12224 0.0 0.0 112736 976 pts/0 s+ 17:37 0:00 grep --color=auto php-fpm
3.追踪pid[root@test ~]# gdbgnu gdb (gdb) red hat enterprise linux 7.6.1-115.el7copyright (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 copyingand 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 1127attaching to process 1127reading 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_tsbreakpoint 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) ccontinuing.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:499499    {(gdb) ccontinuing.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:505505        res += do_years(time->y);(gdb) sdo_years (year=2020) at /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c:381381        eras = (year - 1970) / 40000;(gdb) stimelib_update_ts (time=time@entry=0x7fc63ec02000, tzi=tzi@entry=0x7fc63ec75000) at /opt/lnmp1.6/src/php-7.3.11/ext/date/lib/tm2unixtime.c:504504        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);        res += (secs_per_era * eras * 100);    }        if (year >= 1970) {        for (i = year - 1; i >= 1970; i--) {            //判断是否是闰年,闰年366天,平年365天            if (timelib_is_leap(i)) {                res += (days_per_lyear * secs_per_day);            } else {                res += (days_per_year * secs_per_day);            }        }    } else {        for (i = 1969; i >= year; i--) {            if (timelib_is_leap(i)) {                res -= (days_per_lyear * secs_per_day);            } else {                res -= (days_per_year * secs_per_day);            }        }    }    return res;}
总结通过gdb追踪很方便我们debug代码信息,查看底层代码跳用栈,对学习源码有很大的帮助
这里也总结下php strtotime方法的实现逻辑
如果当前年>=1970,则循环判断[1970-(当前年-1)]中每一年是否是闰年,是闰年则86400366,不是则86400355  (86400是一天的秒数),月天时分秒计算逻辑不再累述,最后还会加上/减去时区,上海是东八区会减去8小时。
东八区(utc/gmt+08:00)是比世界协调时间(utc)/格林尼治时间(gmt)快8小时的时区,
附php代码实现年转化成时间戳<?phpconst yearleep = 366;//闰年366天const year = 365;//平年365天//判断是否是闰年function is_leap($year){ return ($year % 4 == 0) && ($year % 100 != 0 || $year % 400 == 0);}//将年转换成时间戳function getstime($year){ $res = 0; for ($i = $year - 1; $i >= 1970; $i--) {        if (is_leap($i)) {            $res += yearleep * 86400;        } else {            $res += year * 86400;        }    }    //上海是东八区要减8小时    $res -= 8 * 3600;    return $res;}echo getstime('2020');
推荐学习:《php视频教程》
以上就是教你如何使用gdb调试php!的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product