gdb调试技巧,GDB调试教程

尽管线上有一段php脚本,突然在某天出难点了,不处理可是经过没有脱离。那种情况只怕是充足休眠可能是有段死循环代码,不过我们怎么定位呢,大家以此时候最想清楚的应该是其一本子在那儿在做什么吧。这么些是gdb+zbacktrace就有用了

gdb调试技巧,GDB调试教程。简介

   GDB(GNU
debugger)是GNU开源公司颁发的二个有力的UNIX下的程序调试工具。可以使用它经过命令行的措施调试程序。它使您能在程序运转时观看程序的内部结构和内存的接纳处境。你也得以选拔它分析程序崩溃前的发出了什么,从而找出程序崩溃的原因。相对于windows下的图形界面的VC等调节工具,它提供了更强劲的机能。即使想在Windows下使用gdb,需要安装MinGW或然CygWin,并且须求配备环境变量才得以应用。

   一般的话,gdb完结以下两个方面的做事:

   ① 、运营你的先后,修改部分事物,从而影响程序运营的一颦一笑。

   二 、可以钦命断点。程序执行到断点处会暂停实施。

   ③ 、当您的主次停掉时,你可以用它来寓目发生了哪些业务。

   肆 、动态的转移您程序的推行环境,尝试订正bug。

PHP的落实控制了它没有Java和.Net那种AppServer的定义,
而http共商是三个无状态的情商, php只好被用户触发, 被调用,
调用后会自动退出内存, 没有常驻内存, 就没有主意准确的定时处理那么,
假如须求用PHP定时举办某个职务以来, 可以有以下俩个格局:

在Linux下要让2个脚本挂在后台执行可以在指令的末梢加上1个 “&”
符号,有时候那还不够,必要依赖nohup命令,关于nohup,

第3随便写三个测试脚本test.php,里面就写3个sleep函数,换到死循环也可以。

安装

 
 在装置gdb在此以前,先鲜明你的linux操作系统是不是安装了gdb。你可以动用如下命令来规定是不是安装了gdb。

1
#gdb -help

 
 倘若已经设置了gdb,那么将会体现它能运用的拥有参数。如若没有设置,我们得以经过以下两种艺术来安装。

Linux下crontab, windows下布置职责找个被一再调用的网页,
里面加上二个检测代码set_time_limit(0);ignore_user_abort(true);死循环第二个法子是最广大的,
借使php服务器上从不权力去crontab,
也足以找二个友好的机械定期crontab去哀告服务器第①种方法,
论坛上定时清理新帖基本上就是这么达成的, 尽管人气不旺的话,
可以设想去其他火爆点的论坛里面发个图片,
调用本人的php来落到实处贰个trigger就好了。
Discuz!是判定在00:00从此,第2个执行者去实施的。第2种相比较不可相信,
Apache重启了就得重新访问,  fastcgi倒是会好一点。

玩过Linux的人应有都晓得,如果想让2个程序在后台运转,只要在执行命令的结尾加上贰个&符号就可以了。然则那种措施不是很保证,有个别程序当你登出极端后它就会终止。那么怎么样让2个先后真的永远在后台执行呢。答案就是行使
nohub 命令,格式为:

<?php
function Mecho($i){
 echo $i.PHP_EOL;
}
$i = 20;
while($i>0){

if($i%2==0){
  Mecho($i);
}
sleep(100000);
$i--;
}

由此yum命令安装

   通过yum安装的命令行如下:

1
#yum install gdb

上边的那段代码,可以在眼下文件夹下,生成多个test.txt,并每隔20秒,往里面写入贰个岁月戳,无论客户端是还是不是关闭浏览器。

nohup 执行顺序的一声令下 &

zbacktrace下载php源码包里面就有,当前自己的环境是新装的,当前的php版本是php7.2.9

经过rpm包格局安装

 
 从

1
#rpm -ivh ./gdb-7.8.1.rpm

<?php
ignore_user_abort(true);set_time_limit(0);functionwrite_txt()
{if(!file_exists(”test.txt”)){$fp=fopen(”test.txt”,”wb”);fclose($fp);}$str=file_get_contents(’test.txt’);$str.=
“\r\n”.date(”H:i:s”);$fp=fopen(”test.txt”,”wb”);fwrite($fp,$str);fclose($fp);}functiondo_cron(){usleep(20000000);write_txt();}while(1){do_cron();}

如若程序有出口,它会试着把出口写入执
行上述命令的此时此刻文件夹下的 nohup.out
文件中,当写入失利,就会写当前用户的$HOME目录下的nohup.out 中。

直接cli执行test.php

由此源码格局安装

   安装gdb是很简单的。只要依据以下步骤一步步操作即可。

 
 壹 、可是安装从前,必须有限支持它所看重的条件没问题。上边是它依靠的看重环境。

   * c语言编译器。推荐应用gcc。

   * 确保有不少于150M的磁盘空间。

   贰 、然后打开那一个网址
ftp://sourceware.org/pub/gdb/releases/,下载须要安装的gdb源码包。大家下载的源码包是gdb-7.8.1.tar.gz。

   三 、解压压缩包。压缩包解压为止后,进入解压后的目录。

1
2
3
#gzip -d gdb-7.8.1.tar.gz
#tar xfv gdb-7.8.1.tar.gz
#cd gdb-7.8.1

   肆 、然后两次实施如下命令,以便形成安装

1
2
3
#./configure
#make
#make install

一言九鼎的多个函数:

 

php test.php

骨干使用

ignore_user_abort(true),那些函数的出力是,无论客户端是还是不是关闭浏览器,下边的代码都将拿到实施。

CLI环境和Web环境举行的操作还不太相同。先来说CLI环境,那里要求用上nohup和&,同时还要把指定输出,借使不想要输出结果,可以把出口定向到/dev/null中。今后来做2个测试,若是在一个索引中有main.php、sub1.php和sub2.php,其中sub1和sub2内容同样都让sleep函数暂停一段时间。代码如下:

 然后找到当前php进度

命令行格式

gdb    [-help] [-nx] [-q] [-batch]
[-cd=dir] [-f] [-b bps] [-tty=dev]
[-s symfile] [-e prog] [-se prog] [-c core]
[-x

             cmds] [-d亚洲必赢官网 , dir] [prog[core|procID]]

set_time_limit(0),这几个函数的功能是,废除php文件的实施时间,若是没有那么些函数的话,暗许php的进行时间是30秒,相当于说30秒后,那么些文件就say
goodbay了。

 代码如下

   亚洲必赢官网 1

常用功效介绍

 
 网上的一部分科目基本上都以介绍使用gdb调试c或然c++语言编写的顺序的。大家那节紧要表达什么利用gdb调试php程序。我们的php脚本如下:

   文件名为test.php,代码如下:

1
2
3
4
5
6
<?php
echo "hello \n";
for($i = 0; $i < 10; $i++){    
    echo $i."\n";    
    sleep(10); }
?>

另外usleep在PHP5.0之后,支持windows操作系统。

//main.php
<?php
    $cmd = ‘nohup php ./sub.php >./tmp.log  &’;
    exec($cmd);
    $cmd = ‘nohup php ./sub1.php >/dev/null  &’;
    exec($cmd);
?>

 然后用gdb调试

启动gdb

   运行gdb可以使用如下二种办法:

   第叁种格局:

   运维的时候钦命要进行的脚本。

1
2
3
4
5
6
7
#sudo gdb /usr/bin/php
......
Reading symbols from /home/admin/fpm-php5.5.15/bin/php...done.
(gdb) set args ./test.php
(gdb) r
Starting program: /home/admin/fpm-php5.5.15/bin/php ./test.php
......

   运行的时候钦赐php程序的门径。

   Reading symbols from /home/admin/fpm-php5.5.15/bin/php…done.
表明已经加载了php程序的符号表。

   使用set args 命令钦命php命令的参数。

 
 使用r命令开始施行脚本。r即为run的简写格局。也足以运用run命令开首实践脚本。

   第1种方式:

 
 运营后通过file命令钦赐要调节的先后。当你利用gdb调试完一个顺序,想调试其它2个先后时,就可以不脱离gdb便能切换要调节的程序。具体操作步骤如下:

1
2
3
4
5
6
7
8
9
#sudo gdb ~/home/test/exproxy
......
Reading symbols from /home/hailong.xhl/exproxy/test/exproxy...(no debugging symbols found)...done.
(gdb) file /home/admin/fpm-php/bin/php
Reading symbols from /usr/bin/php...done.
(gdb) set args ./test.php
(gdb) r
Starting program: /home/admin/fpm-php5.5.15/bin/php ./test.php
......

 
 下边的事例中大家先利用gdb加载了程序exproxy进行调节。然后通过file命令加载了php程序,从而切换了要调节的顺序。

大家在做1个php
邮件发送难点是常常会遇见如此的题目,就是用户订阅一些素材必要定时发送到用户的邮箱中去。去网上搜索了一晃,发今后如此的稿子不多,本文介绍了一种用PHP完结的方法,作者用PHP的时刻相当长,欢迎我们PP。

//sub1.php sub2.php
<?php
    sleep(100000);
?>

gdb -p 56571

得到协理消息

 
 gdb的子命令很多,大概有些你也不太了解。没关系,gdb提供了help子命令。通过那个help子命令,大家得以通晓内定子命令的片段用法。如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#gdb
......
(gdb) help set
Evaluate expression EXP and assign result to variable VAR, using assignment
syntax appropriate for the current language (VAR = EXP or VAR := EXP for
example).  VAR may be a debugger "convenience" variable (names starting
with $), a register (a few standard names starting with $), or an actual
variable in the program being debugged.  EXP is any valid expression.
Use "set variable" for variables with names identical to set subcommands.
  
With a subcommand, this command modifies parts of the gdb environment.
You can see these environment settings with the "show" command.
  
List of set subcommands:
  
set annotate -- Set annotation_level
set architecture -- Set architecture of target
set args -- Set argument list to give program being debugged when it is started
.......
(gdb) help set args
Set argument list to give program being debugged when it is started.
Follow this command with any number of args, to be passed to the program.
......

 
 可知,通过help命令,我们得以通晓命令的功效和利用格局。如若那么些子命令还有一些子命令,那么它的全体子命令也会列出来。如上,set命令的set
args等子命令也都列出来了。你还足以行使help命令来询问set
args的更详细的消息。

一 、要兑现定时发送,主要消除难点是定时。

上述文件中main.php是作为主脚本,在命令行中执行php
main.php,可以看来main.php脚本很快就执行完并脱离。在利用ps
aux | grep
sub命令搜索进度,应该可以在后台看到上述的七个子脚本,表明成功挂起了子脚本。

 调试

安装断点

 
 为啥要设置断点呢?设置断点后,我们就可以钦点程序执行到钦赐的点后终止。以便大家更详尽的跟踪断点附近程序的实施意况。

   设置断点的命令是break,缩写形式为b。

   设置断点有广大主意。下边大家举例表明下常用的两种形式。

  我们在写程序时必要加个什么if
有个别时刻=有个别时刻则发送,但是要贯彻那个进度,面临的难题是,大家要实践那个页面才能发送。所以主要解决的标题是怎么到时让服务器定时举办这几个页面,那样落成起来好像比较困难。

在Web环境下,执行php脚本都以Web服务器开启的cgi进度来拍卖,只要脚本不脱离,就会向来占据该cgi进度,当运行的全数cgi进程都被占用完后就不或许在拍卖新的请求。所以对这个只怕会很为难的台本,可以利用异步的法门。运营子脚本的章程和CLI差不离,必需求使用&和点名输出(只能够是定向到/dev/null),然而无法应用nohup。例如:

source /usr/local/src/php-7.2.9/.gdbinit
zbacktrace 

依据文件名和行号钦点断点

 

 
 若是您的主次是用c恐怕c++写的,那么你可以动用“文件名:行号”的样式设置断点。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
#gdb /usr/bin/php
(gdb) set  args ./test.php
(gdb) b basic_functions.c:4439
Breakpoint 6 at 0x624740: file /home/php-5.5.15/ext/standard/basic_functions.c, line 4439.
(gdb) r
Starting program: /home/fpm-php5.5.15/bin/php ./test.php
hello
0
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
(gdb)

   示例中的(gdb) b basic_functions.c:4439
是安装了断点。断点的地点是basic_functions.c文件的4439行。使用r命令执行脚本时,当运维到4439行时就会中断。暂停的时候会把断点附近的代码给显示出来。可知,断点处是zif_sleep方法。这个zif_sleep方法就是大家php代码中sleep方法在php内核中的已毕。依据专业,php内置提供的办法名前面加上zif_,就是那些点子在php内核可能增添中贯彻时定义的章程名。

