2014-09-05
Sara Golemon写过一篇文章,里面提到:“是否存在特别的地方可以找到GLOBALS数组?”答案是“存在”,就是EG(symbol_table)-Executor Globals结构,她也给出了找的具体实例,如下
PHP_FUNCTION(confirm_getGlobal_compiled) {
char *varname;
int varname_len;
zval **varvalue;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &varname, &varname_len) == FAILURE) {
RETURN_NULL();
}
if (zend_hash_find(&EG(symbol_table), varname, varname_len + 1, (void**)&varvalue) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined variable: %s", varname);
RETURN_NULL();
}
*return_value = **varvalue;
zval_copy_ctor(return_value);
}
编译成so加载后,编写php测试代码
$abc = 'string';
$def = 'string2';
var_dump(confirm_getGlobal_compiled('abc'));
执行结果
string(6) "string"
大家可能感觉奇怪,为什么多写了一个def变量,这就是下面要进行的,一起来看下EG这个hashtable
gdb --args bin/php -c php.ini a.php
调试代码如下
(gdb) b renzhi.c : 301 //在写的扩展地方加上断点
No source file named renzhi.c.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (renzhi.c : 301) pending.
(gdb) r //运行到断点处
Starting program: /root/php-src-5.3/bin/php -c php.ini ceshi.php
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
[Thread debugging using libthread_db enabled]
Breakpoint 1, zif_confirm_getGlobal_compiled (ht=1, return_value=0x837a43c, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
at /root/php-src-5.3/ext/renzhi/renzhi.c:305
305 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &varname, &varname_len) == FAILURE) {
(gdb) n
309 if (zend_hash_find(&EG(symbol_table), varname, varname_len + 1, (void**)&varvalue) == FAILURE) {
(gdb) step //进入zend_hash_find哈希查找函数
zend_hash_find (ht=0x82e3250, arKey=0x837a42c "abc", nKeyLength=4, pData=0xbfffc484) at /root/php-src-5.3/Zend/zend_hash.c:872
下面看下关键
(gdb) p *ht
$9 = {nTableSize = 64, nTableMask = 63, nNumOfElements = 10, nNextFreeElement = 0, pInternalPointer = 0x83edc98, pListHead = 0x83edc98,
pListTail = 0x837a3fc, arBuckets = 0x83705a8, pDestructor = 0x81923b0 <_zval_ptr_dtor>, persistent = 0 '/000', nApplyCount = 0 '/000',
bApplyProtection = 1 '/001'}
(gdb) p *ht.pListHead
$2 = {h = 2572561225, nKeyLength = 8, pData = 0x83edca4, pDataPtr = 0x83edc7c, pListNext = 0x8378c4c, pListLast = 0x0, pNext = 0x0, pLast = 0x0,
arKey = "G"}
(gdb) p *ht.pListHead.pListNext
$3 = {h = 253399445, nKeyLength = 5, pData = 0x8378c58, pDataPtr = 0x8378b60, pListNext = 0x8378c7c, pListLast = 0x83edc98, pNext = 0x0, pLast = 0x0,
arKey = "a"}
(gdb) p *ht.pListHead.pListNext.pListNext
$4 = {h = 253398818, nKeyLength = 5, pData = 0x8378c88, pDataPtr = 0x8378c30, pListNext = 0x8378d20, pListLast = 0x8378c4c, pNext = 0x0, pLast = 0x0,
arKey = "a"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext
$5 = {h = 3947724458, nKeyLength = 6, pData = 0x8378d2c, pDataPtr = 0x8378cac, pListNext = 0x8378d54, pListLast = 0x8378c7c, pNext = 0x0, pLast = 0x0,
arKey = "_"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext
$6 = {h = 249444164, nKeyLength = 5, pData = 0x8378d60, pDataPtr = 0x83edd1c, pListNext = 0x8378d84, pListLast = 0x8378d20, pNext = 0x0, pLast = 0x0,
arKey = "_"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext
$7 = {h = 195471710, nKeyLength = 8, pData = 0x8378d90, pDataPtr = 0x83edd38, pListNext = 0x8378e2c, pListLast = 0x8378d54, pNext = 0x0, pLast = 0x0,
arKey = "_"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$8 = {h = 1027153623, nKeyLength = 7, pData = 0x8378e38, pDataPtr = 0x8378db8, pListNext = 0x8379e8c, pListLast = 0x8378d84, pNext = 0x0, pLast = 0x0,
arKey = "_"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$9 = {h = 3291685243, nKeyLength = 8, pData = 0x8379e98, pDataPtr = 0x8378e88, pListNext = 0x837a3cc, pListLast = 0x8378e2c, pNext = 0x0, pLast = 0x0,
arKey = "_"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$10 = {h = 2090069483, nKeyLength = 4, pData = 0x837a3d8, pDataPtr = 0x8379ef8, pListNext = 0x837a3fc, pListLast = 0x8379e8c, pNext = 0x0, pLast = 0x0,
arKey = "a"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$11 = {h = 2090180660, nKeyLength = 4, pData = 0x837a408, pDataPtr = 0x8379edc, pListNext = 0x0, pListLast = 0x837a3cc, pNext = 0x0, pLast = 0x0,
arKey = "d"}
有点乱,这里第一条就是现实了EG这个hash表里面有nNumOfElements =10个元素
这里的
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$10 = {h = 2090069483, nKeyLength = 4, pData = 0x837a3d8, pDataPtr = 0x8379ef8, pListNext = 0x837a3fc, pListLast = 0x8379e8c, pNext = 0x0, pLast = 0x0,
arKey = "a"}
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$11 = {h = 2090180660, nKeyLength = 4, pData = 0x837a408, pDataPtr = 0x8379edc, pListNext = 0x0, pListLast = 0x837a3cc, pNext = 0x0, pLast = 0x0,
arKey = "d"}
就是测试php代码里面的
$abc = 'string';
$def = 'string2';
这两个变量名称的具体hash的bucket了
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$10 = {h = 2090069483, nKeyLength = 4, pData = 0x837a3d8, pDataPtr = 0x8379ef8, pListNext = 0x837a3fc, pListLast = 0x8379e8c, pNext = 0x0, pLast = 0x0,
arKey = "a"}
第一个字符arKey为a,有nKeyLength = 4四个字符长度
(gdb) p ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.arKey[0]
$10 = 97 'a'
(gdb) p ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.arKey[1]
$11 = 98 'b'
(gdb) p ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.arKey[2]
$12 = 99 'c'
(gdb) p ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.arKey[3]
$13 = 0 '/000'
如何在gdb方式下拿到指针了,看到对应的执行的zval的内容呢?
已经知道了bucket结构体中的pData就执行了内容
(gdb) p ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pData
$19 = (void *) 0x837a3d8
但是返回的这个,还不知道如何获得,请高手帮助
搞明白了
(gdb) p *ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext
$29 = {h = 2090069483, nKeyLength = 4, pData = 0x839fe28, pDataPtr = 0x839f948, pListNext = 0x839fe4c, pListLast = 0x839f8dc, pNext = 0x0, pLast = 0x0,
arKey = "a"}
(gdb) p *(zval *)$29->pDataPtr
$30 = {value = {lval = 138024112, dval = 1.2800167717828578e-313, str = {val = 0x83a14b0 "string", len = 6}, ht = 0x83a14b0, obj = {handle = 138024112,
handlers = 0x6}}, refcount__gc = 1, type = 6 '/006', is_ref__gc = 0 '/000'}
哈哈,可以看到具体的hash指向的值了
但是又有点不明白了pData和pDataPtr到底有啥关系?
(gdb) p &$29->pDataPtr
$46 = (void **) 0x839fe28
(gdb) p $29->pData
$47 = (void *) 0x839fe28
也就是pData里面存得是pDataPtr的地址
摘自 xiaoq3406的专栏
1
CI框架连接数据库配置操作以及多数据库操作
09-05
2
asp 简单读取数据表并列出来 ASP如何快速从数据库读取大量数据
05-17
3
C语言关键字及其解释介绍 C语言32个关键字详解
04-05
4
C语言中sizeof是什么意思 c语言里sizeof怎样用法详解
04-26
5
PHP中的魔术方法 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep,
09-05
6
将视频设置为Android手机开机动画的教程
12-11
7
PHP中的(++i)前缀自增 和 (i++)后缀自增
09-05
8
常用dos命令及语法
09-27
PHP中include和require区别之我见
2014-09-05
最简单的asp登陆界面代码 asp登陆界面源代码详细介绍
2017-04-12
php递归返回值的问题
2014-09-05
如何安装PHPstorm并配置方法教程 phpstorm安装后要进行哪些配置
2017-05-03
单片机编程好学吗?单片机初学者怎样看懂代码
2022-03-21
PHP 教程之如何使用BLOB存取图片信息实例
2014-09-05
零基础的初学者怎样学习java,或者应该先学什么?
2022-03-21
学ug编程如何快速入门?
2022-03-17
PHP数组函数array
2014-09-05
学习使用C语言/C++编程的7个步骤!超赞~
2022-03-20
球球大作战汉化版下载v19.7.1 安卓版
其它手游 170.54MB
下载
葫芦侠三楼最新破解版下载v4.4.0.6 安卓版
其它手游 34.82MB
下载
葫芦侠7楼破解版免费下载v4.4.0.6安卓最新版
其它手游 34.82MB
下载
葫芦侠八楼免费版下载v4.4.0.6安卓版
其它手游 34.82MB
下载
葫芦侠3楼破解版免费下载v4.4.0.6安卓手机版
其它手游 34.82MB
下载
像素漫斗抱歉,“八神庵”是特指游戏角色的专有名词,不存在符合要求的常用同义词近义词。下载v1.00安卓版
其它手游 206.87MB
下载
葫芦侠4楼破解版游戏修改器下载v4.4.0.6安卓免费版
其它手游 34.82MB
下载
末日餐厅安卓版下载v1.35安卓版
其它手游 73.98MB
下载葫芦侠十楼免费破解版下载v4.4.0.6安卓版
下载
葫芦侠8楼最新破解版下载v4.4.0.6安卓版
下载
猫娘乐园世界连结正版下载v1.9.1 安卓版
下载
像素漫斗全员下载v1.00安卓版
下载
葫芦侠8楼手机版下载v4.4.0.6安卓版
下载
末日餐厅正版官网入口下载v1.35安卓版
下载
我的汉克狗正版下载v26.4.1.48473 安卓版
下载
像素漫斗u鼬神最新版本下载v1.00安卓版
下载