static intphp_handler(request_rec *r) { /* Initiliaze the context */ php_struct * volatile ctx; void *conf; apr_bucket_brigade * volatile brigade; apr_bucket *bucket; apr_status_t rv; request_rec * volatile parent_req = NULL; TSRMLS_FETCH(); ...... zend_file_handle zfd; zfd.type = ZEND_HANDLE_FILENAME; zfd.filename = (char *) r->filename; zfd.free_filename = 0; zfd.opened_path = NULL; zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC, NULL, 1, &zfd); ...... } ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */ { ...... EG(active_op_array) = \ zend_compile_file(file_handle, type TSRMLS_CC); ...... zend_execute(EG(active_op_array) TSRMLS_CC); ...... } ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) { // 初始化执行上下文 zend_execute_data execute_data; // 如果有异常就退出执行 if (EG(exception)) { return; } /* Initialize execute_data */ EX(fbc) = NULL; // 初始化正在调用的函数 EX(object) = NULL; // 初始化正在调用的对象 EX(old_error_reporting) = NULL; // 初始化错误报告变量 // 为执行栈分配空间 if (op_array->T T); } else { EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0); } // 为临时变量分配空间并初始化这些空间 EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var); memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); EX(op_array) = op_array; // 切换执行上下文 EX(original_in_execution) = EG(in_execution); EX(symbol_table) = EG(active_symbol_table); EX(prev_execute_data) = EG(current_execute_data); // 将当前全局变量中的执行数据压栈 EG(current_execute_data) = &execute_data; // 将当前执行上下文压栈 EG(in_execution) = 1; // 初始化第一个指令(opcode) /* #define ZEND_VM_SET_OPCODE(new_op) \ CHECK_SYMBOL_TABLES() \ EX(opline) = new_op execute_data.opline 为当前执行的 opcode */ if (op_array->start_op) { ZEND_VM_SET_OPCODE(op_array->start_op); } else { ZEND_VM_SET_OPCODE(op_array->opcodes); } if (op_array->uses_this && EG(This)) { EG(This)->refcount++; /* For $this pointer */ if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) { EG(This)->refcount--; } } // 将存储opline的内存地址赋给 executor_globals.online_ptr ,可以实时跟踪opcode的执行 EG(opline_ptr) = &EX(opline); EX(function_state).function = (zend_function *) op_array; EG(function_state_ptr) = &EX(function_state); #if ZEND_DEBUG /* function_state.function_symbol_table is saved as-is to a stack, * which is an intentional UMR. Shut it up if we're in DEBUG. */ EX(function_state).function_symbol_table = NULL; #endif while (1) { #ifdef ZEND_WIN32 if (EG(timed_out)) { zend_timeout(0); } #endif // 循环调用每个opline的 handler 函数,如果是推出函数的话,返回值大于0,就退出 if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) { return; } } zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen"); 2881064151}

存储opline的内存地址可以实时跟踪opcode的执行的更多相关文章

  1. 汇编语言 Part 1——简介、基本语法、内存分段与内存地址

    简介 什么是汇编语言? 汇编语言是一种低级的编程语言,在程序的语句和体系结构的机器代码指令之间有很强的对应关系. 每种汇编语言都特定于特定的计算机体系结构,但需要解释或编译.汇编语言也可以称为符号机器 ...

  2. python获取内存地址上存储的值

    在python中,可以通过id()这个方法来获取对象的内存地址. 但是反过来,怎么获取内存地址上存储的值? 先看一段代码: from ctypes import string_at from sys ...

  3. Bugtags 实时跟踪插件 - BugtagsInsta

    BugtagsInsta 是 Bugtags SDK 的官方插件,应用集成成功后,可以在 Bugtags 云端管理平台实时查看应用的运行时数据:操作步骤.用户数据.控制台日志.Bugtags 日志.网 ...

  4. c语言中通过指针将数值赋值到制定内存地址

    1.一种直观的方法 假设现在需要往内存0x12ff7c地址上存入一个整型数0x100.我们怎么才能做到呢? 我们知道可以通过一个指针向其指向的内存地址写入数据,那么这里的内存地址0x12ff7c其本质 ...

  5. C语言内存地址基础

    来源:http://blog.jobbole.com/44845/ 从计算机内存的角度思考C语言中的一切东东,是挺有帮助的.我们可以把计算机内存想象成一个字节数组,内存中每一个地址表示 1 字节.比方 ...

  6. C语言精要总结-内存地址对齐与struct大小判断篇

    在笔试时,经常会遇到结构体大小的问题,实际就是在考内存地址对齐.在实际开发中,如果一个结构体会在内存中高频地分配创建,那么掌握内存地址对齐规则,通过简单地自定义对齐方式,或者调整结构体成员的顺序,可以 ...

  7. 07_Python变量内存地址、小数据池

    一.变量在内存中的地址 变量:用来标识(identify)一块内存区域.为了方便表示内存,我们操作变量实质上是在操作变量指向的那块内存单元.编译器负责分配.我们可以使用Python内建函数id()来获 ...

  8. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  9. day06 内存地址 小数据池缓存机制

    1. 内存相关 示例一 v1=[11,22,33] v2=[11,22,33] #值相等 内存地址不等 v1=11 v2=11 #按理说内存地址应该不等,但是python为了优化使其内存地址相等 v1 ...

随机推荐

  1. showModalDialog介绍

    基本介绍:          showModalDialog()         (IE 4+ 支持)          showModelessDialog()      (IE 5+ 支持)    ...

  2. manifest.json文件介绍

    { // 必须 "manifest_version": 2, // 清单文件的版本,这个必须写,而且必须是2 "name": "My Extensio ...

  3. SpringBoot------使用Fastjson解析Json数据

    方法一: 1.在pom.xml文件下添加依赖包 <dependency> <groupId>com.alibaba</groupId> <artifactId ...

  4. PMP模拟考试-1

    1. A manufacturing project has a schedule performance index (SPI) of 0.89 and a cost performance ind ...

  5. SpringMVC由浅入深day02_1课程安排_2包装类型pojo参数绑定_3集合类型绑定

    springmvc第二天 高级知识 复习: springmvc框架: DispatcherServlet前端控制器:接收request,进行response HandlerMapping处理器映射器: ...

  6. 递归的几个demo

    /** * Created by root * Description : 递归函数 */ object RecursionTest { def main(args: Array[String]): ...

  7. iOS开发-- 设置UIButton的文字显示位置、字体的大小、字体的颜色

    btn.frame = CGRectMake(x, y, width, height); [btn setTitle: @"search" forState: UIControlS ...

  8. Linux 集群架构

    集群介绍 Keepalived 配置高可用集群

  9. flask实现简单的接收json返回json的接口

    结合http://docs.jinkan.org/docs/flask/quickstart.html#a-minimal-application这个flask文档实现 #!/usr/bin/pyth ...

  10. C++ template —— 动多态与静多态(六)

    前面的几篇博文介绍了模板的基础知识,并且也深入的讲解了模板的特性.接下来的博文中,将会针对模板与设计进行相关的介绍.------------------------------------------ ...