Comprendre le « champ inconnu » dans les traces de pile de panique
Dans la poursuite du déchiffrement des traces de pile de panique, des éléments inconnus peuvent survenir. Un tel cas se produit dans le deuxième argument des appels de fonction dans une trace de pile de panique.
Considérons le code suivant pour illustrer ceci :
<code class="go">package main func F(a int) { panic(nil) } func main() { F(1) }</code>
Lors de son exécution, ce code génère :
panic: nil goroutine 1 [running]: main.F(0x1, 0x10436000) /tmp/sandbox090887108/main.go:4 +0x20 main.main() /tmp/sandbox090887108/main.go:8 +0x20
Le deuxième argument (0x10436000) dans main.F(0x1, 0x10436000) est ce qui nécessite des éclaircissements.
Décodage du champ inconnu
Le les valeurs affichées dans la trace de la pile sont les arguments de la fonction, mais elles ne correspondent pas directement aux valeurs transmises. Au lieu de cela, ils représentent les données brutes stockées dans des valeurs de la taille d'un pointeur.
Dans le cas donné, le terrain de jeu fonctionne sur une architecture 64 bits avec des pointeurs 32 bits (GOARCH=amd64p32). Dans une telle configuration, chaque valeur est stockée dans un mot de 64 bits, tandis que les pointeurs sont de 32 bits.
La fonction F(a int) prend un seul argument de type int. L'argument de trace de pile est stocké dans un mot de 64 bits. Étant donné que la taille du pointeur est de 32 bits, les 32 premiers bits contiennent le pointeur vers l'argument (0x1) et les 32 bits restants (0x10436000) sont inutilisés.
Autres exemples
Pour démontrer davantage ce concept, considérons un autre exemple :
<code class="go">func F(a uint8) { panic(nil) } func main() { F(1) }</code>
Ce code renvoie :
panic: nil goroutine 1 [running]: main.F(0x97301, 0x10436000)
Ici, l'argument a est de type uint8, qui occupe 8 morceaux. Les 8 premiers bits du mot de 64 bits contiennent la valeur d'un (1), tandis que les 56 bits restants (0x97300 et 0x10436000) sont inutilisés.
Valeurs de retour
En plus des arguments, les cadres de pile affichent également les valeurs de retour, qui sont allouées sur la pile. Par exemple, la signature de fonction :
<code class="go">func F(a int64) (int, int)</code>
sur les systèmes amd64, afficherait les arguments du cadre de pile comme :
main.F(0xa, 0x1054d60, 0xc420078058)
La première valeur représente l'argument, tandis que les deux valeurs suivantes représentent les valeurs de retour (int et int). Cependant, comme les valeurs de retour ne sont pas initialisées, elles ne fournissent pas beaucoup d'informations utiles.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!