How do you find the cause of soaring cpu usage when a process that usually consumes less cpu suddenly occupies nearly 100% of the cpu? My idea is to first find the code line being executed by the process to identify the code segment that may be faulty. Then, carefully analyze the problematic code segment to find out the cause. If your program is written in c and c ++,
How do you find the cause of soaring cpu usage when a process that usually consumes less cpu suddenly occupies nearly 100% of the cpu? My idea is to first find the code line being executed by the process to identify the code segment that may be faulty. Then, carefully analyze the problematic code segment to find out the cause. If your program is written in c and c ++,
How do you find the cause of soaring cpu usage when a process that usually consumes less cpu suddenly occupies nearly 100% of the cpu? My idea is to first find the code line being executed by the process to identify the code segment that may be faulty. Then, carefully analyze the problematic code segment to find out the cause.
If your program is written in c and c ++, you can easily find the code lines being executed. However, the program is written in php. How can I find the problematic code lines? This is the problem to be solved in this article.
Background:
If you are not familiar with the C language, you can skip this step and take a look at the demo.
Everyone knows that php is an explanatory language. The php Code Compiled by the user generates opcode, which is interpreted and executed by the interpreter engine. During the explain execution process, a global variable contains various data used in the execution process. Executor_globals. You can find its type definition in the Zend/zend_globals.h file of the source code.
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_WIN32zend_bool timed_out;OSVERSIONINFOEX windows_version_info;#endifHashTable 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 talk about two variables that are important to us, active_op_array and current_execute_data.
Active_op_arrayThe variable stores the op_array being executed by the engine. (For more information about op_array, click here ). The data type of op_array is defined in Zend/zend_compile.h.
struct _zend_op_array {/* Common elements */zend_uchar 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 talk about it. In the definition, filename and function_name respectively Save the name of the file being executed and the method name.
Current_execute_dataThe execute_data of the op_array being executed is saved. Execute_data stores some data during the execution of each op_array. It is defined in Zend/zend_compile.h:
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 being executed. The opcode structure is defined as follows:
struct _zend_op {opcode_handler_t handler;znode result;znode op1;znode op2;ulong extended_value;uint lineno;zend_uchar opcode;};
Here, lineno is the row number corresponding to opcode.
Example:
After reading the data structure definition above, do you know how to find the name, method name, and row number of the file being executed by php? If you have any questions, let's look at the example below. Create a file test. php with the following code:
Run the php script in cli mode. The number of processes added for execution is 14973. We use the gdb command to debug the process.
$sudo gdb -p 14973(gdb) print (char *)executor_globals.active_op_array->filename$1 = 0x9853a34 "/home/xinhailong/test/php/test.php"(gdb) print (char *)executor_globals.active_op_array->function_name$2 = 0x9854db8 "test1"(gdb) print executor_globals->current_execute_data->opline->lineno$3 = 4
Apparently, he is executing the sleep method of the fourth row.
If you are in trouble with the above method, you can use the. gdbinit file. This file is in the root directory of the php source code. The usage 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)
Digress:
? From php5.6, php has integrated a phpdbg tool. You can debug php programs like gdb in C language. If you are interested, open the following connection.
Https://wiki.php.net/rfc/phpdbg
Http://phpdbg.com/docs
Original article address: When the cpu usage soared, find out the lines of code that may be faulty in php. Thanks for sharing them with the original author.