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さんのコラムより抜粋