本文给大家介绍关于如何使用gdb调试php(gdb 是c语言的代码调试工具,可以用来调试php、python、mysql等),希望对需要的朋友有所帮助!4.打断点,这里在
简介
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 focusbreak
- 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);
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代码实现年转化成时间戳
<?php
const 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视频教程》
相关阅读 更多
-
域名劫持什么意思?域名劫持原理及实现?域名劫持怎么解决? 时间:2025-10-30 -
什么是网络协议?它包括哪些要素和内容? 时间:2025-10-30 -
简述Zookeeper的原理和作用 时间:2025-10-30 -
什么是ZooKeeper ZooKeeper是干什么的 ZooKeeper和Nacos的区别 时间:2025-10-30 -
集线器和交换机在原理,实现与使用上有哪些区别? 时间:2025-10-30 -
集线器和交换机的功能是什么?区别在哪? 时间:2025-10-30
今日更新
-
SKL币2026年价格预测 币安行情分析与投资策略指南
阅读:18
-
【SEO优化标题】
小婷是什么梗 揭秘网络热梗小婷的爆火原因和表情包出处
阅读:18
-
MANTA币2026年价格预测及欧易交易教程 项目前景分析
阅读:18
-
2026全球十大加密货币交易所排名 新手投资入门指南
阅读:18
-
狗头是什么梗?揭秘聊天神回复背后的幽默暗号,看完秒懂!
阅读:18
-
2026最佳加密货币交易平台排行 新手入门必看指南
阅读:18
-
**"摆烂娃是什么梗?揭秘年轻人躺平自嘲新潮流"**
(注:严格控制在48字内,符合百度SEO标题规范,用疑问句式吸引点击,关键词前置,突出热点话题和用户需求。)
阅读:18
-
2026年加密货币新手必选5大交易所 安全靠谱交易平台排名
阅读:18
-
重返未来3.2版本迁流的盛宴今日开启-海量活动来袭
阅读:18
-
2026年最佳虚拟币交易所排名 币圈用户必看指南
阅读:18










