Traverse key of the EG (symbol_table) hash table using gdb

Source: Internet
Author: User

 

Sara Golemon wrote an article saying: "Is there a special place to find the GLOBALS array ?" The answer is "exist", that is, the EG (symbol_table)-Executor Globals structure. She also provided the specific instance for finding, as shown below:

 

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 );

}

 

Compile the php test code after being loaded into so.

 

$ Abc = 'string ';

$ Def = 'string2 ';

 

Var_dump (confirm_getGlobal_compiled ('abc '));

 

Execution result

 

String (6) "string"

 

You may be wondering why I wrote another def variable. This is what is going on below. Let's take a look at this hashtable.

 

Gdb -- args bin/php-c php. ini a. php

 

The debugging code is as follows:

(Gdb) B renzhi. c: 301 // Add a breakpoint to the write Extension

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 // run to the breakpoint

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. 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 // enter the zend_hash_find Hash Lookup Function

Zend_hash_find (ht = 0x82e3250, arKey = 0x837a42c "abc", nKeyLength = 4, pData = 0xbfffc484) at/root/php-src-5.3/Zend/zend_hash.c: 872

 

 

Next, let's take a look at the key points.

 

(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 = 0x80000c58, pDataPtr = 0x80000b60, pListNext = 0x80000c7c, pListLast = 0x83edc98, pNext = 0x0, pLast = 0x0,

ArKey = ""}

(Gdb) p * ht. pListHead. pListNext. pListNext

$4 = {h = 253398818, nKeyLength = 5, pData = 0x80000c88, pDataPtr = 0x80000c30, pListNext = 0x80000d20, pListLast = 0x80000c4c, pNext = 0x0, pLast = 0x0,

ArKey = ""}

(Gdb) p * ht. pListHead. pListNext

$5 = {h = 3947724458, nKeyLength = 6, pData = 0x80000d2c, pDataPtr = 0x80000cac, pListNext = 0x80000d54, pListLast = 0x80000c7c, pNext = 0x0, pLast = 0x0,

ArKey = "_"}

(Gdb) p * ht. pListHead. pListNext

$6 = {h = 249444164, nKeyLength = 5, pData = 0x80000d60, pDataPtr = 0x83edd1c, pListNext = 0x80000d84, pListLast = 0x80000d20, pNext = 0x0, pLast = 0x0,

ArKey = "_"}

(Gdb) p * ht. pListHead. pListNext

$7 = {h = 195471710, nKeyLength = 8, pData = 0x80000d90, pDataPtr = 0x83edd38, pListNext = 0x80000e2c, pListLast = 0x80000d54, pNext = 0x0, pLast = 0x0,

ArKey = "_"}

(Gdb) p * ht. pListHead. pListNext

$8 = {h = 1027153623, nKeyLength = 7, pData = 0x80000e38, pDataPtr = 0x80000db8, pListNext = 0x80000e8c, pListLast = 0x80000d84, pNext = 0x0, pLast = 0x0,

ArKey = "_"}

(Gdb) p * ht. pListHead. pListNext

$9 = {h = 3291685243, nKeyLength = 8, pData = 0x80000e98, pDataPtr = 0x80000e88, pListNext = 0x837a3cc, pListLast = 0x80000e2c, pNext = 0x0, pLast = 0x0,

ArKey = "_"}

(Gdb) p * ht. pListHead. pListNext

$10 = {h = 2090069483, nKeyLength = 4, pData = 0x837a3d8, pDataPtr = 0x81_ef8, pListNext = 0x837a3fc, pListLast = 0x81_e8c, pNext = 0x0, pLast = 0x0,

ArKey = ""}

(Gdb) p * ht. pListHead. pListNext

$11 = {h = 2090180660, nKeyLength = 4, pData = 0x837a408, pDataPtr = 0x81_edc, pListNext = 0x0, pListLast = 0x837a3cc, pNext = 0x0, pLast = 0x0,

ArKey = "d "}

 

A bit messy. The first one here is the reality. For example, the hash table contains nNumOfElements = 10 elements.

 

Here

 

(Gdb) p * ht. pListHead. pListNext

$10 = {h = 2090069483, nKeyLength = 4, pData = 0x837a3d8, pDataPtr = 0x81_ef8, pListNext = 0x837a3fc, pListLast = 0x81_e8c, pNext = 0x0, pLast = 0x0,

ArKey = ""}

(Gdb) p * ht. pListHead. pListNext

$11 = {h = 2090180660, nKeyLength = 4, pData = 0x837a408, pDataPtr = 0x81_edc, pListNext = 0x0, pListLast = 0x837a3cc, pNext = 0x0, pLast = 0x0,

ArKey = "d "}

 

Is to test the php code

 

$ Abc = 'string ';

$ Def = 'string2 ';

 

The bucket for the specific hash of the two variable names

 

(Gdb) p * ht. pListHead. pListNext

$10 = {h = 2090069483, nKeyLength = 4, pData = 0x837a3d8, pDataPtr = 0x81_ef8, pListNext = 0x837a3fc, pListLast = 0x81_e8c, pNext = 0x0, pLast = 0x0,

ArKey = ""}

 

The first character, arKey, is a and has a length of nKeyLength = 4.

 

(Gdb) p ht. pListHead. pListNext. arKey [0]

$10 = 97 'A'

(Gdb) p ht. pListHead. pListNext. arKey [1]

$11 = 98 'B'

(Gdb) p ht. pListHead. pListNext. arKey [2]

$12 = 99 'C'

(Gdb) p ht. pListHead. pListNext. arKey [3]

$13 = 0' \ 000'

 

 

How can I get the pointer in the gdb mode and see the zval content of the corresponding execution?

 

The pData in the bucket struct is executed.

(Gdb) p ht. pListHead. pListNext. pData

$19 = (void *) 0x837a3d8

 

However, you do not know how to obtain the returned result.

 

Understand

 

(Gdb) p * ht. pListHead. pListNext

$29 = {h = 2090069483, nKeyLength = 4, pData = 0x839fe28, pDataPtr = 0x839f948, pListNext = 0x839fe4c, pListLast = 0x839f8dc, pNext = 0x0, pLast = 0x0,

ArKey = ""}

(Gdb) p * (zval *) $29-> pDataPtr

$30 = {value = {lval = 138024112, dval = 1.2800167717828578e-313, str = {val = 0x83a14b0 "string", len = 6}, ht = 0x83a14b0, obj = {hand = 138024112,

Handlers = 0x6 }}, refcount _ gc = 1, type = 6' \ 006 ', is_ref _ gc = 0' \ 000 '}

 

Haha, you can see the specific hash pointing value.

 

But what is the relationship between pData and pDataPtr?

 

(Gdb) p & $29-> pDataPtr

$46 = (void **) 0x839fe28

(Gdb) p $29-> pData

$47 = (void *) 0x839fe28

 

That is, pData stores the pDataPtr address.

From the column xiaoq3406

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.