Más contenido relacionado
La actualidad más candente (20)
Similar a Internal php and gdb php core (20)
Internal php and gdb php core
- 2. Agenda
• Overview
• PHP lifecycle
• Zend Engine 2 & PHP Opcodes
• PHP 变量
• PHP 函数
• PHP OO
• Some Details
• PHP extensions
• gdb php core
- 5. Overview – 代码结构
• main
– php的核心文件以及基础设施
• Zend
– Zend engine2
– 词法语法分析,虚拟机,所有与”php”相关的
• ext
– 扩展目录
• sapi
– 服务器抽象层(mod_php,fastcgi,etc)
• TSRM
– 线程安全相关
- 9. PHP lifecycle – 扩展
• PHP_MINIT_FUNCTION(mysqli);
• PHP_MSHUTDOWN_FUNCTION(mysqli);
• PHP_RINIT_FUNCTION(mysqli);
• PHP_RSHUTDOWN_FUNCTION(mysqli);
- 10. PHP lifecycle – execute PHP
• Lexical Analysis
• Syntax Analysis
• Opcodes Generation
• Opcodes Execution
- 11. PHP lifecycle – PHP Execution
*.php
lex
Exprs
yacc
opcodes
Zend
vm
zend_language_scanner.l
zend_language_parser.y
eAccelerator(eacc)
eaccelerator.c,
PHP_MINIT_FUNCTION(eaccele
rator)
- 12. PHP lifecycle – tokens
zend_language_scanner.l 中有所有token的定义,php的token_get_all函数可以获得
一段php代码的token
- 13. Opcodes
zend_op_array
Zend Engine 2 & PHP Opcodes
php_execute_scrip
t()
zend_execute_scripts()
zend_execute()
user call
(function/method)
包括定义在php中的函数和扩展里的函数
include/require
zend_compile_file()
函数指针
Zend engine 整体流程
- 14. Zend Engine 2 - execute_scripts
• PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
(main/main.c)
• ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int
file_count, ...) (Zend/zend.c)
• php_execute_script把auto_prepend_file,
primary_file,auto_prepend_file这三个文件
传给zend_execute_scripts
- 15. Zend Engine 2 - zend_compile_file
• Zend/zend.c zend_startup
• 默认指向compile_file() in zend_language_scanner.c
• ZEND_API zend_op_array *compile_file(zend_file_handle
*file_handle, int type TSRMLS_DC)
• Lexical Analysis -> Syntax Analysis -> Opcodes Generation
- 18. PHP Opcodes
struct _zend_op {
opcode_handler_t handler; //每一个opcode对应的回调
znode result;
znode op1;
znode op2;
ulong extended_value;
uint lineno;
zend_uchar opcode; // opcode值
};
typedef int (*opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);
typedef unsigned char zend_uchar;
//zend_compile.h( _zend_op_array 也在这里)
- 19. PHP Opcodes
• Opcodes由zend_execute来执行
• 默认情况,zend_execute指向zend_vm_execute.h
的
ZEND_API void execute(zend_op_array *op_array
TSRMLS_DC)
• 每个opcode的回调都存在全局变量zend_opcode_handlers
中,初始化在zend_init_opcodes_handlers()
• 回调命名规则
ZEND_[opcode]_SPEC_(变量类型1)_(变量类型2)_HANDLER
- 20. PHP 变量
• 弱类型
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
//zend.h
typedef struct _zval_struct zval;
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount;
zend_uchar type; /* active type */
zend_uchar is_ref;
};
- 21. PHP 变量 - type
/* data types */ // zval.type
/* All data types <= IS_BOOL have their constructor/destructors
skipped */
#define IS_NULL 0
#define IS_LONG 1
#define IS_DOUBLE 2
#define IS_BOOL 3
#define IS_ARRAY 4
#define IS_OBJECT 5
#define IS_STRING 6
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9
- 22. PHP 变量 - HashTable
• 整个zend engine最核心的数据结构
• 不仅仅是php中的array,ze中大量采用
HashTable来实现自己的逻辑,比如OO的逻辑,
全局大变量等等
• zend_hash.h
- 26. PHP 函数
• 两种类型函数
– User function(写在php代码中的函数)
– Internal function(扩展中的函数)
• Php代码的函数栈会在zend vm中也体现出
来!
– 就是zend_do_fcall_common_helper_SPEC形成的
栈(还包括execute,zend_execute_internal等)
• abc
- 27. PHP 函数 – 函数类型
#define ZEND_INTERNAL_FUNCTION 1
#define ZEND_USER_FUNCTION 2
#define ZEND_OVERLOADED_FUNCTION 3
#define ZEND_EVAL_CODE 4
#define ZEND_OVERLOADED_FUNCTION_TEMPORARY
typedef union _zend_function {
zend_uchar type; /* MUST be the first element of this struct! */
struct {
zend_uchar type; /* never used */
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;
} common;
zend_op_array op_array;
zend_internal_function internal_function;
} zend_function;
- 28. PHP OO
struct _zend_class_entry {
char type;
char *name;
zend_uint name_length;
struct _*parent;
int refcozend_class_entry unt;
HashTable function_table;
HashTable default_properties;
HashTable properties_info;
HashTable default_static_members;
HashTable *static_members;
HashTable constants_table;
struct _zend_function_entry *builtin_functions;
union _zend_function *constructor;
union _zend_function *destructor;
union _zend_function *clone;
union _zend_function *__get;
union _zend_function *serialize_func;
union _zend_function *unserialize_func;
……..
- 29. Some Details
• 大量的宏
– # define EG(v) (executor_globals.v)
//Zend/zend_globals_macros.h
– #define EX(element) execute_data->element
- 32. PHP extensions - eAccelerator
• PHP_MINIT_FUNCTION(eaccelerator) 中
zend_compile_file = eaccelerator_compile_file;
• eaccelerator_compile_file会首先从cache中读
opcode,没有cache才会重新生成,cache
• 来实现opcode cache
- 33. PHP extensions - xdebug
• 函数调用的性能分析
// PHP_MINIT_FUNCTION
old_compile_file = zend_compile_file;
zend_compile_file = xdebug_compile_file;
xdebug_old_execute = zend_execute;
zend_execute = xdebug_execute;
xdebug_orig_header_handler = sapi_module.header_handler;
sapi_module.header_handler = xdebug_header_handler;
xdebug_execute做完一堆
事情后,再调回
xdebug_old_execute
- 34. PHP extensions - xdebug
• 代码覆盖率分析
// PHP_MINIT_FUNCTION
if (XG(coverage_enable)) {
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMP);
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPZ);
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPZ_EX);
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPNZ);
#define XDEBUG_SET_OPCODE_OVERRIDE_COMMON(oc)
zend_set_user_opcode_handler(oc, xdebug_common_override_handler);
- 35. PHP extensions - Xphrof
• PHP_FUNCTION(xhprof_enable) 中进行
_zend_compile_file = zend_compile_file;
zend_compile_file = hp_compile_file;
/* Replace zend_execute with our proxy */
_zend_execute = zend_execute;
zend_execute = hp_execute;
- 37. gdb php core
• source ~/php-5.2.10/.gdbinit 初始化一些gdb
命令(方便查询hashtable)
• 如果获取当前执行在php的那个函数?
- 39. gdb php core – 获取php中的全局变量
• $_SERVER,$_GET,$_POST 等这些php代码中
的大变量如何获取?
• executor_globals
• executor_globals->symbol_table 全局的变量
在这个符号表里
- 41. 这次没有涉及到的
• PHP SAPI架构
• PHP HashTable细节
• PHP内存管理
• PHP ZTS & TSRM等线程安全机制
• OO的更多细节以及如何编写OO扩展
• 变量的作用域
• Zend vm更深入的分析
• 等等
• 这些内容也期待大家共同参与