How to use GDB to debug a PHP program _php instance

Source: Internet
Author: User
Tags print print sapi usleep zend

In general, GDB mainly completes the following four areas of functionality:

(1) Start your program, you can follow your custom requirements of the arbitrary operation of the program.
(2) Allow the program to be debugged to stop at the breakpoint where you specified the adjustment. (A breakpoint can be a conditional expression)
(3) When the program is stopped, you can check what happened in your program at this time.
(4) Dynamically changing the execution environment of your program.

1. Introduction

GDB is a powerful UNIX program debugging tool released by the GNU Open source organization. If you're working on a UNIX platform, you'll find that GDB's debugging tool has more power than VC, BCB's graphical debugger. GDB also has a graphical debugging end such as DDD.

2. Debug C + + program

directly on the code.

#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;

Compile

1

g++ k.cpp-g-wall-werror-o Main

Start debugging

[Root@localhost code]# gdb./main
GNU/gdb Red Hat Enterprise Linux (7.2-83.el6)
Copyright (C) Soft Ware Foundation, Inc.
License gplv3+: GNU GPL version 3 or later  
 

Set Breakpoint Break linenumber

(GDB) b 9
breakpoint 1 at 0x80486f9:file K.cpp, line 9.
(GDB) r
starting program:/code/main 
4
Breakpoint 1, Main () at K.cpp:9

Set observation Point Watch Var

