Quickly identify the lines of code in PHP that could cause the CPU to soar.

Source: Internet
Author: User
Tags php code php script php source code reserved sleep root directory zend

How do you find out what caused the CPU to soar with the CPU approaching 100%? My idea is to first find the line of code that the process is executing to determine the code snippet that might be problematic. Then, carefully analyze the problematic code snippet to find out why.

If your program is written in C and C + +, you can easily find the line of code you are executing. However, the program is written in PHP, how to find the possible problem of the line of code? This problem is the problem to be solved in this article.

Background knowledge:

As you all know, PHP is an explanatory language. The user-written php code generates opcode, which is interpreted by the interpreter engine. During interpretation execution, there is a global variable that contains the various data that is used during execution. It's executor_globals. His type definition can be found in the Zend/zend_globals.h file of the source code.

The code is as follows

struct _zend_executor_globals {
Zval **return_value_ptr_ptr;

Zval Uninitialized_zval;
Zval *uninitialized_zval_ptr;

Zval Error_zval;
Zval *error_zval_ptr;

Zend_ptr_stack Arg_types_stack;

/* Symbol Table Cache * *
HashTable *symtable_cache[symtable_cache_size];
HashTable **symtable_cache_limit;
HashTable **symtable_cache_ptr;

Zend_op **opline_ptr;

HashTable *active_symbol_table;
HashTable symbol_table; /* Main symbol Table/*

HashTable Included_files; /* files already included * *

Jmp_buf *bailout;

int error_reporting;
int orig_error_reporting;
int exit_status;

Zend_op_array *active_op_array;

HashTable *function_table; /* Function Symbol Table/*
HashTable *class_table; /* Class Table * *
HashTable *zend_constants; /* Constants Table * *

Zend_class_entry *scope;
Zend_class_entry *called_scope; /* Scope of the calling class * *

Zval *this;

Long precision;

int ticks_count;

Zend_bool in_execution;
HashTable *in_autoload;
Zend_function *autoload_func;
Zend_bool Full_tables_cleanup;

/* For extended information support * *
Zend_bool no_extensions;

#ifdef ZEND_WIN32
Zend_bool timed_out;
Osversioninfoex Windows_version_info;
#endif

HashTable regular_list;
HashTable persistent_list;

Zend_vm_stack Argument_stack;

int user_error_handler_error_reporting;
Zval *user_error_handler;
Zval *user_exception_handler;
Zend_stack user_error_handlers_error_reporting;
Zend_ptr_stack user_error_handlers;
Zend_ptr_stack user_exception_handlers;

zend_error_handling_t error_handling;
Zend_class_entry *exception_class;

/* Timeout Support * *
int timeout_seconds;

int lambda_count;

HashTable *ini_directives;
HashTable *modified_ini_directives;

Zend_objects_store Objects_store;
Zval *exception, *prev_exception;
Zend_op *opline_before_exception;
Zend_op Exception_op[3];

struct _zend_execute_data *current_execute_data;

struct _zend_module_entry *current_module;

Zend_property_info Std_property_info;

Zend_bool active;

void *SAVED_FPU_CW;

void *reserved[zend_max_reserved_resources];
};

Here we only say two variables that are more important to us, Active_op_array and Current_execute_data.

The Active_op_array variable holds the Op_array the engine is executing (want to know what is Op_array please click to view). There is a definition of the data type for Op_array in Zend/zend_compile.h.

code as follows  

struct _zend_op_array {
/* Common elements */
Zend_uc Har type;
Char *function_name;
Zend_class_entry *scope;
Zend_uint fn_flags;
Union _zend_function *prototype;
Zend_uint Num_args;
Zend_uint Required_num_args;
Zend_arg_info *arg_info;
Zend_bool pass_rest_by_reference;
unsigned char return_reference;
/* End of common elements */

Zend_bool Done_pass_two;

Zend_uint *refcount;

Zend_op *opcodes;
Zend_uint last, size;

Zend_compiled_variable *vars;
int Last_var, Size_var;

Zend_uint T;

Zend_brk_cont_element *brk_cont_array;
int Last_brk_cont;
int current_brk_cont;

Zend_try_catch_element *try_catch_array;
int last_try_catch;

/* Static variables Support */
HashTable *static_variables;

Zend_op *start_op;
int backpatch_count;

Zend_uint This_var;

Char *filename;
Zend_uint Line_start;
Zend_uint Line_end;
Char *doc_comment;
Zend_uint Doc_comment_len;
Zend_uint early_binding/* The linked list of delayed declarations */

Void *reserved[zend_max_reserved_resources];
};

After reading the definition, I don't need to say more. In the definition, filename and function_name each save the file name and method name that are being executed.

Current_execute_data saves the execute_data of the op_array that is being executed. Execute_data saves some data during the execution of each op_array. It is defined in the zend/zend_compile.h:

The code is as follows
struct _zend_execute_data {
struct _ZEND_OP *opline;
Zend_function_state function_state;
Zend_function *FBC; /* Function being called * *
Zend_class_entry *called_scope;
Zend_op_array *op_array;
Zval *object;
Union _temp_variable *ts;
Zval ***cvs;
HashTable *symbol_table;
struct _zend_execute_data *prev_execute_data;
Zval *old_error_reporting;
Zend_bool nested;
Zval **original_return_value;
Zend_class_entry *current_scope;
Zend_class_entry *current_called_scope;
Zval *current_this;
Zval *current_object;
struct _ZEND_OP *call_opline;
};

The opline in the definition is the opcode that is being executed. The structure of the opcode is defined as follows:

The code is as follows
struct _ZEND_OP {
opcode_handler_t handler;
Znode result;
Znode OP1;
Znode OP2;
ULONG Extended_value;
UINT Lineno;
Zend_uchar opcode;
};

Where Lineno is the line number corresponding to the opcode.

Example Description:

After reading the data structure definition above, do you already know how to find the file name, method name and line number that PHP is executing? If you have any questions, then look at the example below. Create a file test.php with the following code:

The code is as follows
<?php
function Test1 () {
while (true) {
Sleep (1);
}
}
Test1 ();
?>

CLI executes the PHP script by adding a process number of 14973. We use the GDB command to debug the process.

The code is as follows
$sudo gdb-p 14973
(GDB) print (char *) executor_globals.active_op_array->filename
$ = 0x9853a34 "/home/xinhailong/test/php/test.php"
(GDB) print (char *) executor_globals.active_op_array->function_name
$ = 0X9854DB8 "Test1"
(gdb) Print Executor_globals->current_execute_data->opline->lineno
$ = 4

Apparently, he was performing the sleep method on line fourth.

If the above method makes you feel trouble, you can use the. gdbinit file. This file is in the root directory of the PHP source code. Use the following methods:

The code is as follows
$sudo gdb-p 14973
(GDB) Source/home/xinhailong/.gdbinit
(GDB) Zbacktrace
[0xa453f34] Sleep (1)/home/xinhailong/test/php/test.php:4
[0xa453ed0] Test1 ()/home/xinhailong/test/php/test.php:7
(GDB)

Digression:

Starting with php5.6, a phpdbg tool is integrated into PHP. You can debug the PHP program just as you would debug the C language program in GDB. If you are interested, you can open the connection below to see

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.