찾다
php教程php手册快速找出php中可能导致cpu飙升问题的代码行

快速找出php中可能导致cpu飙升问题的代码行

  用cpu接近100%时,你如何找到导致cpu飙升的原因?我的思路是,首先找到进程正在执行的代码行,从而确定可能有问题的代码段。然后,再仔细分析有问题的代码段,从而找出原因。

  如果你的程序使用的是c、c++编写,那么你可以很容易的找到正在执行的代码行。但是,程序是php编写的,如何找到可能有问题的代码行呢?这个问题就是本文要解决的问题。

  背景知识:

  大家都知道php是一个解释性语言。用户编写的php代码会生成opcode,由解释器引擎去解释执行。在解释执行过程中,有一个全局变量包含了执行过 程中用到的各种数据。它就是executor_globals。在源码的Zend/zend_globals.h 文件中可以找到他的类型定义。

代码如下  

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];
};

  这里我们只说两个对我们比较重要的变量,active_op_array 和 current_execute_data。

  active_op_array变量中保存了引擎正在执行的op_array(想了解什么是op_array请点击查看)。在Zend/zend_compile.h中有关于op_array的数据类型的定义。

代码如下  

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];
};

  看完定义,就不用我多说了把。定义中,filename和 function_name分别保存了正在执行的文件名和方法名。

  current_execute_data保存了正在执行的op_array的execute_data。execute_data保存了每个op_array执行过程中的一些数据。其定义在,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;
};

  定义中的opline就是正在执行的opcode。opcode的结构定义如下:

代码如下  
struct _zend_op {
opcode_handler_t handler;
znode result;
znode op1;
znode op2;
ulong extended_value;
uint lineno;
zend_uchar opcode;
};

  其中lineno就是opcode所对应的行号。

  示例说明:

  看完上面的数据结构定义,你是否已经知道如何找php正在执行的文件名,方法名和行号呢?如果还有疑问的话,那就接着看下面的例子。创建一个文件test.php,代码如下:

代码如下  
function test1(){
while(true){
sleep(1);
}
}
test1();
?>

  cli方式执行php脚本,加入执行的进程号为14973。我们使用gdb命令来调试进程。

代码如下  
$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

  很显然,他正在执行第四行的sleep方法。

  如果上面的方法你感觉麻烦,那你可以使用.gdbinit文件。这个文件在php源码的根目录下。使用方法如下:

代码如下  
$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)

  题外话:

  从php5.6开始,php中集成了一个phpdbg的工具。可以像gdb调试c语言程序一样,调试php程序。感兴趣的话,可以打开下面的连接看看

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
理解SpringBoot和SpringMVC之间的差异及比较理解SpringBoot和SpringMVC之间的差异及比较Dec 29, 2023 am 09:20 AM

对比SpringBoot与SpringMVC,了解它们的差异随着Java开发的不断发展,Spring框架已经成为了许多开发人员和企业的首选。在Spring的生态系统中,SpringBoot和SpringMVC是两个非常重要的组件。虽然它们都是基于Spring框架的,但在功能和使用方式上却有一些区别。本文将重点对比一下SpringBoot与Sprin

WordPress 网站搭建指南:快速搭建个人网站WordPress 网站搭建指南:快速搭建个人网站Mar 04, 2024 pm 04:39 PM

WordPress网站搭建指南:快速搭建个人网站随着数字化时代的到来,拥有一个个人网站已经成为了一种时尚和必要。而WordPress作为最受欢迎的网站搭建工具,让搭建个人网站变得更加容易和便捷。本文将为大家提供一个快速搭建个人网站的指南,包含具体的代码示例,希望可以帮助到想要拥有自己网站的朋友们。第一步:购买域名和主机在开始搭建个人网站之前,首先要购买自己

Vue3中的生命周期函数:快速掌握Vue3的生命周期Vue3中的生命周期函数:快速掌握Vue3的生命周期Jun 18, 2023 am 08:20 AM

Vue3是目前前端界最热门的框架之一,而Vue3的生命周期函数是Vue3中非常重要的一部分。Vue3的生命周期函数可以让我们实现在特定的时机触发特定的事件,增强了组件的高度可控性。本文将从Vue3的生命周期函数的基本概念、各个生命周期函数的作用和使用方法以及实现案例等方面进行详细探究和讲解,帮助读者快速掌握Vue3的生命周期函数。一、Vue3的生命周期函数的

win10电脑怎么快速切屏win10电脑怎么快速切屏Jul 10, 2023 am 08:21 AM

电脑怎么切屏?在使用电脑的时候,有的朋友会使用两个甚至三个显示屏,但是在使用的时候,就会遇到需要切换屏幕的问题,那么电脑怎么切屏呢?一些朋友不知道电脑快速切屏方法,所以本期将教大家win10电脑怎么快速切屏。win10电脑怎么快速切屏?具体的方法如下:1、外接显示屏以后,同时按下【Fn】+【F4】或者【win】+【P】即可选择外接显示器。2、第二种方法是,在桌面空白处鼠标右键,然后选择【屏幕分辨率】。3、然后在【多显示器】中,就能够切换屏幕了。以上就是小编带来的win10电脑怎么快速切屏的全部内

分享PyCharm中快速注释代码的技巧,提高工作效率分享PyCharm中快速注释代码的技巧,提高工作效率Jan 04, 2024 pm 12:02 PM

效率提升!PyCharm中快速注释代码的方法分享在日常的软件开发工作中,我们经常需要注释掉一部分代码进行调试或者调整。如果手动逐行添加注释,这无疑会增加我们的工作量和耗费时间。而PyCharm作为一款强大的Python集成开发环境,提供了快速注释代码的功能,大大提升了我们的开发效率。本文将分享一些在PyCharm中快速注释代码的方法,并提供具体的代码示例。单

win7如何快速截屏win7如何快速截屏Jun 29, 2023 am 11:19 AM

win7如何快速截屏?win7系统之中有着很多便捷操作功能,可以为各位提供非常多样化的便捷服务。很多win7系统的用户在使用电脑的过程中,想要通过win7系统之中的快捷键进行截屏,但是却不清楚具体的快捷键是哪些,因此无法正常使用,那么,这些快捷截屏键究竟是哪些呢?下面小编就为各位带来win7快速截屏键介绍。win7快速截屏键介绍1、按Prtsc键截图这样获取的是整个电脑屏幕的内容,按Prtsc键后,可以直接打开画图工具,接粘贴使用。也可以粘贴在QQ聊天框或者Word文档中,之后再选择保存即可。2

前端开发中sessionStorage的优点及应用案例分析前端开发中sessionStorage的优点及应用案例分析Jan 11, 2024 pm 02:51 PM

sessionStorage在前端开发中的优势与应用案例分析随着Web应用的发展,前端开发的需求也越来越多样化。前端开发人员需要使用各种工具和技术来提高用户体验,其中,sessionStorage是一个非常有用的工具。本文将介绍sessionStorage在前端开发中的优势,以及几个具体的应用案例。sessionStorage是HTML5提供的一种本地存储方

VUE3初学者必备的快速开发入门指南VUE3初学者必备的快速开发入门指南Jun 15, 2023 pm 04:38 PM

VUE3初学者必备的快速开发入门指南Vue是一款流行的JavaScript框架,它的易用性、高度定制性和快速开发模式使得它在前端开发中广受欢迎。而最新的Vue3则推出了更多强大的特性,包括性能优化、TypeScript支持、CompositionAPI以及更好的自定义渲染器等等。本篇文章将为Vue3初学者提供一份快速开发入门指南,帮助你快速上手Vue3开发

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

SecList

SecList

SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전