GDB调试教程,异步执行脚本程序代码

如果线上有一段php脚本,突然在某天出标题了,不处理然而经过没有脱离。那种气象或者是非凡休眠或者是有段死循环代码,可是大家怎么固定呢,大家以此时候最想驾驭的应当是以此剧本在那时候在做什么样啊。这几个是gdb+zbacktrace就有用了

简介

   GDB(GNU
debugger)是GNU开源公司揭橥的一个强劲的UNIX下的程序调试工具。可以行使它经过命令行的不二法门调试程序。它使你能在程序运行时考察程序的内部结构和内存的使用情况。你也得以应用它分析程序崩溃前的发出了怎么,从而找出程序崩溃的原委。相对于windows下的图形界面的VC等调节工具,它提供了更强有力的功能。假如想在Windows下利用gdb,须要安装MinGW或者CygWin,并且须要安插环境变量才方可采纳。

   一般的话,gdb已毕以下八个方面的干活:

   1、启动你的程序,修改部分事物,从而影响程序运行的表现。

   2、可以指定断点。程序执行到断点处会暂停实施。

   3、当你的主次停掉时,你能够用它来观察暴发了怎么着业务。

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

PHP的落到实处控制了它并未Java和.Net那种AppServer的定义,
而http合计是一个无状态的协议, php只可以被用户触发, 被调用,
调用后会自动退出内存, 没有常驻内存, 就没有办法准确的定时处理那么,
就算要求用PHP定时实施某些义务的话, 可以有以下俩个办法:

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

第一随便写一个测试脚本test.php,里面就写一个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就好了。
DiscuzGDB调试教程,异步执行脚本程序代码。!是判定在00:00随后,第二个执行者去实践的。第二种比较不可靠,
Apache重启了就得重新访问,  fastcgi倒是会好一些。

玩过Linux的人应有都知情,如若想让一个程序在后台运行,只要在执行命令的最后加上一个&符号就可以了。可是那种办法不是很保障,有些程序当你登出极端后它就会终止。那么如何让一个先后真的永远在后台执行呢。答案就是利用
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是很简单的。只要根据以下步骤一步步操作即可。

 
 1、可是安装以前,必须确保它所珍重的环境没难点。下边是它借助的看重性环境。

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

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

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

   3、解压压缩包。压缩包解压甘休后,进入解压后的目录。

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

   4、然后四遍举行如下命令,以便形成安装

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

主要的多少个函数:

 

php test.php

主题使用

ignore_user_abort(true),那么些函数的功力是,无论客户端是还是不是关闭浏览器,上面的代码都将获得实施。

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

 然后找到当前php进程

一声令下行格式

gdb    [-help] [-nx] [GDB调试教程,异步执行脚本程序代码。-q] [-batch]www.5929.com,
[-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了。

 代码如下

   www.5929.com 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命令开首推行脚本。

   第二种办法:

 
 启动后透过file命令指定要调节的次序。当你利用gdb调试完一个主次,想调试其它一个程序时,就足以不脱离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程序,从而切换了要调节的主次。

大家在做一个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
的命令行形式这一章,发现能一蹴即至这一题材,指出大家若是想用这么些点子的话先看看这一章。

 代码如下

www.5929.com 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)
......

1、在 Windows 平台下你可以将cli\php.exe 和 .php
文件的双击属性相关联,您也足以编制一个批处理公事来用 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
......

接下来写一个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中的布署职务中添加一个义务,让操作系统在某个时刻来运转那几个批处理文件。

翻开变量

 
 现在您早就会设置断点,查看断点附近的代码,并可以单步执行和继续执行。接下来您或许会想驾驭程序运行的有的境况,如查看变量的值。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” 的情势得以以十六进制格局查看变量值。

2、要是您使用 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);//等待5分钟}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

 

Leave a Comment.