溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么使用gdb調(diào)試php

發(fā)布時(shí)間:2022-01-26 16:34:56 來(lái)源:億速云 閱讀:162 作者:柒染 欄目:編程語(yǔ)言

今天給大家介紹一下怎么使用gdb調(diào)試php。文章的內(nèi)容小編覺(jué)得不錯(cuò),現(xiàn)在給大家分享一下,覺(jué)得有需要的朋友可以了解一下,希望對(duì)大家有所幫助,下面跟著小編的思路一起來(lái)閱讀吧。

簡(jiǎn)介

gdb 是c語(yǔ)言的代碼調(diào)試工具
可以用來(lái)調(diào)試php、python、mysql

調(diào)試主要有4種形式

gdb:?jiǎn)?dòng)之后用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 ...]

常用調(diào)試命令

attach pid

例:如果向跟蹤調(diào)試mysql代碼
1.先找到mysql進(jìn)行ID:10111
怎么使用gdb調(diào)試php

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 增加斷點(diǎn)

  • info b 顯示斷點(diǎn)信息

  • delete num 刪除指定斷點(diǎn)

continue [num]

  • c num 執(zhí)行到num個(gè)斷點(diǎn),num可以不填默認(rèn)=1

next [num]

  • n num 執(zhí)行到下num行,num可以不填默認(rèn)=1,不進(jìn)入函數(shù)內(nèi)部

step [num]

  • s num 執(zhí)行到下num行,num可以不填默認(rèn)=1,不進(jìn)入函數(shù)內(nèi)部

backtrace

  • bt 查看當(dāng)前調(diào)用棧

print [value]

  • p value 打印變量信息

help

  • help layout 查看命令如何使用

調(diào)試php代碼

1. 新增一個(gè)php文件

<?php
echo date('Y-m-d', strtotime("last day of +2month", strtotime('2020-05-31')));

2.查看php-fpm work進(jìn)程PID

我這里通過(guò)修改php-fpm配置只啟動(dòng)一個(gè)work進(jìn)程方便追蹤

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.打斷點(diǎn),這里在timelib_update_tsdo_years方法打了一個(gè)斷點(diǎn),這里需要你看下php源碼,看你需要在哪里調(diào)試代碼

(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.請(qǐng)求測(cè)試文件

請(qǐng)求之后發(fā)現(xiàn)沒(méi)有立刻看到返回結(jié)果,被阻塞在了這里,說(shuō)明執(zhí)行到了斷點(diǎn)的地方

[root@test ~]# curl localhost/3.php

6.查看調(diào)試信息

通過(guò)p *time可以看到變量time里面的內(nèi)容

(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;
}

總結(jié)

通過(guò)gdb追蹤很方便我們debug代碼信息,查看底層代碼跳用棧,對(duì)學(xué)習(xí)源碼有很大的幫助
這里也總結(jié)下php strtotime方法的實(shí)現(xiàn)邏輯
如果當(dāng)前年>=1970,則循環(huán)判斷[1970-(當(dāng)前年-1)]中每一年是否是閏年,是閏年則86400366,不是則86400355  (86400是一天的秒數(shù)),月天時(shí)分秒計(jì)算邏輯不再累述,最后還會(huì)加上/減去時(shí)區(qū),上海是東八區(qū)會(huì)減去8小時(shí)。
東八區(qū)(UTC/GMT+08:00)是比世界協(xié)調(diào)時(shí)間(UTC)/格林尼治時(shí)間(GMT)快8小時(shí)的時(shí)區(qū),
附php代碼實(shí)現(xiàn)年轉(zhuǎn)化成時(shí)間戳
<?php

const YEARLEEP = 366;//閏年366天
const YEAR     = 365;//平年365天

//判斷是否是閏年
function is_leap($year)
{
    return ($year % 4 == 0) && ($year % 100 != 0 || $year % 400 == 0);
}

//將年轉(zhuǎn)換成時(shí)間戳
function getStime($year)
{
    $res = 0;
    for ($i = $year - 1; $i >= 1970; $i--) {
        if (is_leap($i)) {
            $res += YEARLEEP * 86400;
        } else {
            $res += YEAR * 86400;
        }
    }
    //上海是東八區(qū)要減8小時(shí)
    $res -= 8 * 3600;
    return $res;
}

echo getStime('2020');

以上就是怎么使用gdb調(diào)試php的全部?jī)?nèi)容了,更多與怎么使用gdb調(diào)試php相關(guān)的內(nèi)容可以搜索億速云之前的文章或者瀏覽下面的文章進(jìn)行學(xué)習(xí)哈!相信小編會(huì)給大家增添更多知識(shí),希望大家能夠支持一下億速云!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI