php symbol table,gdb方式遍历EG(symbol_table) 哈希表的key_PHP教程

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 , persistent = 0 ’00’, nApplyCount = 0 ’00’,

bApplyProtection = 1 ’01’}

(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 ’00’

如何在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 ’06’, is_ref__gc = 0 ’00’}

哈哈,可以看到具体的hash指向的值了

但是又有点不明白了pData和pDataPtr到底有啥关系?

(gdb) p &$29->pDataPtr

$46 = (void **) 0x839fe28

(gdb) p $29->pData

$47 = (void *) 0x839fe28

也就是pData里面存得是pDataPtr的地址

摘自 xiaoq3406的专栏

www.bkjia.comtrueTechArticleSara Golemon写过一篇文章,里面提到:是否存在特别的地方可以找到GLOBALS数组?答案是存在,就是EG(symbol_table)-Executor Globals结构,她也给出…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常用快捷键归纳

CtrlX     剪贴 CtrlC    复制 CtrlV    粘贴 CtrlD    删除对应行 CtrlA    全选 CtrlZ    撤销 Alt↑    两行代码互换 CtrlAltX J 运行代码 CtrlshiftO 添加缺少的包, Ctrlshift↓  向下复制本行代码转载于:https://www.cnblogs.c…

php edm 系统,edm.php

// ----------------------------------------------------------------------// | 科创众达// ----------------------------------------------------------------------// | Copyright (c) 2011 http://ctrlcoo.com All rights reserved.// -------------------------------…

jQuery选择id属性带有.点符号元素的方法

如果jquery要选择的元素id中带有点符号&#xff0c;在选择时需要在点前面加上两个反斜杠&#xff0c;如&#xff1a;$("#address\\.street").text("Enter this field");<div id"address.street"> http://www.jb51.net </div> 转载于…

单账户登录踢人 php,踢人下线

前言 在java的世界里&#xff0c;有很多优秀的权限认证框架&#xff0c;如Apache Shiro、Spring Security 等等。这些框架背景强大&#xff0c;历史悠久&#xff0c;其生态也比较齐全。 但同时这些框架也并非十分完美&#xff0c;在前后台分离已成标配的互联网时代&#xff0c;…

python 基础,包括列表,元组,字典,字符串,set集合,while循环,for循环,运算符。...

1.continue 的作用&#xff1a;跳出一次循环&#xff0c;进行下一次循环2.break 跳出不再循环3.常量 &#xff08;全是大写&#xff09;NAME cjk 一般改了会出错4.python的第三方库&#xff0c;先安装再导入。装模块&#xff1a;pip 命令例如&#xff1a;pip install pandas5…

10054 java,为什么Socket.Receive在远程主机断开连接时抛出SocketException(10054)?

我以前用C编写套接字程序&#xff0c;无法理解为什么会发生这种情况 .我的服务器在接收调用时阻塞&#xff0c;当它返回0时&#xff0c;我打破了while循环并关闭了线程 .public class MyServer {public MyServer() {}public void Init() {ThreadPool.QueueUserWorkItem(StartLi…

SQL 截取字符

select SUBSTRING(123,abcdefg,charindex(,,123,abcdefg,0)1,LEN(123,abcdefg)-charindex(,,123,abcdefg,0)) select SUBSTRING(123,abcdefg,0,charindex(,,123,abcdefg,0))转载于:https://www.cnblogs.com/kunEssay/p/5726672.html

hdoj 1004 学习思路

hdoj 1004题目大概讲的是&#xff0c;将输入的字符串根据输入次数多少&#xff0c;输出出现次数最多的字符串。 题目逻辑很简单&#xff0c;就是需要选择相应的数据结构&#xff0c;看了别人提交的discuss&#xff0c;明显发现可以使用多种数据结构解这道题。 其实我本是打算用…

oracle 关闭数据库实列,Oracle 11g 数据库启动和关闭

Oracles11数据库的启动状态Oracle11g在启动的时候必须经过三个状态&#xff1a;NOMOUNT,MOUNT,OPEN。NOMOUNT: 此状态下只打开数据库实例&#xff0c;读取参数文件。MOUNT: 根据参数文件信息&#xff0c;打开控制文件。读取控制文件中的各种信息&#xff0c;如数据文件位置&…

JavaScript进阶(下)

指定分隔符连接数组元素join() join()方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。 语法&#xff1a; arrayObject.join(分隔符) 参数说明: 注意&#xff1a;返回一个字符串&#xff0c;该字符串把数组中的各个元素串起来&#xff0c;用<…

oracle报无效月份 注册表,在oracle中插入时间时出现“无效的月份”解决方法

这个问题是我曾经在使用中遇到的&#xff0c;在网上搜了一下&#xff0c;发现很多人都遇到过&#xff0c;并且也说明了很多解决方法。引起这个问题是有很多种可能的&#xff0c;现在我将在网上收集的资料结合我自己的解决经验总结一下&#xff0c;希望对大家有帮助。我用的是or…

oracle 用户禁止登录,[转] oracle限制用户在某个时间段内禁止登录数据库

原文: http://blog.itpub.net/29371470/viewspace-1081319/ [oraclerhel ~]$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.5.0 - Production on Sat Feb 8 12:51:15 2014 Copyright (c) 1982, 2010, Oracle. All Rights Reserved. Connected to: Oracle Database 10g Enter…

ongl 表达式

struts.xml简单配置 <!-- &#xff08;默认false&#xff09;设置ognl表达式是否支持静态方法 --><constant name"struts.ognl.allowStaticMethodAccess" value"true"></constant><package name"ognl" namespace"/ogn…

oracle dd if=/dev/zero of=/dev,【转】dd if=/dev/zero of=的含义是什么?Linux 下的dd命令使用详解...

一、dd命令的解释dd&#xff1a;用指定大小的块拷贝一个文件&#xff0c;并在拷贝的同时进行指定的转换。注意&#xff1a;指定数字的地方若以下列字符结尾&#xff0c;则乘以相应的数字&#xff1a;b512&#xff1b;c1&#xff1b;k1024&#xff1b;w2参数注释&#xff1a;1. …

Python开发-- Lesson 2--Python数据类型(2016/07/30)

1、文件操作 python中对文件、文件夹&#xff08;文件操作函数&#xff09;的操作需要涉及到os模块和shutil模块。 得到当前工作目录&#xff0c;即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 函数用来删除一个文件:os.remove(…

oracle什么是重复组,规范化:“重复组”是什么意思?

扬帆大鱼英语的价值一次又一次地重复。这是重复组吗&#xff1f;不。在SUBJECT_MODULE中英语的多次出现不是重复组&#xff0c;甚至不是人们误认为重复组的两件事中的任何一个。它们也不是冗余或缺乏规范化的证据。这样的多个外观可能与冗余或规范化有关&#xff0c;但是在没有…

清除浮动php,CSS清除浮动

今天看到一篇文章关于清除浮动的&#xff0c;突然间脑袋短路了&#xff0c;咦&#xff1f;为什么要清除浮动&#xff1f;原谅我的无知&#xff0c;搜了下原来是这样&#xff0c;又倒腾出原来的笔记&#xff0c;唉&#xff0c;本来就有记录啊&#xff0c;而且也会经常用到&#…

Linux下使用Speedtest测试网速

导读Speedtest是用来测试网络性能的开源软件&#xff0c;在Linux下面安装Speedtest可以用来测试网络出口的上传和下载速度&#xff0c;帮助排查网络方面导致的故障。Speedtest介绍由于公司几个项目用户访问的时候响应较慢&#xff0c;项目本身没问题&#xff0c;服务及调用的接…

oracle leg函数,oracle对象 约束索引 游标 函数

约束视图:视图是存储在数据库中的查询的SQL 语句,视图是一个虚拟表&#xff0c;其内容由查询定义。视图就如同一张表一样&#xff0c;对表能够进行的一般操作都可以应用于视图&#xff0c;例如查询&#xff0c;插入&#xff0c;修改&#xff0c;删除操作等。当对通过视图看到的…

iOS开发ARC内存管理

本文的主要内容&#xff1a; ARC的本质ARC的开启与关闭ARC的修饰符ARC与BlockARC与Toll-Free BridgingARC的本质 ARC是编译器&#xff08;时&#xff09;特性&#xff0c;而不是运行时特性&#xff0c;更不是垃圾回收器(GC)。 Automatic Reference Counting (ARC) is a compile…