function - una - ¿Cómo evaluar funciones en GDB?
evaluar funciones online (6)
Me pregunto por qué la función de evaluación no funciona en gdb? En mi archivo de origen incluyo, al depurar en gdb, estos ejemplos son evaluaciones incorrectas.
(gdb) p pow(3,2)
$10 = 1
(gdb) p pow(3,3)
$11 = 1
(gdb) p sqrt(9)
$12 = 0
Debe decirle a gdb que encontrará el valor de retorno en los registros de punto flotante, no los normales, además de dar a los parámetros los tipos correctos.
Es decir:
(gdb) p ((double (*) ()) pow) (2., 2.)
$ 1 = 4
En realidad, al menos en mi implementación LINUX de gcc, muchas de las funciones matemáticas se reemplazan con variantes específicas de los tipos de sus argumentos a través de algunas sustituciones extravagantes introducidas por math.hy bit / mathcalls.h (incluidas desde math.h ). Como consecuencia, las funciones como pow y exp se llaman en su lugar como __pow
o *__GI___exp
(sus resultados pueden variar según los tipos de argumentos y quizás la versión en particular).
Para identificar qué es exactamente la función que está vinculada a mi código, coloco un salto en una línea donde se llama a esa función, por ejemplo, tengo una línea en mi código con b=exp(c);
. Luego corro en gdb hasta ese punto de interrupción y luego uso el comando "step" para ingresar la llamada desde esa línea. Luego puedo usar el comando "dónde" para identificar el nombre de la rutina llamada. En mi caso eso fue *__GI___exp
.
Probablemente hay formas más inteligentes de obtener esta información, sin embargo, no pude encontrar el nombre correcto simplemente ejecutando el preprocesador solo (la opción -E) o mirando el código de ensamblado generado (-s).
La sintaxis para llamar a una función en gdb es
call pow(3,2)
Tipo
help call
en el gdb prompt para más información.
Mi conjetura es que el compilador y el enlazador hacen algo de magia con esas funciones particulares. Es muy probable que aumente el rendimiento.
Si necesitas absolutamente que pow()
esté disponible en gdb, puedes crear tu propia función de envoltorio:
double mypow(double a, double b)
{
return pow(a,b);
}
Tal vez también envuélvalo en un #ifdef DEBUG
o algo para no desordenar el binario final.
Por cierto, notará que se pueden llamar otras funciones de la biblioteca (y se imprimió su valor de retorno), por ejemplo:
(gdb) print printf("hello world")
$4 = 11
pow se define como una macro, no una función. La llamada en gdb solo puede llamar a funciones en su programa o en una biblioteca compartida. Por lo tanto, la llamada a pow en gdb debería fallar.
(gdb) p pow(3,2)
No symbol "pow" in current context.
Aquí está el código binario generado por gcc de fuente que llama 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
Aquí está el código binario generado por gcc de fuente que llama 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);
No deberías pasar un int en lugar de un doble.
call pow( 3. , 2. )
Además, pasar un solo argumento no es suficiente, necesita dos argumentos al igual que la función espera
wrong: call pow ( 3. )