Use GDB to Debug PHP code and solve the endless PHP code loop problem. gdbphp_PHP tutorial

Source: Internet
Author: User
Tags sapi
Use GDB to Debug PHP code to solve the endless PHP code loop problem, gdbphp. Debug the PHP code using GDB to solve the endless PHP code loop problem. when gdbphp recently helped a colleague solve the SwooleServer problem, it found that one worker process has been in the R state, besides, the CPU time is not used to debug PHP code using GDB, solving the endless loop problem of PHP code, gdbphp

When I recently helped my colleagues solve the Swoole Server problem, I found that one worker process has been in the R state, and the CPU consumption is very high. It was preliminarily determined that it was a life-and-death loop in PHP code.

The following code shows how to solve the PHP endless loop problem.

The code is as follows:
# Dead_loop.php
$ Array = array ();
For ($ I = 0; I I <10000; $ I ++)
{
$ Array [] = $ I;
}
Include _ DIR _. "/include. php ";
# Include. php
While (1)
{
Usleep (10 );
$ Keys = array_flip ($ array );
$ Index = array_search (rand (1500,999 9), $ array );
$ Str = str_repeat ('A', $ index );
$ Strb = test ($ index, $ str );
}
Function test ($ index, $ str)
{
Return str_replace ('A', 'B', $ str );
}

Obtain the process ID and status through ps aux, use gdb-p process ptrace to trace, and use the bt command to obtain the call stack.

The code is as follows:
Htf 3834 2.6 0.2 166676 pts/12 R + php dead_loop.php
Gdb-p 3834
(Gdb) bt
#0 0x000000000000008cc03f in seconds (heap = 0x1eaa2c0, ptr = 0x2584910, silent = 1, _ zend_filename = 0xee3d40 "/home/htf/workspace/php-5.4.27/Zend/zend_variables.c ",
_ Zend_lineno = 182, _ zend_orig_filename = 0xee1888 "/home/htf/workspace/php-5.4.27/Zend/zend_execute_API.c", _ zend_orig_lineno = 437)
At/home/htf/workspace/php-5.4.27/Zend/zend_alloc.c: 1485
#1 0x000000000000008cd643 in _ partition (heap = 0x1eaa2c0, p = 0x2584910, _ zend_filename = 0xee3d40 "/home/htf/workspace/php-5.4.27/Zend/zend_variables.c ", _ zend_lineno = 182,
_ Zend_orig_filename = 0xee1888 "/home/htf/workspace/php-5.4.27/Zend/empty", _ zend_orig_lineno = 437) at/home/htf/workspace/php-5.4.27/Zend/zend_alloc.c: 2064
#2 0x000000000000008cebf7 in _ efree (ptr = 0x2584910, _ zend_filename = 0xee3d40 "/home/htf/workspace/php-5.4.27/Zend/zend_variables.c", _ zend_lineno = 182,
_ Zend_orig_filename = 0xee1888 "/home/htf/workspace/php-5.4.27/Zend/empty", _ zend_orig_lineno = 437) at/home/htf/workspace/php-5.4.27/Zend/zend_alloc.c: 2436
#3 records in _ Records (zval_ptr = 0x25849a0, _ zend_filename = 0xee3d40 "/home/htf/workspace/php-5.4.27/Zend/zend_variables.c", _ zend_lineno = 182)
At/home/htf/workspace/php-5.4.27/Zend/zend_execute_API.c: 437
#4 0x000000000000008fe687 in _ zval_ptr_dtor_wrapper (zval_ptr = 0x25849a0) at/home/htf/workspace/php-5.4.27/Zend/zend_variables.c: 182
#5 0x0000000000000091259f in zend_hash_destroy (ht = 0x7f00003f6e380) at/home/htf/workspace/php-5.4.27/Zend/zend_hash.c: 560
#6 records in _ Records (zvalue = 0x7f00000000fe50, _ zend_filename = 0xeea290 "/home/htf/workspace/php-5.4.27/Zend/zend_execute.c", _ zend_lineno = 901)
At/home/htf/workspace/php-5.4.27/Zend/zend_variables.c: 45
#7 0x0000000000936656 in _ zval_dtor (zvalue = 0x7f00000000fe50, _ zend_filename = 0xeea290 "/home/htf/workspace/php-5.4.27/Zend/zend_execute.c", _ zend_lineno = 901)
At/home/htf/workspace/php-5.4.27/Zend/zend_variables.h: 35
#8 0x0000000000939747 in zend_assign_to_variable (variable_ptr_ptr = 0x7f00003f8e738, value = 0x7f000000000000f6a8) at/home/htf/workspace/php-5.4.27/Zend/zend_execute.c
#9 0x0000000000997ee5 in ZEND_ASSIGN_SPEC_CV_VAR_HANDLER (execute_data = 0x7f1_d04b2a8) at/home/htf/workspace/php-5.4.27/Zend/zend_vm_execute.h: 33168
#10 0x0000000000000093b5fd in execute (op_array = 0x21d58b0) at/home/htf/workspace/php-5.4.27/Zend/zend_vm_execute.h: 410
#11 0x0000000000901692 in zend_execute_scripts (type = 8, retval = 0x0, file_count = 3) at/home/htf/workspace/php-5.4.27/Zend/zend. c: 1315
#12 0x000000000087926a in php_execute_script (primary_file = 0x7ffffe0038d0) at/home/htf/workspace/php-5.4.27/main. c: 2502
#13 0x000000000000009a32e3 in do_cli (argc = 2, argv = 0x7ffffe004d18) at/home/htf/workspace/php-5.4.27/sapi/cli/php_cli.c: 989
#14 0x00000000009a4491 in main (argc = 2, argv = 0x7ffffe004d18) at/home/htf/workspace/php-5.4.27/sapi/cli/php_cli.c: 1365

