Je me demande pourquoi évaluer la fonction ne fonctionne pas dans gdb? Dans mon fichier source inclus, lors du débogage dans gdb, ces exemples sont des évaluations erronées.
(gdb) p pow(3,2)
$10 = 1
(gdb) p pow(3,3)
$11 = 1
(gdb) p sqrt(9)
$12 = 0
Je suppose que le compilateur et l'éditeur de liens font de la magie avec ces fonctions particulières. Très susceptible d’augmenter les performances.
Si vous avez absolument besoin que pow()
soit disponible dans gdb, vous pouvez créer votre propre fonction de wrapper:
double mypow(double a, double b)
{
return pow(a,b);
}
Peut-être aussi l'envelopper dans un #ifdef DEBUG
ou quelque chose pour ne pas encombrer le binaire final.
En passant, vous remarquerez que d’autres fonctions de la bibliothèque peuvent être appelées (et leur valeur de retour imprimée), par exemple:
(gdb) print printf("hello world")
$4 = 11
La syntaxe pour appeler une fonction dans gdb est
call pow(3,2)
Type
help call
sur l'invite gdb pour plus d'informations.
Vous devez dire à gdb qu'il trouvera la valeur de retour dans les registres à virgule flottante, et non les registres normaux, en plus de donner les types appropriés aux paramètres.
C'est à dire.:
(gdb) p ((double (*) ()) pow) (2., 2.)
1 $ = 4
En fait, du moins dans mon implémentation LINCC de gcc, de nombreuses fonctions mathématiques sont remplacées par des variantes spécifiques aux types de leurs arguments via des substitutions fantaisies tirées de math.h et de bits/mathcalls.h (inclus dans math.h ). En conséquence, des fonctions telles que pow et exp sont appelées à la place par __pow
ou *__GI___exp
(vos résultats peuvent varier en fonction des types d'arguments et peut-être de la version particulière).
Pour identifier la fonction qui est liée à mon code, je mets une rupture à la ligne où cette fonction est appelée, par exemple. avoir une ligne dans mon code avec b=exp(c);
. Puis je cours dans gdb jusqu’à ce point d’arrêt, puis utilise la commande "step" pour entrer l’appel à partir de cette ligne. Ensuite, je peux utiliser la commande "where" pour identifier le nom de la routine appelée. Dans mon cas, c'était *__GI___exp
.
Il existe probablement des moyens plus intelligents d’obtenir ces informations. Cependant, je n’étais pas en mesure de trouver le bon nom en exécutant uniquement le préprocesseur (option -E) ou en consultant le code d’assemblage généré (-s).
pow est défini comme une macro, pas une fonction. L’appel dans gdb ne peut appeler que des fonctions de votre programme ou de la bibliothèque partagée. Donc, l'appel à pow dans gdb devrait échouer.
(gdb) p pow(3,2)
No symbol "pow" in current context.
voici le code binaire généré par gcc de l'appelant source pow (int, int):
(gdb) list
1 int main() {
2 int a=pow(3,2);
3 printf("hello:%d\n", a);
4 }
(gdb) x/16i main
0x4004f4 <main>: Push %rbp
0x4004f5 <main+1>: mov %rsp,%rbp
0x4004f8 <main+4>: sub $0x10,%rsp
0x4004fc <main+8>: movl $0x9,-0x4(%rbp)
=> 0x400503 <main+15>: mov -0x4(%rbp),%eax
0x400506 <main+18>: mov %eax,%esi
0x400508 <main+20>: mov $0x40060c,%edi
0x40050d <main+25>: mov $0x0,%eax
0x400512 <main+30>: callq 0x4003f0 <printf@plt>
0x400517 <main+35>: leaveq
0x400518 <main+36>: retq
0x400519: nop
0x40051a: nop
0x40051b: nop
0x40051c: nop
0x40051d: nop
voici le code binaire généré par gcc de la source appelant pow (float, float):
(gdb) list
1 int main() {
2 double a=pow(0.3, 0.2);
3 printf("hello:%f\n", a);
4 }
(gdb) x/16i main
0x4004f4 <main>: Push %rbp
0x4004f5 <main+1>: mov %rsp,%rbp
0x4004f8 <main+4>: sub $0x10,%rsp
0x4004fc <main+8>: movabs $0x3fe926eff16629a5,%rax
0x400506 <main+18>: mov %rax,-0x8(%rbp)
0x40050a <main+22>: movsd -0x8(%rbp),%xmm0
0x40050f <main+27>: mov $0x40060c,%edi
0x400514 <main+32>: mov $0x1,%eax
0x400519 <main+37>: callq 0x4003f0 <printf@plt>
0x40051e <main+42>: leaveq
0x40051f <main+43>: retq
NAME
pow, powf, powl - power functions
SYNOPSIS
#include <math.h>
double pow(double x, double y);
Vous ne devriez pas passer un int à la place d'un double
call pow( 3. , 2. )
De plus, passer un seul argument ne suffit pas, vous avez besoin de deux arguments exactement comme la fonction
wrong: call pow ( 3. )