2009-08-30 17 views
19

Me pregunto por qué evaluar la función no funciona en gdb? En mi archivo fuente que incluyo, al depurar en gdb, estos ejemplos son evaluaciones incorrectas.¿Cómo evaluar las funciones en GDB?

(gdb) p pow(3,2) 

$10 = 1 

(gdb) p pow(3,3) 

$11 = 1 

(gdb) p sqrt(9) 

$12 = 0 

Respuesta

14

Supongo que el compilador y el enlazador hacen algo de magia con esas funciones particulares. Lo más probable es que aumente el rendimiento.

Si es absolutamente necesario pow() que esté disponible en el BGF continuación, puede crear una función propia:

double mypow(double a, double b) 
{ 
    return pow(a,b); 
} 

Tal vez también se envuelven en una #ifdef DEBUG o algo para no estorbar el binario final.

Por cierto, se dará cuenta de que otras funciones de la biblioteca se pueden llamar (y su valor de retorno impresos), por ejemplo:

(gdb) print printf("hello world") 
$4 = 11 
+0

La respuesta correcta se da a continuación por anon – mattypiper

15

La sintaxis para llamar a una función en GDB es

call pow(3,2) 

Tipo

help call 

en el símbolo del BGF para más información.

+0

Gracias! Pero el llamado es sigue sin funcionar correctamente (BGF) llamada sqrt (9) $ 14 = 0 (BGF) pow llamada (3,3) $ 15 = 1 – Tim

+1

de impresión también llamar a las funciones. De hecho, creo que la única diferencia es que la llamada no saturará la salida al llamar a las funciones nulas –

0
NAME 
    pow, powf, powl - power functions 

SYNOPSIS 
    #include <math.h> 

    double pow(double x, double y); 

No debe pasar un int en el lugar de un doble

call pow(3. , 2.) 

También, pasar un solo argumento no es suficiente decir, que necesita dos argumentos al igual que la función espera

wrong: call pow (3.) 
+1

en realidad, al pasar las entradas funcionan bien. no estoy seguro de si es solo una coincidencia, pero al invocar mypow (ver mi respuesta) con números enteros se obtiene el resultado correcto. No obtengo ningún resultado de gdb cuando llamo pow (2.0,2.0), pero lo hago cuando llamo a mypow() con cualquier número –

4

En realidad, al menos en mi aplicació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 sofisticadas introducidas por math.h y bits/mathcalls.h (incluidas desde math.h). Como consecuencia, las funciones como pow y exp se llaman en su lugar como __pow o *__GI___exp (los resultados pueden variar según los tipos de argumentos y quizás la versión particular).

Para identificar exactamente qué función está vinculada a mi código, puse un salto en una línea donde solo se llama a esa función, p. tener una línea en mi código con b=exp(c);. Luego corro en gdb hasta ese punto de ruptura y luego uso el comando "paso" para ingresar la llamada desde esa línea. Entonces puedo usar el comando "donde" para identificar el nombre de la rutina llamada. En mi caso, eso fue *__GI___exp.

Probablemente haya 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 ensamblado generado (-s).

+2

Sé que esto es antiguo, pero si alguien viene a buscarlo, aquí va: Para mí funcionó hacer 'p pow' que me dio:' $ 28 = {} 0x7ffff77ffbd0 <__pow> ' – falstro

14

Necesita 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 ((doble (*)()) pow) (2., 2.)

$ 1 = 4

+0

Es extraño, recibo un valor de' $ 1 = 2' – daj

2

pow se define como una macro, no una función. La llamada en gdb solo puede llamar funciones en su programa o en una biblioteca compartida. Entonces, la llamada a pow en gdb debería fallar.

(gdb) p pow(3,2) 
    No symbol "pow" in current context. 

aquí es el gcc generada código binario de la fuente llamando 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 <[email protected]> 
    0x400517 <main+35>: leaveq 
    0x400518 <main+36>: retq 
    0x400519: nop 
    0x40051a: nop 
    0x40051b: nop 
    0x40051c: nop 
    0x40051d: nop 

aquí es el gcc genera el código binario de la fuente llamando 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 <[email protected]> 
    0x40051e <main+42>: leaveq 
    0x40051f <main+43>: retq 
Cuestiones relacionadas