存储opline的内存地址可以实时跟踪opcode的执行
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的执行的更多相关文章
- 汇编语言 Part 1——简介、基本语法、内存分段与内存地址
简介 什么是汇编语言? 汇编语言是一种低级的编程语言,在程序的语句和体系结构的机器代码指令之间有很强的对应关系. 每种汇编语言都特定于特定的计算机体系结构,但需要解释或编译.汇编语言也可以称为符号机器 ...
- python获取内存地址上存储的值
在python中,可以通过id()这个方法来获取对象的内存地址. 但是反过来,怎么获取内存地址上存储的值? 先看一段代码: from ctypes import string_at from sys ...
- Bugtags 实时跟踪插件 - BugtagsInsta
BugtagsInsta 是 Bugtags SDK 的官方插件,应用集成成功后,可以在 Bugtags 云端管理平台实时查看应用的运行时数据:操作步骤.用户数据.控制台日志.Bugtags 日志.网 ...
- c语言中通过指针将数值赋值到制定内存地址
1.一种直观的方法 假设现在需要往内存0x12ff7c地址上存入一个整型数0x100.我们怎么才能做到呢? 我们知道可以通过一个指针向其指向的内存地址写入数据,那么这里的内存地址0x12ff7c其本质 ...
- C语言内存地址基础
来源:http://blog.jobbole.com/44845/ 从计算机内存的角度思考C语言中的一切东东,是挺有帮助的.我们可以把计算机内存想象成一个字节数组,内存中每一个地址表示 1 字节.比方 ...
- C语言精要总结-内存地址对齐与struct大小判断篇
在笔试时,经常会遇到结构体大小的问题,实际就是在考内存地址对齐.在实际开发中,如果一个结构体会在内存中高频地分配创建,那么掌握内存地址对齐规则,通过简单地自定义对齐方式,或者调整结构体成员的顺序,可以 ...
- 07_Python变量内存地址、小数据池
一.变量在内存中的地址 变量:用来标识(identify)一块内存区域.为了方便表示内存,我们操作变量实质上是在操作变量指向的那块内存单元.编译器负责分配.我们可以使用Python内建函数id()来获 ...
- Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...
- day06 内存地址 小数据池缓存机制
1. 内存相关 示例一 v1=[11,22,33] v2=[11,22,33] #值相等 内存地址不等 v1=11 v2=11 #按理说内存地址应该不等,但是python为了优化使其内存地址相等 v1 ...
随机推荐
- Tensorflow物体检测(Object Detection)API的使用
Tensorflow在更新1.2版本之后多了很多新功能,其中放出了很多用tf框架写的深度网络结构(看这里),大大降低了吾等调包侠的开发难度,无论是fine-tuning还是该网络结构都方便了不少.这里 ...
- Redis使用示例及在PHP环境中用redis存储session
在文件夹redis-3.2.0下 1. 启动redis服务 nohup ./src/redis-server redis.conf & 2. 停止服务 #使用客户端 ./src/redis-c ...
- Tomcat------如何更改被IIS占用的80端口
1.打开cmd,运行'netstat -ano'发现80端口被pid=4的进程占用 2.打开任务管理器,发现pid=4的进程,其实是system进程,其对应的进程描述是NT kernel & ...
- Java位运算加密
创建一个类,通过位运算中的”^"异或运算符把字符串与一个指定的值进行异或运算,从而改变字符串每个字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,再与那个指定的 ...
- MySQL --- 计算指定日期为当月的第几周
SET @d=NOW(); ; 啦啦啦
- 浅谈千万级PV/IP规模高性能高并发网站架构(转自老男孩)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.com/2561410/736710 如果把来 ...
- LINUX安装中文输入法和那些大坑
明明有很多事要做,却偏偏不知道要做什么,这种感觉,很令人上火. 一.基础知识 在原生ubuntu14.04英文环境系统中只有IBus拼音,真的好难用.由于搜狗输入法确实比Linux系统下其它的中文输入 ...
- JQuery选择器和DOM的操作-入门学习
嘿嘿,今天学习了JQuery,前面的一周都在学习javascript,今天学习了JQuery,虽然javascript的类库有很多个,例如:Prototype,Dojo,JQuery等,javascr ...
- Hibernate系列之基本配置
一.概述 Hibernate是一个开放源码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使我们可以使用对象的编程思维来操作数据库. 二.配置准备 IDE:Eclipse 下载Jar包: ...
- easy-ui curd方法
/** _ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ .' \\| |// `. / \\||| : ...