variable una online khan graficas grafica funciones funcion expresiones evaluar evaluacion evalua diferencial con como calculo academy function gdb evaluation

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. )