After gdb is executed, the process of the endless loop changes to the T state, indicating that the Trace is in progress. This is exclusive, so you cannot use strace/gdb or other ptrace tools to debug this process. In addition, this process will interrupt execution. After gdb inputs c, the program continues to run down. Then press ctrl + c again to interrupt the program. Use the bt command to view the call stack of a process.

The code is as follows:
(Gdb) bt
#0 _ zend_mm_alloc_int (heap = 0x1eaa2c0, size = 72, _ zend_filename = 0xe43410 "/home/htf/workspace/php-5.4.27/ext/standard/array. c ", _ zend_lineno = 2719,
_ Zend_orig_filename = 0xee5a38 "/home/htf/workspace/php-5.4.27/Zend/zend_hash.c", _ labels = 412) at/home/htf/workspace/php-5.4.27/Zend/zend_alloc.c: 1895
#1 0x000000000000008ceb86 in _ emalloc (size = 72, _ zend_filename = 0xe43410 "/home/htf/workspace/php-5.4.27/ext/standard/array. c ", _ zend_lineno = 2719,
_ Zend_orig_filename = 0xee5a38 "/home/htf/workspace/php-5.4.27/Zend/zend_hash.c", _ labels = 412) at/home/htf/workspace/php-5.4.27/Zend/zend_alloc.c: 2425
#2 0x00000000000000911d85 in _ Records (ht = 0x2257a10, h = 3972, pData = 0x7ffffe0012b0, nDataSize = 8, pDest = 0x0, flag = 1,
_ Zend_filename = 0xe43410 "/home/htf/workspace/php-5.4.27/ext/standard/array. c ", _ zend_lineno = 2719) at/home/htf/workspace/php-5.4.27/Zend/zend_hash.c: 412
#3 0x00000000007767e1 in zif_array_flip (ht = 1, return_value = 0x7f00000000ea68, return_value_ptr = 0x0, this_ptr = 0x0, return_value_used = 1)
At/home/htf/workspace/php-5.4.27/ext/standard/array. c: 2719
#4 0x000000000093c03e in zend_do_fcall_common_helper_SPEC (execute_data = 0x7f1_d04b2a8) at/home/htf/workspace/php-5.4.27/Zend/zend_vm_execute.h: 643
#5 0x000000000000009400e6 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data = 0x7f1_d04b2a8) at/home/htf/workspace/php-5.4.27/Zend/zend_vm_execute.h: 2233
#6 0x0000000000000093b5fd in execute (op_array = 0x21d58b0) at/home/htf/workspace/php-5.4.27/Zend/zend_vm_execute.h: 410

The two BT messages are different because the program is interrupted at different locations. The line execute (oparray = 0x21d58b0) is displayed. here is the entry for PHP to execute oparray. Input f 6 under gdb (available by calling the stack number ).

The code is as follows:
(Gdb) f 6
#6 0x0000000000000093b5fd in execute (op_array = 0x21d58b0) at/home/htf/workspace/php-5.4.27/Zend/zend_vm_execute.h: 410
410 if (ret = OPLINE-> handler (execute_data TSRMLS_CC)> 0 ){
(Gdb) p * op_array
$2 = {type = 2' \ 002 ', function_name = 0x7f1_d086540 "test", scope = 0x0, fn_flags = 134217728, prototype = 0x0, num_args = 2, required_num_args = 2, arg_info = 0x7f1_d086bd8,
Refcount = primary, opcodes = 0x7f00000000d600, last = 8, vars = primary, last_var = 2, T = 1, brk_cont_array = 0x0, last_brk_cont = 0, try_catch_array = 0x0,
Last_try_catch = 0, static_variables = 0x0, this_var = 4294967295, filename = 0x7f00000000ba38 "/home/htf/wwwroot/include. php ", line_start = 12, line_end = 15, doc_comment = 0x0,
Doc_comment_len = 0, early_binding = 4294967295, literals = Week, last_literal = 4, run_time_cache = Week, last_cache_slot = 1, reserved = {0x0, 0x0, 0x0, 0x0 }}

Here, the filename shows which php file op_array is. Enter f 0 to enter the current position.

The code is as follows:
(Gdb) p ** executor_globals.opline_ptr
$4 = {handler = 0x93ff9c, op1 = {constant = 1680133296, var = 1680133296, num = 1680133296, hash = 140129283132592, opline_num = 1680133296,
Jmp_addr = numeric, zv = numeric, literal = 0x7f1_1_ccb0, ptr = 0x7f1_1_ccb0}, op2 = {constant = 0, var = 0, num = 0, hash = 0, opline_num = 0, jmp_addr = 0x0,
Zv = 0x0, literal = 0x0, ptr = 0x0}, result = {constant = 32, var = 32, num = 32, hash = 32, opline_num = 32, jmp_addr = 0x20, zv = 0x20, literal = 0x20, ptr = 0x20 },
Extended_value = 1, lineno = 5, opcode = 60'

Here, lineno indicates the number of lines of code where OPCODE is located. you can check the lines of code in the corresponding file. You can view more information using GDB. I will not introduce it here. if you are interested, try it on your own.

Use of zbacktrace

Zend officially provides a gdb script that encapsulates commands and can directly see the call relationship of php functions. There is a. gdbinit in the root directory of the php source code package. Use

The code is as follows:
Source your_php_src_path/. gdbinit
Zbacktrace

You can directly see the call stack of the PHP function.

The above is all the content of this article. I hope you will like it.

Worker recently helped his colleagues solve the Swoole Server problem and found that one worker process has been in the R state, and the CPU time consumption is not...

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.