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 <_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的专栏

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Comment configurer le démarrage du clavier sur la carte mère de Gigabyte Tout d'abord, s'il doit prendre en charge le démarrage du clavier, il doit s'agir d'un clavier PS2 ! ! Les étapes de configuration sont les suivantes : Étape 1 : appuyez sur Suppr ou F2 pour entrer dans le BIOS après le démarrage, et entrez dans le mode avancé (avancé) du BIOS. Les cartes mères ordinaires entrent dans le mode EZ (facile) de la carte mère par défaut. pour appuyer sur F7 pour passer au mode avancé. Les cartes mères de la série ROG entrent dans le BIOS par défaut (nous utilisons le chinois simplifié pour démontrer) Étape 2 : Sélectionnez - [Avancé] - [Gestion avancée de l'alimentation (APM)] Étape 3 : Recherchez l'option [Réveil par le clavier PS2] Étape 4 : Cette option est désactivée par défaut. Après avoir tiré vers le bas, vous pouvez voir trois options de configuration différentes, à savoir appuyer sur [barre d'espace] pour allumer l'ordinateur, appuyer sur groupe.

1. Comment pouvez-vous gagner de l'argent en publiant des articles sur Toutiao aujourd'hui ? Comment gagner plus de revenus en publiant des articles sur Toutiao dès aujourd'hui ! 1. Activer les droits et intérêts fondamentaux : les articles originaux peuvent générer des bénéfices grâce à la publicité, et les vidéos doivent être originales en mode écran horizontal pour générer des bénéfices. 2. Activez les droits de 100 fans : si le nombre de fans atteint 100 fans ou plus, vous pouvez tirer des bénéfices des micro-titres, de la création originale de questions-réponses et des questions-réponses. 3. Insistez sur les œuvres originales : les œuvres originales comprennent des articles, des micro-titres, des questions, etc., et doivent contenir plus de 300 mots. Veuillez noter que si des œuvres illégalement plagiées sont publiées en tant qu'œuvres originales, des points de crédit seront déduits, et même les éventuels bénéfices seront déduits. 4. Verticalité : lorsque vous rédigez des articles dans des domaines professionnels, vous ne pouvez pas écrire à volonté des articles dans tous les domaines, vous n'obtiendrez pas de recommandations appropriées, vous ne pourrez pas atteindre le professionnalisme et le raffinement de votre travail et il sera difficile d'attirer des fans. et les lecteurs. 5. Activité : forte activité,

1. Processeur Lors du choix d'une configuration informatique, le processeur est l'un des composants les plus importants. Pour jouer à des jeux comme CS, les performances du processeur affectent directement la fluidité et la vitesse de réponse du jeu. Il est recommandé de choisir les processeurs Intel Core i5 ou i7 car ils disposent de puissantes capacités de traitement multicœur et de hautes fréquences, et peuvent facilement répondre aux exigences élevées du CS. 2. Carte graphique La carte graphique est l'un des facteurs importants dans les performances du jeu. Pour les jeux de tir tels que CS, les performances de la carte graphique affectent directement la clarté et la fluidité de l'écran de jeu. Il est recommandé de choisir les cartes graphiques de la série NVIDIA GeForce GTX ou de la série AMD Radeon RX. Elles ont d'excellentes capacités de traitement graphique et une fréquence d'images élevée, et peuvent offrir une meilleure expérience de jeu. 3. Puissance de la mémoire.

Qu'est-ce que l'identité en SQL ? Des exemples de code spécifiques sont nécessaires. En SQL, l'identité est un type de données spécial utilisé pour générer des nombres à incrémentation automatique. Il est souvent utilisé pour identifier de manière unique chaque ligne de données dans une table. La colonne Identité est souvent utilisée conjointement avec la colonne clé primaire pour garantir que chaque enregistrement possède un identifiant unique. Cet article détaillera comment utiliser Identity et quelques exemples de code pratiques. La manière de base d'utiliser Identity consiste à utiliser Identit lors de la création d'une table.

Glodon Software est une société de logiciels spécialisée dans le domaine de l'informatisation des bâtiments. Ses produits sont largement utilisés dans tous les aspects de la conception architecturale, de la construction et de l'exploitation. En raison des fonctions complexes et du grand volume de données du logiciel Glodon, celui-ci nécessite une configuration informatique élevée. Cet article détaillera les recommandations de configuration informatique de Glodon Software sous de nombreux aspects pour aider les lecteurs à choisir un processeur de configuration informatique approprié. Glodon Software nécessite une grande quantité de calcul et de traitement de données lors de l'exécution de la conception architecturale, de la simulation et d'autres opérations. pour le processeur sont plus élevés. Il est recommandé de choisir un processeur multicœur haute fréquence, tel que la série Intel i7 ou la série AMD Ryzen. Ces processeurs disposent d'une forte puissance de calcul et de capacités de traitement multithread, qui peuvent mieux répondre aux besoins du logiciel Glodon. Mémoire La mémoire affecte l'informatique

Séquence des lignes de connexion SPDIFOUT sur la carte mère. Récemment, j'ai rencontré un problème concernant la séquence de câblage des fils. J'ai vérifié en ligne. Certaines informations indiquent que 1, 2 et 4 correspondent à la sortie, au +5 V et à la masse tandis que d'autres informations indiquent que 1, 2 et 4 correspondent à la sortie, à la masse et au +5 V ; La meilleure façon est de consulter le manuel de votre carte mère. Si vous ne trouvez pas le manuel, vous pouvez utiliser un multimètre pour le mesurer. Trouvez d’abord la terre, puis vous pourrez déterminer l’ordre du reste du câblage. Comment connecter le câblage VDG de la carte mère Lors de la connexion du câblage VDG de la carte mère, vous devez brancher une extrémité du câble VGA dans l'interface VGA du moniteur et l'autre extrémité dans l'interface VGA de la carte graphique de l'ordinateur. Attention à ne pas le brancher sur le port VGA de la carte mère. Une fois connecté, vous pouvez

Une vulnérabilité de clé d'authentification à deux facteurs Yubico non corrigible a brisé la sécurité de la plupart des appareils Yubikey 5, Security Key et YubiHSM 2FA. La JavaCard Feitian A22 et d'autres appareils utilisant les TPM de la série Infineon SLB96xx sont également vulnérables.

Comment utiliser l'algorithme de recherche de hachage en C++ L'algorithme de recherche de hachage est une technologie de recherche et de stockage efficace. Il convertit les mots-clés en un index de longueur fixe via une fonction de hachage, puis utilise cet index dans la structure de données Search. En C++, nous pouvons implémenter des algorithmes de recherche de hachage en utilisant des conteneurs de hachage et des fonctions de hachage de la bibliothèque standard. Cet article explique comment utiliser l'algorithme de recherche de hachage en C++ et fournit des exemples de code spécifiques. Présentation des fichiers d'en-tête et des espaces de noms Tout d'abord, avant d'utiliser l'algorithme de recherche de hachage en C++