贰 、小编查看PHP手册,找到了PHP
的命令行形式这一章,发现能一举成功这一标题,提议大家即便想用这一个点子的话先看看这一章。

 代码如下

亚洲必赢官网 2

依据文件名和格局名钦点断点

 
 有个别时候,手头没有源代码,不驾驭要打断点的具体地方。不过我们依据php的命名规范知道方法名。如,大家通晓php程序中调用的sleep方法,在
php内核中完毕时的措施名是zif_sleep。那时,大家就可以通过”文件名:方法名”的办法打断点。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
#gdb /usr/bin/php
(gdb) set  args ./test.php
(gdb) b basic_functions.c:zif_sleep
Breakpoint 6 at 0x624740: file /home/php-5.5.15/ext/standard/basic_functions.c, line 4439.
(gdb) r
Starting program: /home/fpm-php5.5.15/bin/php ./test.php
hello
0
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
(gdb)

   别的,如若您不清楚文书名的话,你也足以只钦定方法名。命令示例如下:

1
2
3
......
(gdb)b zif_sleep
......

三 、化解办法:

<?php
    $cmd = ‘php PATH_TO_SUB1/sub1.php >/dev/null  &’;
    exec($cmd);
    $cmd = ‘php PATH_TO_SUB1/sub2.php >/dev/null  &’;
    exec($cmd);
?>

 这一个时候就明白了是在test.php的11行 sleep函数导致的经过sleep。

设置条件断点

 
 假若按下面的不二法门设置断点后,每一遍执行到断点地方都会中断。有时候卓殊厌恶。大家只想在钦赐条件下才中断。那时候依据规则设置断点就有了用武之地。设置条件断点的款式,就是在安装断点的主题格局背后增加if条件。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
......
(gdb) b zif_sleep if num > 0
Breakpoint 9 at 0x624740: file /home/php_src/php-5.5.15/ext/standard/basic_functions.c, line 4439.
(gdb) r
Starting program: /home/fpm-php5.5.15/bin/php ./test.php
hello
0
  
Breakpoint 9, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
(gdb)
......

一 、在 Windows 平台下你可以将cli\php.exe 和 .php
文件的双击属性相关联,您也可以编制3个批处理公事来用 PHP
执行脚本。我们把写好的程序放在一个索引下如 E:\web\mail.php

当在浏览器中走访该脚本文件,可以看出浏览器里面响应完结,同时选取ps命令查看后台可以看来sub1和sub2脚本。

  

查看断点

   可以使用info
breakpoint查看断点的情事。包括都设置了那几个断点,断点被命中的次数等音讯。示例如下:

1
2
3
4
5
6
7
8
......
(gdb) info breakpoint
Num     Type           Disp Enb Address            What
9       breakpoint     keep y   0x0000000000624740 in zif_sleep at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
    stop only if num > 0
    breakpoint already hit 1 time
10      breakpoint     keep y   0x0000000000624740 in zif_sleep at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
......

接下来写2个windows批处理公事内容如下。

注意上述例子中如果php命令不在PATH中,需求内定命令完整的门径。推荐应用完全路径,尤其是在Web下

 

删除断点

   对于低效的断点大家可以去除。删除的吩咐格式为 delete breakpoint
断点编号。info
breakpoint命令显示结果中的num列就是编号。删除断点的示范如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
......
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
9       breakpoint     keep y   0x0000000000624740 in zif_sleep at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
    stop only if num > 0
    breakpoint already hit 1 time
10      breakpoint     keep y   0x0000000000624740 in zif_sleep at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
(gdb) info breakpoint
Num     Type           Disp Enb Address            What
9       breakpoint     keep y   0x0000000000624740 in zif_sleep at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
    stop only if num > 0
    breakpoint already hit 1 time
10      breakpoint     keep y   0x0000000000624740 in zif_sleep at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
(gdb) delete 9
(gdb) info breakpoint
Num     Type           Disp Enb Address            What
10      breakpoint     keep y   0x0000000000624740 in zif_sleep at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
(gdb)
......

   上边的例子中大家删除了数码为9的断点。

@D:\php\cli\php.exe E:\web\mail.php >d:\php\cli\sendmail.log

查看代码

 
 断点设置完后,当程序运营到断点处就会搁浅。暂停的时候,大家得以查看断点附近的代码。查看代码的子命令是list,缩写方式为l。彰显的代码行数为10行,基本上以断点处为主导,向上向下各显示几行代码。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#gdb /usr/bin/php
