【php】使用gdb調試php程式

來源:互聯網
上載者:User

標籤:

1、簡介

GDB是GNU開源組織發布的一個強大的UNIX下的程式調試工具。如果你是在 UNIX平台下做軟體,你會發現GDB這個調試工具有比VC、BCB的圖形化調試器更強大的功能。同時GDB也具有例如ddd這樣的圖形化的調試端

2、調試C/C++程式

直接上代碼了

#include<iostream>using namespace std;long factorial(int n);  int main(){    int n(0);    cin>>n;    long val=factorial(n);    cout<<val<<endl;    cin.get();    return 0;} long factorial(int n){    long result(1);    while(n--)    {           result*=n;    }       return result;}

編譯

g++ k.cpp -g -Wall -Werror -o main

開始調試

[[email protected] code]# gdb ./mainGNU gdb (GDB) Red Hat Enterprise Linux (7.2-83.el6)Copyright (C) 2010 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 "i686-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /code/main...done.(gdb) l warning: Source file is more recent than executable.1       #include<iostream>2       using namespace std;3       long factorial(int n);45       int main()6       {7           int n(0);8           cin>>n;9           long val=factorial(n);10          cout<<val<<endl;(gdb) 

設定斷點 break linenumber

(gdb) b 9Breakpoint 1 at 0x80486f9: file k.cpp, line 9.(gdb) rStarting program: /code/main 4Breakpoint 1, main () at k.cpp:99           long val=factorial(n);

設定觀察點 watch var

