Internal PHP and gdb php core
alpha.1986@gmail.com
Agenda
• Overview
• PHP lifecycle
• Zend Engine 2 & PHP Opcodes
• PHP 变量
• PHP 函数
• PHP OO
• Some Details
• PHP extensions...
Overview
Overview
• Php 5.2.x
– Zend Engine 2.0
• OO的改进
Overview – 代码结构
• main
– php的核心文件以及基础设施
• Zend
– Zend engine2
– 词法语法分析,虚拟机,所有与”php”相关的
• ext
– 扩展目录
• sapi
– 服务器抽象层(mod_ph...
PHP lifecycle - CLI
PHP lifecycle – Apache Multiprocess
Individual process life cycle
PHP lifecycle – Apache Multiprocess
Multiprocess life cycles
PHP lifecycle – 扩展
• PHP_MINIT_FUNCTION(mysqli);
• PHP_MSHUTDOWN_FUNCTION(mysqli);
• PHP_RINIT_FUNCTION(mysqli);
• PHP_RSH...
PHP lifecycle – execute PHP
• Lexical Analysis
• Syntax Analysis
• Opcodes Generation
• Opcodes Execution
PHP lifecycle – PHP Execution
*.php
lex
Exprs
yacc
opcodes
Zend
vm
zend_language_scanner.l
zend_language_parser.y
eAcceler...
PHP lifecycle – tokens
zend_language_scanner.l 中有所有token的定义,php的token_get_all函数可以获得
一段php代码的token
Opcodes
zend_op_array
Zend Engine 2 & PHP Opcodes
php_execute_scrip
t()
zend_execute_scripts()
zend_execute()
user call
(f...
Zend Engine 2 - execute_scripts
• PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
(main/main.c)
• ...
Zend Engine 2 - zend_compile_file
• Zend/zend.c zend_startup
• 默认指向compile_file() in zend_language_scanner.c
• ZEND_API ze...
PHP Opcodes
<?php
echo "hello world!";
通过vld扩展可以查看opcode,space@bb-space-test000
/home/space/php5/bin/php -dvld.active=1 te...
PHP Opcodes
<?php
function testHello(){
return "hello world";
}
echo testHello();
PHP Opcodes
struct _zend_op {
opcode_handler_t handler; //每一个opcode对应的回调
znode result;
znode op1;
znode op2;
ulong extende...
PHP Opcodes
• Opcodes由zend_execute来执行
• 默认情况,zend_execute指向zend_vm_execute.h
的
ZEND_API void execute(zend_op_array *op_arr...
PHP 变量
• 弱类型
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;...
PHP 变量 - type
/* data types */ // zval.type
/* All data types <= IS_BOOL have their constructor/destructors
skipped */
#de...
PHP 变量 - HashTable
• 整个zend engine最核心的数据结构
• 不仅仅是php中的array,ze中大量采用
HashTable来实现自己的逻辑,比如OO的逻辑,
全局大变量等等
• zend_hash.h
PHP 函数
<?php
fcrypt_hstr_2id("space","aaaa");
strstr("abcde","abc");
echo "done";
PHP中的user_function和扩展中的函数都是DO_FCALL指令,ec...
PHP 函数
• DO_FCALL最终调到
static int
zend_do_fcall_common_helper_SPEC(ZEND_OPCOD
E_HANDLER_ARGS)
// zend_vm_execute.h
zend_do_fcall_common_helper_SPEC
PHP 函数
• 两种类型函数
– User function(写在php代码中的函数)
– Internal function(扩展中的函数)
• Php代码的函数栈会在zend vm中也体现出
来!
– 就是zend_do_fcall_co...
PHP 函数 – 函数类型
#define ZEND_INTERNAL_FUNCTION 1
#define ZEND_USER_FUNCTION 2
#define ZEND_OVERLOADED_FUNCTION 3
#define ZEN...
PHP OO
struct _zend_class_entry {
char type;
char *name;
zend_uint name_length;
struct _*parent;
int refcozend_class_entry...
Some Details
• 大量的宏
– # define EG(v) (executor_globals.v)
//Zend/zend_globals_macros.h
– #define EX(element) execute_data-...
比较重要的全局变量
• ZEND_API zend_compiler_globals
compiler_globals;
• ZEND_API zend_executor_globals
executor_globals;
• 尤其对于exec...
PHP extensions(学习hack php的一些思路)
• eAccelerator
• Xdebug
• Xphrof
PHP extensions - eAccelerator
• PHP_MINIT_FUNCTION(eaccelerator) 中
zend_compile_file = eaccelerator_compile_file;
• eaccel...
PHP extensions - xdebug
• 函数调用的性能分析
// PHP_MINIT_FUNCTION
old_compile_file = zend_compile_file;
zend_compile_file = xdebug...
PHP extensions - xdebug
• 代码覆盖率分析
// PHP_MINIT_FUNCTION
if (XG(coverage_enable)) {
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_...
PHP extensions - Xphrof
• PHP_FUNCTION(xhprof_enable) 中进行
_zend_compile_file = zend_compile_file;
zend_compile_file = hp_c...
gdb php core
类似于下面这种,需要了解php的逻辑来排查问题的
gdb php core
• source ~/php-5.2.10/.gdbinit 初始化一些gdb
命令(方便查询hashtable)
• 如果获取当前执行在php的那个函数?
gdb php core – 在哪个类?
gdb php core – 获取php中的全局变量
• $_SERVER,$_GET,$_POST 等这些php代码中
的大变量如何获取?
• executor_globals
• executor_globals->symbol_table...
这次没有涉及到的
• PHP SAPI架构
• PHP HashTable细节
• PHP内存管理
• PHP ZTS & TSRM等线程安全机制
• OO的更多细节以及如何编写OO扩展
• 变量的作用域
• Zend vm更深入的分析
• 等...
参考资料
• Php.net
• Extending and Embedding PHP
• http://www.php-internal.com/
• http://www.laruence.com/
Thank you!
Internal php and gdb php core
Upcoming SlideShare
Loading in...5
×

Internal php and gdb php core

1,284

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,284
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
10
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Internal php and gdb php core

  1. 1. Internal PHP and gdb php core alpha.1986@gmail.com
  2. 2. Agenda • Overview • PHP lifecycle • Zend Engine 2 & PHP Opcodes • PHP 变量 • PHP 函数 • PHP OO • Some Details • PHP extensions • gdb php core
  3. 3. Overview
  4. 4. Overview • Php 5.2.x – Zend Engine 2.0 • OO的改进
  5. 5. Overview – 代码结构 • main – php的核心文件以及基础设施 • Zend – Zend engine2 – 词法语法分析,虚拟机,所有与”php”相关的 • ext – 扩展目录 • sapi – 服务器抽象层(mod_php,fastcgi,etc) • TSRM – 线程安全相关
  6. 6. PHP lifecycle - CLI
  7. 7. PHP lifecycle – Apache Multiprocess Individual process life cycle
  8. 8. PHP lifecycle – Apache Multiprocess Multiprocess life cycles
  9. 9. PHP lifecycle – 扩展 • PHP_MINIT_FUNCTION(mysqli); • PHP_MSHUTDOWN_FUNCTION(mysqli); • PHP_RINIT_FUNCTION(mysqli); • PHP_RSHUTDOWN_FUNCTION(mysqli);
  10. 10. PHP lifecycle – execute PHP • Lexical Analysis • Syntax Analysis • Opcodes Generation • Opcodes Execution
  11. 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. 12. PHP lifecycle – tokens zend_language_scanner.l 中有所有token的定义,php的token_get_all函数可以获得 一段php代码的token
  13. 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. 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. 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
  16. 16. PHP Opcodes <?php echo "hello world!"; 通过vld扩展可以查看opcode,space@bb-space-test000 /home/space/php5/bin/php -dvld.active=1 test3.php
  17. 17. PHP Opcodes <?php function testHello(){ return "hello world"; } echo testHello();
  18. 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. 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. 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. 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. 22. PHP 变量 - HashTable • 整个zend engine最核心的数据结构 • 不仅仅是php中的array,ze中大量采用 HashTable来实现自己的逻辑,比如OO的逻辑, 全局大变量等等 • zend_hash.h
  23. 23. PHP 函数 <?php fcrypt_hstr_2id("space","aaaa"); strstr("abcde","abc"); echo "done"; PHP中的user_function和扩展中的函数都是DO_FCALL指令,echo是指令不是函数
  24. 24. PHP 函数 • DO_FCALL最终调到 static int zend_do_fcall_common_helper_SPEC(ZEND_OPCOD E_HANDLER_ARGS) // zend_vm_execute.h
  25. 25. zend_do_fcall_common_helper_SPEC
  26. 26. PHP 函数 • 两种类型函数 – User function(写在php代码中的函数) – Internal function(扩展中的函数) • Php代码的函数栈会在zend vm中也体现出 来! – 就是zend_do_fcall_common_helper_SPEC形成的 栈(还包括execute,zend_execute_internal等) • abc
  27. 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. 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. 29. Some Details • 大量的宏 – # define EG(v) (executor_globals.v) //Zend/zend_globals_macros.h – #define EX(element) execute_data->element
  30. 30. 比较重要的全局变量 • ZEND_API zend_compiler_globals compiler_globals; • ZEND_API zend_executor_globals executor_globals; • 尤其对于executor_globals会有大量的运行时 数据
  31. 31. PHP extensions(学习hack php的一些思路) • eAccelerator • Xdebug • Xphrof
  32. 32. PHP extensions - eAccelerator • PHP_MINIT_FUNCTION(eaccelerator) 中 zend_compile_file = eaccelerator_compile_file; • eaccelerator_compile_file会首先从cache中读 opcode,没有cache才会重新生成,cache • 来实现opcode cache
  33. 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. 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. 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;
  36. 36. gdb php core 类似于下面这种,需要了解php的逻辑来排查问题的
  37. 37. gdb php core • source ~/php-5.2.10/.gdbinit 初始化一些gdb 命令(方便查询hashtable) • 如果获取当前执行在php的那个函数?
  38. 38. gdb php core – 在哪个类?
  39. 39. gdb php core – 获取php中的全局变量 • $_SERVER,$_GET,$_POST 等这些php代码中 的大变量如何获取? • executor_globals • executor_globals->symbol_table 全局的变量 在这个符号表里
  40. 40. 这次没有涉及到的 • PHP SAPI架构 • PHP HashTable细节 • PHP内存管理 • PHP ZTS & TSRM等线程安全机制 • OO的更多细节以及如何编写OO扩展 • 变量的作用域 • Zend vm更深入的分析 • 等等 • 这些内容也期待大家共同参与
  41. 41. 参考资料 • Php.net • Extending and Embedding PHP • http://www.php-internal.com/ • http://www.laruence.com/
  42. 42. Thank you!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×