GDB is a powerful UNIX program debugging tool released by the GNU open-source organization. If you are working on a UNIX platform, you will find that the GDB debugging tool has more powerful functions than the visual debugger of VC and BCB. At the same time, GDB also has a graphical debugging end such as ddd. In general, GDB mainly implements the following four functions:
(1) start your program and run it as needed according to your custom requirements.
(2) the program to be debugged can be stopped at the breakpoint you specified. (The breakpoint can be a conditional expression)
(3) when the program is stopped, you can check what happens in your program.
(4) dynamically change 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 are working on a UNIX platform, you will find that the GDB debugging tool has more powerful functions than the visual debugger of VC and BCB. At the same time, GDB also has a graphical debugging end such as ddd.
2. debug the C/C ++ program
Code directly
# Include
Using namespace std; long factorial (int n); int main () {int n (0); cin> n; long val = factorial (n); cout <
Compile
1
G ++ k. cpp-g-Wall-Werror-o main
Start Debugging
[Root @ localhost 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
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 <
Set the breakpoint 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);
Set 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)
It can be seen that while, resulting in n out of bounds, fix
while(n>0) //doesn't let n reach 0{result*=n;n--; //decrements only after the evaluation}
Some quick commands
L-list
P-print {variable}
C-continue
S-step
B-break line_number/break [file_name]: line_number/break [file_name]: func_name
R-run
Set=
Watch
ENTER: pressing enter key wowould execute the previusly executed command again.
Differences between 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. debug the PHP program
PHP code
<?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;} }
Start Debugging and add breakpoints
[root@localhost 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
6 breakpoint keep y 0x08069390
(gdb)
Add a few breakpoints to test syntax: break [file_name]: func_name. here we can roughly see that echo print is not a function.
Then start debugging.
(gdb) p *return_value$1 = {value = {lval = 1515870810, dval = 1.7838867517321418e+127, str = {val = 0x5a5a5a5a , 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 , len = 1515870810}, ht = 0x5a5a5a5a, obj = {handle = 1515870810, handlers = 0x5a5a5a5a}}(gdb) p return_value->value->lval$3 = 1515870810
We can also use the built-in gdbinit for debugging.
(gdb) source /usr/local/src/php-5.5.23/.gdbinit(gdb) zbacktrace[0xb7fa1144] sleep(3) /code/kk.php:4
View the execution process of the current stack and PHP kernel
(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
View code segments
(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) {
Continue execution
(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 }
To execute_internal, you can view a status of the current function.
(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"
View the 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_dtor_wrapper>, persistent = '\', nApplyCount = '\', bApplyProtection = '\', inconsistent = }
After executing the output c, press enter to view the execution information of 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
, 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 monitoring watch and set some debugging variables.
Other debugging tools include strace viewing system calls, ltrace viewing class library calls, and vld viewing opcode.
The above content is all about how to use GDB to Debug PHP programs. I hope you will like it.