千家信息网

怎么使用gdb调试php

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,今天给大家介绍一下怎么使用gdb调试php。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。使用gdb调试php简介gdb
千家信息网最后更新 2025年01月31日怎么使用gdb调试php

今天给大家介绍一下怎么使用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

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文件

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 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:.(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_tsdo_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代码实现年转化成时间戳
= 1970; $i--) {        if (is_leap($i)) {            $res += YEARLEEP * 86400;        } else {            $res += YEAR * 86400;        }    }    //上海是东八区要减8小时    $res -= 8 * 3600;    return $res;}echo getStime('2020');

以上就是怎么使用gdb调试php的全部内容了,更多与怎么使用gdb调试php相关的内容可以搜索之前的文章或者浏览下面的文章进行学习哈!相信小编会给大家增添更多知识,希望大家能够支持一下!

0