【澳门葡京备用网址】找到php执行过程目前推行的代码,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就好了。
Discuz!是判定在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

【澳门葡京备用网址】找到php执行过程目前推行的代码,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] [-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命令最先施行脚本。

   第三种方法:

 
 启动后通过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
的命令行模式这一章,发现能缓解这一问题,提出我们如若想用这么些主意的话先看看这一章。

 代码如下

澳门葡京备用网址 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

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website