PHP Kernel parsing

Source: Internet
Author: User
Tags php source code vars

PHP is to first parse the source code into opcode, and then pass the opcode to ZEND_VM for execution.

//a opcode structure struct _zend_op {const void *handler; //opcode corresponding execution function, each opcode has a corresponding execution function znode_op OP1; //the first element of the execution parameter Znode_op OP2; //the second element of the execution parameter znode_op result; //implementation results uint32_t extended_value; //additional extended fields and values uint32_t Lineno; //line number Zend_uchar opcode; //operation code, the specific operation code list see http://cn.php.net/manual/zh/internals2.opcodes.php Zend_uchar op1_type; //the first element of the type Zend_uchar op2_type; //the type of the second element Zend_uchar Result_type; //result type};             

In Php7, we can easily use phpdbg to view a file or a function's opcode. As for the use of phpdbg, there is not much online introduction, but fortunately there is a very detailed help documentation. Here is one of the simplest opcode codes:

$ bin/phpdbg-f/home/xiaoju/software/php7/demo/Echo.phpprompt>List10000001:<?php00002:00003: $a =1; 00004: $b = $a; 00005: $b = $b + 1; 00006: echo $b; print exec[context/home/xiaoju/software/php7/demo/echo.php (6 Ops)]l1-7 {main} ()/home/xiaoju/ Software/php7/demo/echo.php-0x7fe3fae63300 + 6 opsL3  #0 ASSIGN $a 1l4  #1 ASSIGN $b $aL 5  #2 ADD $b 1 ~2l5  #3 ASSIGN $b ~2l6  #4 ECHO $bL 7 
                             
                               #5 RETURN 1 
                                        

This PHP file does one of the simplest addition operations. 6 _zend_op were generated. Each of the lines shown represents a _zend_op

_zendop.lineno  op号   _zend_op.opcode       _zend_op.op1          _zend_op.op2          _zend_op.resultL5              #2     ADD                     $b                   1                    ~2

Here _zend_op.opcode corresponding operation on the official website have documents and detailed examples can be viewed: http://cn.php.net/manual/zh/internals2.opcodes.php

It is worth saying that phpdbg also has a remote UI version that allows us to access PHP information on the near-end diagnostics server

Gdb

But our goal is to study PHP source code, phpdbg can only analyze to opcode this layer, or is not enough, gdb may be a better choice.

GDB uses the same as usual

For example, I now have a script echo.php:

  1 <?php  2  3 $a = 1; 4 $b = $a; 5 $b = $b + 1; 6 echo $b;

My PHP installation path is:

/home/xiaoju/software/php7/bin/php

PHP Source Path in:

/home/xiaoju/webroot/php-src/php-src-master/

Run GDB

/home/xiaoju/software/php7/bin/php

Load Gdbinit:

/home/xiaoju/webroot/php-src/php-src-master/.gdbinit

To set breakpoints:

(gdb) b zend_execute_scripts

Run:

/home/xiaoju/software/php7/demo/echo.php

I want to set a breakpoint on this line in 1459:

1452          for (i = 0; i < file_count; i++) {1453               file_handle = va_arg(files, zend_file_handle *);1454               if (!file_handle) {1455                    continue;1456               }14571458               op_array = zend_compile_file(file_handle, type);1459               if (file_handle->opened_path) {1460 zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);1461 }(gdb) b 1459

Keep running.

(gdb) continue(gdb) s(gdb) s

Print out the op_array of this time

(GDB) P *op_array$4 = {type =2' \002 ', arg_flags ="\000\000", Fn_flags =134217728, function_name =0x0, scope =0x0Prototype =0x0, Num_args =0, Required_num_args =0, Arg_info =0x0, RefCount =0x7ffff6002000,Last =6, opcodes =0x7ffff6076240, Last_var =2, T =4, VARs =0x7ffff6079030, Last_live_range = 0, Last_try_catch = 0, Live_range = 0x0, Try_catch_array = 0x0, stat Ic_variables = 0x0, filename = 0x7ffff605c2d0, Line_start = 1, line_end = 7, doc_comment = 0x0, early_ binding = 4294967295, last_literal = 3, literals = 0x7ffff60030c0, cache_size = 0, Run_time_cache = 
                                   
                                    0x0, reserved = {
                                    0x0, 0x0, 0x0, 0x0}}    
                                       

I can optimize the output:

(GDB)Set Print PrettyOn (GDB)P *op_array$5 = {Type =2' \002 ', arg_flags ="\000\000", Fn_flags =134217728, function_name =0x0Scope =0x0, prototype =0x0, Num_args =0, Required_num_args =0, Arg_info =0x0, RefCount =0x7ffff6002000,Last =6, opcodes =0x7ffff6076240, Last_var =2,T =4, VARs =0x7ffff6079030, Last_live_range = 0, Last_try_catch = 0, Live_range = 0x0, Try_catch_array = 0x0, static _variables = 0x0, filename = 0x7ffff605c2d0, Line_start = 1, line_end = 7, doc_comment = 0x0, Early_ binding = 4294967295, last_literal = 3, literals = 0x7ffff60030c0, cache_size = 0, Run_time_cache =  0x0, reserved = {0x0, 0x0, 0x0, 0x0}}             

I want to op_array.filename.val the exact value.

40(gdb) p *(op_array.filename.val)@40$13 = "/home/xiaoju/software/php7/demo/echo.php"

Well, we can study the structure of _zend_op_array in the way:

An array of opcode that is compiled to generate this structurestruct _zend_op_array {Zend_uchar type;The type of OP array, such as Zend_eval_code Zend_uchar arg_flags[3];/* Bitset of Arg_info.pass_by_reference */uint32_t fn_flags; Zend_string *function_name; Zend_class_entry *scope; Zend_function *prototype;uint32_t Num_args;Parameters of the scriptuint32_t Required_num_args; Zend_arg_info *arg_info;/* END of common Elements */uint32_t *refcount;The number of references to this structureUint32_t last;The number of opcode zend_op *opcodes;Store all the opcodeint Last_var;Number of PHP variablesuint32_t T; Zend_string **vars;The number of PHP variables that are compiledint last_live_range;int last_try_catch;The number of Try_catch Zend_live_range *live_range; Zend_try_catch_element *try_catch_array;///* static variables support */HashTable *static_variables; Span class= "hljs-comment" >//static variable zend_string *filename; //executed script file uint32_t Line_start; //began in the first few lines uint32_t line_end; //ended in the first few lines zend_string *doc_comment; //Documentation comments uint32_t early_binding; /* the linked list of delayed declarations */int last_literal; Zval *literals; int cache_size; void **run_time_cache; void *reserved[zend_max_reserved_resources]; //reserved field}; 
Go from http://www.cnblogs.com/yjf512/

PHP Kernel parsing

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.