(gdb) set  args ./test.php
(gdb) b basic_functions.c:zif_sleep
Breakpoint 6 at 0x624740: file /home/php-5.5.15/ext/standard/basic_functions.c, line 4439.
(gdb) r
Starting program: /home/fpm-php5.5.15/bin/php ./test.php
hello
0
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
(gdb)l
4434    /* }}} */
4435   
4436    /* {{{ proto void sleep(int seconds)
4437       Delay for a given number of seconds */
4438    PHP_FUNCTION(sleep)
4439    {
4440        long num;
4441   
4442        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {
4443            RETURN_FALSE;

   其它,你可以能够因而点名行号恐怕措施名来查阅相关代码。

   钦命行号查看代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
......
(gdb) list 4442
4437       Delay for a given number of seconds */
4438    PHP_FUNCTION(sleep)
4439    {
4440        long num;
4441   
4442        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {
4443            RETURN_FALSE;
4444        }
4445        if (num < 0) {
4446            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of seconds must be greater than or equal to 0");
......

   指定方法名查看代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
......
(gdb) list zif_sleep
4434    /* }}} */
4435   
4436    /* {{{ proto void sleep(int seconds)
4437       Delay for a given number of seconds */
4438    PHP_FUNCTION(sleep)
4439    {
4440        long num;
4441   
4442        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {
4443            RETURN_FALSE;
......

Pause

单步执行

 
 断点附近的代码你驾驭后,这时候你就足以运用单步执行一条一条语句的去执行。能够每二十七日查看执行后的结果。单步执行有五个指令,分别是step和next。那八个指令的区分在于:

   step 一条语句一条语句的实践。它有二个别名,s。

   next
和step类似。只是当境遇被调用的点未时,不会进来到被调用方法中一条一条语句执行。它有壹个别名n。

   恐怕您对这八个指令还有个别迷惑。下边大家用五个例证来给你演示下。

   step命令示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#gdb /usr/bin/php
(gdb) set  args ./test.php
(gdb) b basic_functions.c:zif_sleep
Breakpoint 6 at 0x624740: file /home/php-5.5.15/ext/standard/basic_functions.c, line 4439.
(gdb) r
Starting program: /home/fpm-php5.5.15/bin/php ./test.php
hello
0
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
.......
(gdb) s
4442        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {
(gdb) s
zend_parse_parameters (num_args=1, type_spec=0x81fc41 "l") at /home/admin/php_src/php-5.5.15/Zend/zend_API.c:917
917 {

 
 可知,step命令进入到了被调用函数中zend_parse_parameters。使用step命令也会在这么些方法中一行一行的单步执行。

   next命令示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#gdb /usr/bin/php
(gdb) set  args ./test.php
(gdb) b basic_functions.c:zif_sleep
Breakpoint 6 at 0x624740: file /home/php-5.5.15/ext/standard/basic_functions.c, line 4439.
(gdb) r
Starting program: /home/fpm-php5.5.15/bin/php ./test.php
hello
0
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
.......
(gdb) n
4442        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {
(gdb) n
4445        if (num < 0) {

   可知,使用next命令只会在本方法中单步执行。

那个D:\php\cli\php.exe是笔者的PHP安装文件所在目录。Php.exe就是windows PHP命令行格局的次第。

继续执行

 
 run命令是从头初叶执行,假如我们只是想继续执行就足以采纳continue命令。它的机能就是从暂停处继续执行。命令的简写格局为c。继续执行进度中相见断点或然观看点变化如故会中断。示例代码如下:

1
2
3
4
5
6
7
8
9
......
(gdb) c
Continuing.
6
  
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/admin/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
......

好的,大家保留这一个文件为mail.bat然后的windows中的安顿任务中添加3个职分,让操作系统在有个别时间来运维那个批处理公事。

查看变量

 
 现在您早已会安装断点,查看断点附近的代码,并得以单步执行和继续执行。接下来你大概会想精晓程序运营的一部分场合,如查看变量的值。print命令正好满意了您的急需。使用它打印出变量的值。print命令的简写格局为p。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
......
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
......
(gdb) n
4442        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {
(gdb) n
4445        if (num < 0) {
(gdb) print num
$1 = 10
(gdb)
......

 
 打印出的num的值为10,正好是我们在php代码中调用sleep方法传的值。其它可以使用“print/x
my var” 的方式得以以十六进制情势查看变量值。

贰 、若是你使用 Unix 系统,您须要在您的 PHP
脚本的最前面加上一行特殊的代码,使得它可以被执行,那样系统就能知道用怎么着的先后要运维该脚本。为
Unix 系统增添的第壹行代码不会影响该脚本在Windows
下的周转,因而你也得以用该格局编写跨平台的剧本程序。

设置变量

 
 使用print命令查看了变量的值,假如感觉这几个值不符合预期,想修改下那个值,再看下执行职能。这种情景下,大家该如何是好吧?平时状态下,大家会修改代码,再重复履行代码。使用gdb的set命令,一切将变得更不难。set命令可以直接改动变量的值。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
......
Breakpoint 1, zif_sleep (ht=1, return_value=0x7ffff425a398, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/php_src/php-5.5.15/ext/standard/basic_functions.c:4439
4439    {
......
(gdb) print num
$4 = 10
(gdb) set num = 2
(gdb) print num
$5 = 2
......

   上边的代码中大家是把sleep函数传入的10改为了2。即,sleep
2秒。注意,大家演示中修改的变量num是局地变量,只能对这次函数调用有效。下次再调用zif_sleep方法时,又会被设置为10。

 ignore_user_abort();//关掉浏览器,PHP脚本也足以持续执行.set_time_limit(0);//通过set_time_limit(0)可以让程序无界定的举行下去$interval=60*30;//每隔半时辰运营do{//那里是你要推行的代码sleep($interval);//等待6分钟}while(true);

安装观察点

 
 设置观看点的效率就是,当被考察的变量暴发变化后,程序就会中断实施,并把变量的原值和新值都会浮现出来。设置观望点的指令是watch。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
......
(gdb) watch num
Hardware watchpoint 3: num
(gdb) c
Continuing.
Hardware watchpoint 3: num
  
Old value = 1
New value = 10
0x0000000000713333 in zend_parse_arg_impl (arg_num=1, arg=0x7ffff42261a8, va=0x7fffffffaf70, spec=0x7fffffffaf30, quiet=0)
    at /home/admin/php_src/php-5.5.15/Zend/zend_API.c:372
372                         *p = Z_LVAL_PP(arg);
(gdb)
......

 
 上例中num值从1变成了10时,程序暂停了。须要注意的是,你的顺序中恐怕有多少个同名的变量。那么使用watch命令会观看尤其变量呢?那么些要凭借于变量的成效域。即,在使用watch设置观望点时,可以平昔访问的变量就是被观望的变量。

其余有效的吩咐

   backtrace 简写方式为bt。查看程序执行的堆栈新闻。

   finish  执行到当前函数的终止

 

 

 命令  解释  示例
file <文件名> 加载被调试的可执行程序文件。
因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。
(gdb) file gdb-sample
r Run的简写,运行被调试的程序。
如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。
(gdb) r
c Continue的简写,继续执行被调试程序,直至下一个断点或程序结束。 (gdb) c
b <行号>
b <函数名称>
b *<函数名称>
b *<代码地址>

d [编号]

b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。
其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。

d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。

(gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c

(gdb) d

s, n s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
n: 执行一行源程序代码,此行代码中的函数调用也一并执行。

s 相当于其它调试器中的“Step Into (单步跟踪进入)”;
n 相当于其它调试器中的“Step Over (单步跟踪)”。

这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。

(gdb) s
(gdb) n
si, ni si命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。 (gdb) si
(gdb) ni
p <变量名称> Print的简写,显示指定变量(临时变量或全局变量)的值。 (gdb) p i
(gdb) p nGlobalVar
display …

undisplay <编号>

display,设置程序中断后欲显示的数据及其格式。
例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令
“display /i $pc”
其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。

undispaly,取消先前的display设置,编号从1开始递增。

(gdb) display /i $pc

(gdb) undisplay 1

i Info的简写,用于显示各类信息,详情请查阅“help i”。 (gdb) i r
q Quit的简写,退出GDB调试环境。 (gdb) q
help [命令名称] GDB帮助命令,提供对GDB名种命令的解释说明。
如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。
(gdb) help display

 

网站地图xml地图