Debug PHP code with GDB, solve the problem of PHP code dead Loop, gdbphp_php tutorial

Source: Internet
Author: User
Tags php source code sapi

Debug PHP code with GDB to solve the PHP code dead loop problem, gdbphp


Recently, when helping colleagues solve the swoole server problem, it was found that 1 worker processes have been in the R state and the CPU time is very high. The initial assertion is that there is a dead loop in the PHP code.

Here's a piece of code to show how to solve the PHP dead loop problem.

Copy the Code code as follows:
#dead_loop. php
$array = Array ();
for ($i = 0; $i < 10000; $i + +)
{
$array [] = $i;
}
Include __dir__. " /include.php ";
#include. php
while (1)
{
Usleep (10);
$keys = Array_flip ($array);
$index = Array_search (rand (9999), $array);
$str = str_repeat (' A ', $index);
$STRB = Test ($index, $STR);
}
function test ($index, $STR)
{
Return Str_replace (' A ', ' B ', $str);
}

Through PS aux get process ID and status as follows, use gdb-p process ptrace trace, get call stack via BT command

Copy CodeThe code is as follows:
HTF 3834 2.6 0.2 166676 22060 pts/12 r+ 10:50 0:12 php dead_loop.php
Gdb-p 3834
(GDB) bt
#0 0x00000000008cc03f in Zend_mm_check_ptr (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 0x00000000008cd643 in _zend_mm_free_int (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/zend_execute_api.c", __zend_orig_lineno=437) at/home/htf/workspace/php-5.4.27/zend/zend_alloc.c:2064
#2 0x00000000008cebf7 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/zend_execute_api.c", __zend_orig_lineno=437) at/home/htf/workspace/php-5.4.27/zend/zend_alloc.c:2436
#3 0x00000000008eda0a in _zval_ptr_dtor (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 0x00000000008fe687 in _zval_ptr_dtor_wrapper (zval_ptr=0x25849a0) at/home/htf/workspace/php-5.4.27/zend/zend_ variables.c:182
#5 0x000000000091259f in Zend_hash_destroy (ht=0x7f7263f6e380) at/home/htf/workspace/php-5.4.27/zend/zend_hash.c : 560
#6 0x00000000008fe2c5 in _zval_dtor_func (Zvalue=0x7f726426fe50, __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=0x7f726426fe50, __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=0x7f7263f8e738, value=0x7f726426f6a8) AT/HOME/HTF /workspace/php-5.4.27/zend/zend_execute.c:901
#9 0x0000000000997ee5 in Zend_assign_spec_cv_var_handler (execute_data=0x7f726d04b2a8) at/home/htf/workspace/ php-5.4.27/zend/zend_vm_execute.h:33168
#10 0x000000000093b5fd 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/ main.c:2502
#13 0x00000000009a32e3 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 executes, the process of the dead loop becomes the state of T, indicating that it is in the trace. This is exclusive, so it is no longer possible to debug this process with STRACE/GDB or other ptrace tools. Additionally, this process interrupts execution. After GDB enters C, the program continues to run down. Then press CTRL + C again to break the program. The call stack for the process is viewed through the BT command.

Copy CodeThe 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", __zend_orig_lineno=412) at/home/ htf/workspace/php-5.4.27/zend/zend_alloc.c:1895
#1 0x00000000008ceb86 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", __zend_orig_lineno=412) at/home/ htf/workspace/php-5.4.27/zend/zend_alloc.c:2425
#2 0x0000000000911d85 in _zend_hash_index_update_or_next_insert (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=0x7f726424ea68, 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=0x7f726d04b2a8) at/home/htf/workspace/ php-5.4.27/zend/zend_vm_execute.h:643
#5 0x00000000009400e6 in Zend_do_fcall_spec_const_handler (execute_data=0x7f726d04b2a8) at/home/htf/workspace/ php-5.4.27/zend/zend_vm_execute.h:2233
#6 0x000000000093b5fd in Execute (op_array=0x21d58b0) at/home/htf/workspace/php-5.4.27/zend/zend_vm_execute.h:410

The BT information for the

Two times is different, because the program is interrupted at various locations. See Execute (OPARRAY=0X21D58B0) This line, this is the PHP execution Oparray entrance. GDB input F 6, (by the call stack number is available).

The

copy Code code is as follows:
(GDB) F 6
#6 0x000000000093b5fd 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
$ = {type = 2 ' \002 ', function_name = 0x7f726d086540 "Test", scope = 0x0, Fn_flags = 134217728, Prototype = 0x0, Num_args = 2, Required_num_args = 2, Arg_info = 0x7f726d086bd8,
RefCount = 0x7f726d0870f0, opcodes = 0x7f726424d600, last = 8, VARs = 0x7f726424e890, Last_var = 2, T = 1, Brk_cont_array = 0x0, Last_brk_cont = 0, try_catch_a Rray = 0x0,
Last_try_catch = 0, Static_variables = 0x0, This_var = 4294967295, filename = 0x7f726424ba38 "/home/htf/www Root/include.php ", Line_start = 0, Line_end = A, doc_comment = 0x0,
Doc_comment_len =, early_binding = 4294967295, literals = 0x7f726424eae0, last_literal = 4, Run_time_cache = 0x7f726450bfb0, Last_cache_slot = 1, reserved = {0x0, 0x0, 0 X0, 0x0}}

The filename here will see which PHP file Op_array is. Then enter F 0 to enter the current position.

Copy the Code code as follows:
(GDB) P **executor_globals.opline_ptr
$4 = {Handler = 0x93ff9c, OP1 = {constant = 1680133296, var = 1680133296, num = 1680133296, hash = 140129283132592, Oplin E_num = 1680133296,
Jmp_addr = 0x7f726424ccb0, Zv = 0x7f726424ccb0, literal = 0x7f726424ccb0, ptr = 0x7f726424ccb0}, OP2 = {constant = 0, var = 0, num = 0, hash = 0, Opline_num = 0, jmp_addr = 0x0,
Zv = 0x0, literal = 0x0, ptr = 0x0}, result = {constant = +, var = +, num = +, hash = +, Opline_num = +, jmp_addr = 0 x20, Zv = 0x20, literal = 0x20, ptr = 0x20},
Extended_value = 1, Lineno = 5, opcode = 60 '

The Lineno here indicates the number of lines of code that opcode is in, and you can go to the corresponding file to see what line of code it is. GDB can be used to see more information, which is no longer introduced here, interested you can try it yourself.

Use of Zbacktrace

Zend Official provides a GDB script, the instructions are encapsulated, you can directly see the PHP function call relationship. There is a. Gdbinit in the root directory of the PHP source code package. Use

Copy the Code code as follows:
SOURCE Your_php_src_path/.gdbinit
Zbacktrace

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

The above is the whole content of this article, I hope you can enjoy.

http://www.bkjia.com/PHPjc/963122.html www.bkjia.com true http://www.bkjia.com/PHPjc/963122.html techarticle debugging PHP code with GDB, to solve the PHP code dead Loop problem, gdbphp recently in helping colleagues solve Swoole server problem, found that there are 1 worker processes have been in the state of R, and CPU time is not ...

  • Related Article

    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.