(gdb) sfactorial (n=4) at k.cpp:1717          long result(1);(gdb) l12          return 0;13      }1415      long factorial(int n)16      {17          long result(1);18          while(n--)19          {20              result*=n;21          }(gdb) watch nHardware watchpoint 2: n(gdb) watch resultHardware watchpoint 3: result(gdb) cContinuing.Hardware watchpoint 3: resultOld value = 0New value = 1factorial (n=4) at k.cpp:1818          while(n--)(gdb) Continuing.Hardware watchpoint 2: nOld value = 4New value = 30x08048764 in factorial (n=3) at k.cpp:1818          while(n--)(gdb) Continuing.Hardware watchpoint 3: resultOld value = 1New value = 3factorial (n=3) at k.cpp:1818          while(n--)(gdb) Continuing.Hardware watchpoint 2: nOld value = 3New value = 20x08048764 in factorial (n=2) at k.cpp:1818          while(n--)(gdb) Continuing.Hardware watchpoint 3: resultOld value = 3New value = 6factorial (n=2) at k.cpp:1818          while(n--)(gdb) Continuing.Hardware watchpoint 2: nOld value = 2New value = 10x08048764 in factorial (n=1) at k.cpp:1818          while(n--)(gdb) Continuing.Hardware watchpoint 2: nOld value = 1New value = 00x08048764 in factorial (n=0) at k.cpp:1818          while(n--)(gdb) Continuing.Watchpoint 2 deleted because the program has left the block inwhich its expression is valid.Watchpoint 3 deleted because the program has left the block inwhich its expression is valid.0x08048705 in main () at k.cpp:99           long val=factorial(n);(gdb) p val$1 = 11476980(gdb) 

可以看到是while那裡,導致n越界了,fix

while(n>0) //doesn‘t let n reach 0{  result*=n;  n--;        //decrements only after the evaluation}

一些快捷命令

l – listp – print print {variable}c – continues – stepb - break  break line_number/break [file_name]:line_number/break [file_name]:func_namer - runset <var> = <value>watch <var>ENTER: pressing enter key would execute the previously executed command again.

c/n/s的區別

  • c or continue: Debugger will continue executing until the next break point.
  • n or next: Debugger will execute the next line as single instruction.
  • s or step: Same as next, but does not treats function as a single instruction, instead goes into the function and executes it line by line
3、調試PHP程式

PHP代碼

<?php.   for($i = 0; $i < 10; $i++){    echo $i."\n";    sleep(3);    if(in_array($i,[1,9,20])){        print_r($i*$i);        var_dump($i*$i);                                                                                                                      print $i*$i;    }       }

開始調試,加上斷點

[[email protected] code]# gdb php    GNU gdb (GDB) Red Hat Enterprise Linux (7.2-83.el6)Copyright (C) 2010 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 "i686-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /usr/bin/php...done.(gdb) b zif_sleepBreakpoint 1 at 0x8435180: file /usr/local/src/php-5.5.23/ext/standard/basic_functions.c, line 4449.(gdb) b zif_in_arrayBreakpoint 2 at 0x8426923: file /usr/local/src/php-5.5.23/ext/standard/array.c, line 1215.(gdb) b zif_print_rBreakpoint 3 at 0x8438273: file /usr/local/src/php-5.5.23/ext/standard/basic_functions.c, line 5553.(gdb) b zif_var_dumpBreakpoint 4 at 0x847d296: file /usr/local/src/php-5.5.23/ext/standard/var.c, line 178.(gdb) b zif_printfFunction "zif_printf" not defined.Make breakpoint pending on future shared library load? (y or [n]) n(gdb) b zif_sprintfFunction "zif_sprintf" not defined.Make breakpoint pending on future shared library load? (y or [n]) n(gdb) b printfBreakpoint 5 at 0x806a390(gdb) b memcpyBreakpoint 6 at 0x8069390(gdb) b zif_printFunction "zif_print" not defined.Make breakpoint pending on future shared library load? (y or [n]) n(gdb) b zif_echo Function "zif_echo" not defined.Make breakpoint pending on future shared library load? (y or [n]) n(gdb) info bNum     Type           Disp Enb Address    What1       breakpoint     keep y   0x08435180 in zif_sleep at /usr/local/src/php-5.5.23/ext/standard/basic_functions.c:44492       breakpoint     keep y   0x08426923 in zif_in_array at /usr/local/src/php-5.5.23/ext/standard/array.c:12153       breakpoint     keep y   0x08438273 in zif_print_r at /usr/local/src/php-5.5.23/ext/standard/basic_functions.c:55534       breakpoint     keep y   0x0847d296 in zif_var_dump at /usr/local/src/php-5.5.23/ext/standard/var.c:1785       breakpoint     keep y   0x0806a390 <[email protected]>6       breakpoint     keep y   0x08069390 <[email protected]>(gdb) 

加幾個斷點測試一下 syntax:break [file_name]:func_name,這裡大致可以看一下 echo print等不是函數了

然後開始調試

(gdb) run kk.php ( or set args ./kk.php && r)Starting program: /usr/bin/php kk.php[Thread debugging using libthread_db enabled]0Breakpoint 3, zif_sleep (ht=1, return_value=0xb7fbd6f0, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)    at /usr/local/src/php-5.5.23/ext/standard/basic_functions.c:44494449            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {(gdb) 

這裡我們可以看一下zif_sleep 函數 return_value 返回的是什麼

(gdb) p *return_value$1 = {value = {lval = 1515870810, dval = 1.7838867517321418e+127, str = {val = 0x5a5a5a5a <Address 0x5a5a5a5a out of bounds>,       len = 1515870810}, ht = 0x5a5a5a5a, obj = {handle = 1515870810, handlers = 0x5a5a5a5a}}, refcount__gc = 1, type = 0 ‘\000‘, is_ref__gc = 0 ‘\000‘}(gdb) p return_value->value$2 = {lval = 1515870810, dval = 1.7838867517321418e+127, str = {val = 0x5a5a5a5a <Address 0x5a5a5a5a out of bounds>,     len = 1515870810}, ht = 0x5a5a5a5a, obj = {handle = 1515870810, handlers = 0x5a5a5a5a}}(gdb) p return_value->value->lval$3 = 1515870810

我們還可以使用內建的gdbinit來調試

(gdb) source /usr/local/src/php-5.5.23/.gdbinit(gdb) zbacktrace[0xb7fa1144] sleep(3) /code/kk.php:4

查看當前堆棧,PHP核心的執行過程

(gdb) bt#0  zif_sleep (ht=1, return_value=0xb7fbd6f0, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)    at /usr/local/src/php-5.5.23/ext/standard/basic_functions.c:4449#1  0x085f6870 in execute_internal (execute_data_ptr=0xb7fa1144, fci=0x0, return_value_used=0)    at /usr/local/src/php-5.5.23/Zend/zend_execute.c:1484#2  0x085aea5f in dtrace_execute_internal (execute_data_ptr=0xb7fa1144, fci=0x0, return_value_used=0)    at /usr/local/src/php-5.5.23/Zend/zend_dtrace.c:97#3  0x00935c33 in pt_execute_core (internal=1, execute_data=0xb7fa1144, fci=0x0, rvu=0)    at /usr/local/src/trace-0.3.0/extension/trace.c:941#4  0x00935e49 in pt_execute_internal (execute_data=0xb7fa1144, fci=0x0, return_value_used=0)    at /usr/local/src/trace-0.3.0/extension/trace.c:1005#5  0x085f7523 in zend_do_fcall_common_helper_SPEC (execute_data=0xb7fa1144) at /usr/local/src/php-5.5.23/Zend/zend_vm_execute.h:552#6  0x085fb2a9 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0xb7fa1144) at /usr/local/src/php-5.5.23/Zend/zend_vm_execute.h:2332#7  0x085f6deb in execute_ex (execute_data=0xb7fa1144) at /usr/local/src/php-5.5.23/Zend/zend_vm_execute.h:363#8  0x085ae9dc in dtrace_execute_ex (execute_data=0xb7fa1144) at /usr/local/src/php-5.5.23/Zend/zend_dtrace.c:73#9  0x00935c5e in pt_execute_core (internal=0, execute_data=0xb7fa1144, fci=0x0, rvu=0)    at /usr/local/src/trace-0.3.0/extension/trace.c:946#10 0x00935e10 in pt_execute_ex (execute_data=0xb7fa1144) at /usr/local/src/trace-0.3.0/extension/trace.c:1000#11 0x085f6e4a in zend_execute (op_array=0xb7fbc7b4) at /usr/local/src/php-5.5.23/Zend/zend_vm_execute.h:388#12 0x085c1cf2 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/local/src/php-5.5.23/Zend/zend.c:1327#13 0x085470f9 in php_execute_script (primary_file=0xbffff4a4) at /usr/local/src/php-5.5.23/main/main.c:2525#14 0x0865af46 in do_cli (argc=2, argv=0x8b9b908) at /usr/local/src/php-5.5.23/sapi/cli/php_cli.c:994#15 0x0865bff3 in main (argc=2, argv=0x8b9b908) at /usr/local/src/php-5.5.23/sapi/cli/php_cli.c:1378

查看程式碼片段

(gdb) l4444       Delay for a given number of seconds */4445    PHP_FUNCTION(sleep)4446    {4447            long num;44484449            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {4450                    RETURN_FALSE;4451            }4452            if (num < 0) {4453                    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of seconds must be greater than or equal to 0");(gdb) l 44504445    PHP_FUNCTION(sleep)4446    {4447            long num;44484449            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {4450                    RETURN_FALSE;4451            }4452            if (num < 0) {4453                    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of seconds must be greater than or equal to 0");4454                    RETURN_FALSE;(gdb) l zif_usleep4463    /* }}} */44644465    /* {{{ proto void usleep(int micro_seconds)4466       Delay for a given number of micro seconds */4467    PHP_FUNCTION(usleep)4468    {4469    #if HAVE_USLEEP4470            long num;44714472            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num) == FAILURE) {

繼續執行

(gdb) n4452            if (num < 0) {(gdb) p num$6 = 3(gdb) n4457            RETURN_LONG(php_sleep(num));(gdb) n4462    }(gdb) nexecute_internal (execute_data_ptr=0xb7fa1144, fci=0x0, return_value_used=0) at /usr/local/src/php-5.5.23/Zend/zend_execute.c:14881488    }

到了execute_internal ,可以查看一下當前函數的一個狀態

(gdb) p execute_data_ptr$7 = (zend_execute_data *) 0xb7fa1144(gdb) p *execute_data_ptr$8 = {opline = 0xb7fbcacc, function_state = {function = 0x8bcf3e8, arguments = 0xb7fa119c}, op_array = 0xb7fbc7b4, object = 0x0,   symbol_table = 0x8b99cdc, prev_execute_data = 0x0, old_error_reporting = 0x0, nested = 0 ‘\000‘,   original_return_value = 0x38b4ac9, current_scope = 0x49, current_called_scope = 0x45, current_this = 0x0, fast_ret = 0x0,   call_slots = 0xb7fa1188, call = 0xb7fa1188}(gdb) p *execute_data_ptr->function_state.function->common->function_name$9 = 115 ‘s‘(gdb) p execute_data_ptr->function_state.function->common->function_name $10 = 0x8af03c9 "sleep"(gdb) p execute_data_ptr->op_array->filename$11 = 0xb7fbc8e8 "/code/kk.php"

查看當前hashtable

(gdb) p *execute_data_ptr->symbol_table$16 = {nTableSize = 64, nTableMask = 63, nNumOfElements = 8, nNextFreeElement = 0, pInternalPointer = 0xb7fb924c,   pListHead = 0xb7fb924c, pListTail = 0xb7fbd228, arBuckets = 0xb7fb9120, pDestructor = 0x85bf06f <_zval_ptr_dtor_wrapper>,   persistent = 0 ‘\000‘, nApplyCount = 0 ‘\000‘, bApplyProtection = 1 ‘\001‘, inconsistent = 0}

繼續執行輸出c之後,斷行符號即可,同樣可以看到in_array的執行資訊

(gdb) p *execute_data_ptr->function_state.function$24 = {type = 1 ‘\001‘, common = {type = 1 ‘\001‘, function_name = 0x8af1841 "in_array", scope = 0x0, fn_flags = 256,     prototype = 0x0, num_args = 3, required_num_args = 2, arg_info = 0x8ae7554}, op_array = {type = 1 ‘\001‘,     function_name = 0x8af1841 "in_array", scope = 0x0, fn_flags = 256, prototype = 0x0, num_args = 3, required_num_args = 2,     arg_info = 0x8ae7554, refcount = 0x842691d, opcodes = 0x8bcf120, last = 0, vars = 0x0, last_var = 0, T = 1,     nested_calls = 3086618796, used_stack = 0, brk_cont_array = 0x0, last_brk_cont = 1, try_catch_array = 0xb7fa10dd,     last_try_catch = 96, has_finally_block = 160 ‘\240‘, static_variables = 0x0, this_var = 11482064,     filename = 0xaf1ff4 "|\035\257", line_start = 11482016, line_end = 146381272,     doc_comment = 0xbffff238 "x\362\377\277\244\aY\b\021", doc_comment_len = 10305959, early_binding = 11085989,     literals = 0x8b7a0a0, last_literal = 140062666, run_time_cache = 0xb7fa10d4, last_cache_slot = 90, reserved = {0x9, 0x8b5f7ac,       0x796, 0x0}}, internal_function = {type = 1 ‘\001‘, function_name = 0x8af1841 "in_array", scope = 0x0, fn_flags = 256,     prototype = 0x0, num_args = 3, required_num_args = 2, arg_info = 0x8ae7554, handler = 0x842691d <zif_in_array>,     module = 0x8bcf120}}(gdb) p execute_data_ptr->function_state.function->common->function_name $26 = 0x8af1841 "in_array"(gdb) p execute_data_ptr->op_array->filename                       $27 = 0xb7fbc8e8 "/code/kk.php"

還可以加一下監控watch、設定一些調試變數set 等等

其他的調試工具還有 strace 查看系統調用、ltrace 查看類庫的調用、vld查看opcode

  

 

參考文章  

http://www.cprogramming.com/gcc.html

http://www.thegeekstuff.com/2010/03/debug-c-program-using-gdb/

http://www.cprogramming.com/gdb.html

http://www.laruence.com/2011/06/23/2057.html

http://derickrethans.nl/what-is-php-doing.html

 

【php】使用gdb調試php程式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.