(GDB) s factorial (n=4) at k.cpp:17-long result (1);
(GDB) l return 0; A long factorial (int n) {long result (1); a while (n--) {result*=n} (GDB) watch n Hardware WATC
Hpoint 2:n (GDB) Watch result hardware Watchpoint 3:result (GDB) C continuing.
Hardware Watchpoint 3:result Old value = 0 New value = 1 factorial (n=4) at K.cpp:18 (n--) (GDB) continuing. Hardware Watchpoint 2:n Old value = 4 New value = 3 0x08048764 into factorial (n=3) at K.cpp:18 (n--) (GDB) Contin
Uing.
Hardware Watchpoint 3:result Old value = 1 New value = 3 factorial (n=3) at K.cpp:18 (n--) (GDB) continuing. Hardware Watchpoint 2:n Old value = 3 New value = 2 0x08048764 into factorial (n=2) at K.cpp:18 (n--) (GDB) Contin
Uing.
Hardware Watchpoint 3:result Old value = 3 New value = 6 factorial (n=2) at K.cpp:18 (n--) (GDB) continuing. Hardware Watchpoint 2:n Old value = 2 New value = 1 0x08048764 into factorial (n=1) at K.cpp:18 (n--) (GDB) continuing. Hardware Watchpoint 2:n Old value = 1 New value = 0 0x08048764 into factorial (n=0) at K.cpp:18 (n--) (GDB) Contin
Uing.
Watchpoint 2 deleted because the program has to the left of the block in which it expression is valid.
Watchpoint 3 deleted because the program has to the left of the block in which it expression is valid.
0x08048705 in Main () at K.cpp:9 9 long val=factorial (n);  (GDB) p val $ = 11476980 (GDB)

You can see there's a while there, causing N to cross over, fix

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

Some shortcut commands

L–list
P–print Print {variable}
C–continue
S–step
B-break break Line_number/break [File_name]:line_number/break [File_name]:func_name
R-run
Set <var> = <value>
Watch <var>

Enter:pressing enter key would execute the previously executed command again.

The difference between the C/N/S

C or Continue:debugger'll continue executing until the next break point.
N or Next:debugger'll execute the next line as single instruction.
s or Step:same as next, but does not treats function as a single instruction, instead goes to the function and execute S It line

3, Debugging PHP Program

PHP code

<?php. 
for ($i = 0; $i < $i + +) {
echo $i. " \ n ";
Sleep (3);
if (In_array ($i, [1,9,20])) {
Print_r ($i * $i);
Var_dump ($i * $i); 
Print $i * $i;
} 

Start debugging, plus breakpoints

[Root@localhost code]# gdb php GNU gdb (gdb) Red Hat Enterprise Linux (7.2-83.el6) Copyright (C) free Software Foun Dation, Inc License gplv3+: GNU GPL version 3 or later  

Add a few breakpoints to test syntax:break [File_name]:func_name, here you can look at the echo print and so on, not a function.

and start debugging.

(GDB) p *return_value
$ = {Value = {lval = 1515870810, dval = 1.7838867517321418e+127, str = {val = 0x5a5a5a5a <ad Dress 0x5a5a5a5a out of Bounds>, 
len = 1515870810}, ht = 0x5a5a5a5a, obj = {handle = 1515870810, handlers = 0x5a5a5 A5A}}, refcount__gc = 1, type = 0 ' \000 ', is_ref__gc = 0 ' \000 '}
(GDB) p return_value->value
$ = {Lval = 15158 70810, dval = 1.7838867517321418e+127, str = {val = 0x5a5a5a5a <address 0x5a5a5a5a out of Bounds>, 
len = 1515870 810}, HT = 0x5a5a5a5a, obj = {handle = 1515870810, handlers = 0x5a5a5a5a}}
(GDB) p Return_value->value->lval

We can also use the built-in Gdbinit to debug

(GDB) Source/usr/local/src/php-5.5.23/.gdbinit
(GDB) zbacktrace

to view the current stack, the PHP kernel's execution process

(GDB) bt #0 zif_sleep (Ht=1, return_value=0xb7fbd6f0, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0) at/usr/l ocal/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  

to view Code Snippets

(GDB) L 4444 Delay for a given number of seconds * * 4445 php_function (sleep) 4446 {4447 long num; 4448 4449 if (zend_par Se_parameters (Zend_num_args () tsrmls_cc, "L", &num) = = failure) {4450 return_false; 4451} 4452 if (NUM < 0) {445
3 Php_error_docref (NULL tsrmls_cc, e_warning, "Number of seconds must is greater than or equal to 0");  (GDB) L 4450 4445 php_function (sleep) 4446 {4447 long num; 4448 4449 if (zend_parse_parameters () Zend_num_args, "L", &num) = = failure) {4450 return_false; 4451} 4452 if (num < 0) {4453 php_error_docref (NULL tsrmls_cc, E_war
NING, "Number of seconds must is greater than or equal to 0");
4454 Return_false; (GDB) L zif_usleep 4463 *}}/4464 4465 * {{proto void usleep (int micro_seconds) 4466 Delay for a given number of M Icro seconds/4467 php_function (usleep) 4468 {4469 #if have_usleep 4470 long num; 4471 4472 if (zend_parse_parameters (Z  End_num_args () tsrmls_cc, "L", &num) = = failure) {

Continue to execute

(GDB) n
4452 if (num < 0) {
(GDB) p num
$ = 3
(gdb) n
4457 return_long (php_sleep (num));
(GDB) n
4462}
(GDB) n
execute_internal (execute_data_ptr=0xb7fa1144, fci=0x0, return_value_used=0) at/ usr/local/src/php-5.5.23/zend/zend_execute.c:1488

To Execute_internal, you can look at a state of the current function

(GDB) p execute_data_ptr
$ = (Zend_execute_data *) 0xb7fa1144
(GDB) p *execute_data_ptr $
= {Opline = 0XB7FB CACC, Function_state = {function = 0x8bcf3e8, arguments = 0xb7fa119c}, Op_array = 0xb7fbc7b4, Object = 0x0, 
symbol_tab Le = 0x8b99cdc, Prev_execute_data = 0x0, old_error_reporting = 0x0, nested = 0 ' \000 ', 
original_return_value = 0x38b4a C9, Current_scope = 0x49, Current_called_scope = 0x45, Current_this = 0x0, Fast_ret = 0x0, 
call_slots = 0xb7fa1188, CA ll = 0xb7fa1188}
(GDB) p *execute_data_ptr->function_state.function->common->function_name $
= 115 ' s '
(GDB) p execute_data_ptr->function_state.function->common->function_name 
$ = 0x8af03c9 " Sleep "
(GDB) p Execute_data_ptr->op_array->filename

View current Hashtable

(GDB) p *execute_data_ptr->symbol_table
$ = {Ntablesize =, Ntablemask =, nnumofelements =, nnextfreeelement =, Pinternalpointer = XBFBC, 
plisthead = XBFBC, Plisttail = xbfbd, arbuckets = xbfb, Pdestructor = XBFF <_zval_ptr_dto R_wrapper>, 

After you continue to perform output C, you can also see the In_array execution information

(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 = 0x8ae 7554}, Op_array = {type = 1 ' \001 ', function_name = 0x8af1841 "In_array", scope = 0x0, Fn_flags = 256, prototype = 0x0, n Um_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_arra y = 0xb7fa10dd, Last_try_catch = Has_finally_block = 160 ' \240 ', static_variables = 0x0, This_var = 11482064, Filena me = 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_cach E = 0xb7fa10d4, LAST_CACHe_slot = 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, Handl ER = 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"

You can also add a monitor watch, set some debug variables set, and so on

Other debugging tools also have strace view system calls, Ltrace view class library calls, vld view opcode.

The above content is small to share about how to use GDB debugging PHP program all the content, I hope you like.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.