ホームページ  >  記事  >  バックエンド開発  >  Gdb メソッドによる EG (symbol_table) ハッシュ テーブル key_PHP のチュートリアル

Gdb メソッドによる EG (symbol_table) ハッシュ テーブル key_PHP のチュートリアル

WBOY
WBOYオリジナル
2016-07-13 17:47:301158ブラウズ

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, "未定義の変数: %s", varname);

RETURN_NULL();

}

*return_value = **varvalue;

zval_copy_ctor(return_value);

}

soにコンパイルしてロードしたら、phpのテストコードを書きます

$abc = '文字列';

$def = 'string2';

var_dump(confirm_getGlobal_compiled('abc'));

実行結果

string(6) "文字列"

なぜ余分な def 変数が書かれているのか不思議に思うかもしれません。次に EG ハッシュテーブルを見てみましょう。

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

デバッグコードは以下の通りです

(gdb) b renzhi.c: 301 //書き込みの延長にブレークポイントを追加

renzhi.c.という名前のソースファイルはありません

今後の共有ライブラリのロード時にブレークポイントを保留します (y または [n]) y

ブレークポイント 1 (renzhi.c : 301) 保留中です。

(gdb) r //ブレークポイントまで実行

起動プログラム: /root/php-src-5.3/bin/php -c php.ini ceshi.php

警告: "/lib/libc.so.6" の .dynamic セクションが予期されたアドレスにありません

警告: 違いはプレリンク、期待値の調整によって生じているようです

[libthread_db を使用したスレッドのデバッグが有効]

ブレークポイント 1、zif_confirm_getGlobal_compiled (ht=1、return_value=0x837a43c、return_value_ptr=0x0、this_ptr=0x0、return_value_used=1)

/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)ん

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) /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>、永続 = 0 '

bApplyProtection = 1 '

(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このハッシュ表里面有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 = '文字列';

$def = 'string2';

 

この 2 つの量名の特定のハッシュのバケット了

 

(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 の内容を確認しますか?

 

既知のバケット構造体内の pData がコンテンツを実行します

(gdb) p ht.pListHead.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pListNext.pData

$19 = (無効 *) 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 = {値 = {lval = 138024112, dval = 1.2800167717828578e-313, str = {val = 0x83a14b0 "文字列", len = 6}, ht = 0x83a14b0, obj = {ハンドル = 138024112,

      ハンドラー = 0x6}}、refcount__gc = 1、タイプ = 6 ' 06'、is_ref__gc = 0 ' 00'}

 

哈哈、特定のハッシュ指向の値が確認できます

 

しかしまたある点不明白了pDataとpDataPtrは底有関係ですか?

 

(gdb) p &$29->pDataPtr

$46 = (ボイド **) 0x839fe28

(gdb) p $29->pData

$47 = (無効 *) 0x839fe28

つまり、pDataPtrのアドレスがpData

に格納されます

xiaoq3406さんのコラムより抜粋

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/478497.html技術記事 Sara Golemon は次のような記事を書きました: GLOBALS 配列を見つけるための特別な場所はありますか?答えは存在です、それは EG (symbol_table)-Executor Globals 構造です、と彼女はまた言いました...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。