Cómo evaluar las funciones en GDB?

Me pregunto ¿por qué evaluar la función no funciona en gdb? En mi archivo de origen incluyo, cuando la depuración en gdb, estos ejemplos son valoraciones equivocadas.

(gdb) p pow(3,2)

$10 = 1

(gdb) p pow(3,3)

$11 = 1

(gdb) p sqrt(9)

$12 = 0
InformationsquelleAutor Tim | 2009-08-30

6 Kommentare

  1. 19

    Mi conjetura es que el compilador y el enlazador hace un poco de magia con esas funciones. Más probabilidades de aumentar el rendimiento.

    Si es absolutamente necesario pow() a estar disponible en gdb, a continuación, puede crear su propia función de contenedor:

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

    Tal vez también envuelven en un #ifdef DEBUG o algo para que no sature el final binario.

    Por CIERTO, te darás cuenta de que otras funciones de la biblioteca puede ser llamado (y su valor de retorno impreso), por ejemplo:

    (gdb) print printf("hello world")
    $4 = 11
    
    • La respuesta correcta es la siguiente por anon
  2. 21

    Necesita decirle a gdb que se encontrará el valor de retorno en los registros de punto flotante, no a las normales, además de dar los parámetros de los tipos.

    I. e.:

    (gdb) p ((double(*)())pow)(2.,2.)

    $1 = 4

    • Que extraño, yo obtener un valor de $1 = 2
  3. 18

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

    call pow(3,2)
    

    Tipo

    help call
    

    en el gdb símbolo del sistema para obtener más información.

    • Gracias! Pero es que todavía no está funcionando correctamente (gdb) llamada sqrt(9) $14 = 0 (gdb) llamada pow(3,3) $15 = 1
    • imprimir también las funciones de llamada. De hecho, creo que la única diferencia es que la llamada no saturar la salida al llamar a anular las funciones de
  4. 4

    Realidad, al menos en mi LINUX implementación de gcc, muchas de las funciones matemáticas son reemplazados con variantes específicas de los tipos de sus argumentos a través de algunas de fantasía sustituciones tirados en las matemáticas.h and bits/mathcalls.h (incluido dentro de las matemáticas.h). Como consecuencia, las funciones como prisionero de guerra y exp se llama, en cambio, como __pow o *__GI___exp (los resultados pueden variar dependiendo de los tipos de los argumentos y tal vez la versión en particular).

    Para identificar qué es exactamente la función que está vinculada a mi código me puse un descanso en una línea donde el que se llama a la función, por ejemplo, tiene una línea en mi código con b=exp(c);. Entonces me quedo en gdb hasta que el punto de ruptura y, a continuación, utilizar el «paso» de comandos para entrar en la llamada de la línea. Entonces puedo usar el «dónde» de comandos para identificar el nombre de la rutina. En mi caso que fue *__GI___exp.

    Hay probablemente más inteligente formas de obtener esta información, sin embargo, yo no era capaz de encontrar el nombre correcto ejecutando el preprocesador solo (la opción-E) o en el código ensamblador generado (-s).

    • Sé que esto es viejo, pero si alguien viene buscando, aquí va: a mí me ha funcionado hacer p pow que me dio: $28 = {<text variable, no debug info>} 0x7ffff77ffbd0 <__pow>
  5. 1

    pow se define como una macro , no una función.
    La llamada en gdb sólo puede llamar a funciones en el programa o en la biblioteca compartida. Así, la llamada a pow en gdb debe fallado.

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

    aquí es el gcc binario generado el código de fuente de llamar 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 binario generado el código de fuente de llamar 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
    
    • El resultado de pow se ha reducido a un valor constante en estos ejemplos ya que el compilador sabe que los dos argumentos son constantes en tiempo de compilación. No es terriblemente útil como una respuesta.
  6. 0
    NAME
       pow, powf, powl - power functions
    
    SYNOPSIS
       #include <math.h>
    
       double pow(double x, double y);
    

    Que no debería pasar un int en el lugar de un doble

     call pow( 3. , 2. )
    

    También, pasando de un solo argumento no es suficiente, necesita dos argumentos como que la función espera

     wrong: call pow ( 3. )
    
    • en realidad, pasando enteros funcionar bien. no estoy seguro si es sólo una coincidencia, pero las llamadas a mypow (ver mi respuesta) con números enteros producir el resultado correcto. No tengo salida de gdb cuando se llama a pow(2.0,2.0), pero yo al llamar mypow() con cualquier número

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea