GDB: Automático 'Siguiente ing?

Rápido esta vez.

Es posible (que no sea presionar enter para siempre) para gdb continuamente next a través de un programa línea por línea para encontrar donde un error que está sucediendo?

Edit: continue no es lo que yo quisiera; me gustaría ver que efectivamente la completa ejecución del programa, línea por línea, como los que se obtendrían de nexting más y más.

  • Respuesta seleccionada
    Michael Burr
    28 de abril de 2011

    He aquí algo que es un hack que estoy un poco avergonzado de publicar. Pero si usted necesita sólo un one-off, que puede hacer lo suficientemente bien como para permitirle obtener la información que desea. Realmente debe haber una mejor manera.

    Se puede definir un estúpido poco gdb script que ejecuta el step o next comando de un determinado número de veces:

    # file: step_mult.gdb
    
    define step_mult
        set $step_mult_max = 1000
        if $argc >= 1
            set $step_mult_max = $arg0
        end
    
        set $step_mult_count = 0
        while ($step_mult_count < $step_mult_max)
            set $step_mult_count = $step_mult_count + 1
            printf "step #%d\n", $step_mult_count
            step
        end
    end
    

    (He utilizado el paso en lugar de next por ninguna buena razón en particular; se cambie a lo que usted necesita.)

    A continuación, puede ejecutar el comando (con opcional de contar), y se va a mostrar cada uno de los step o next muy bien.

    Aquí se muestra un ejemplo de programa que va a bloquearse cuando intenta desreferenciar un puntero NULL:

    #include<stdio.h>
    
    int x[] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8,9, 10 
    };
    
    int* p[11];
    
    int main()
    {
        int i;
    
        for (i = 0; i < 11; ++i) {
            p[i] = &x[i];
        }
    
        p[5] = 0;
    
        for (i = 0; i < 11; ++i) {
            printf( "*p[%d] == %d\n", i, *p[i]);
        }
    
        return 0;
    }
    

    He aquí un gdb de la sesión (en Windows) la depuración que se programa y el uso de la step_mult script:

    C:\temp>gdb test.exe
    GNU gdb (GDB) 7.2
    ...
    Reading symbols from C:\temp/test.exe...done.
    
    (gdb) source c:/temp/step_mult.gdb
    (gdb) start
    
    Temporary breakpoint 1 at 0x401385: file C:\temp\test.c, line 23.
    Starting program: C:\temp/test.exe
    [New Thread 5396.0x1638]
    
    Temporary breakpoint 1, main () at C:\temp\test.c:23
    23          for (i = 0; i < 11; ++i) {
    
    (gdb) step_mult 70
    
    step #1
    24              p[i] = &x[i];
    step #2
    23          for (i = 0; i < 11; ++i) {
    step #3
    24              p[i] = &x[i];
    step #4
    23          for (i = 0; i < 11; ++i) {
    step #5
    24              p[i] = &x[i];
    step #6
    23          for (i = 0; i < 11; ++i) {
    step #7
    24              p[i] = &x[i];
    step #8
    23          for (i = 0; i < 11; ++i) {
    step #9
    24              p[i] = &x[i];
    step #10
    23          for (i = 0; i < 11; ++i) {
    step #11
    24              p[i] = &x[i];
    step #12
    23          for (i = 0; i < 11; ++i) {
    step #13
    24              p[i] = &x[i];
    step #14
    23          for (i = 0; i < 11; ++i) {
    step #15
    24              p[i] = &x[i];
    step #16
    23          for (i = 0; i < 11; ++i) {
    step #17
    24              p[i] = &x[i];
    step #18
    23          for (i = 0; i < 11; ++i) {
    step #19
    24              p[i] = &x[i];
    step #20
    23          for (i = 0; i < 11; ++i) {
    step #21
    24              p[i] = &x[i];
    step #22
    23          for (i = 0; i < 11; ++i) {
    step #23
    27          p[5] = 0;
    step #24
    29          for (i = 0; i < 11; ++i) {
    step #25
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #26
    *p[0] == 0
    29          for (i = 0; i < 11; ++i) {
    step #27
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #28
    *p[1] == 1
    29          for (i = 0; i < 11; ++i) {
    step #29
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #30
    *p[2] == 2
    29          for (i = 0; i < 11; ++i) {
    step #31
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #32
    *p[3] == 3
    29          for (i = 0; i < 11; ++i) {
    step #33
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #34
    *p[4] == 4
    29          for (i = 0; i < 11; ++i) {
    step #35
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #36
    
    Program received signal SIGSEGV, Segmentation fault.
    0x004013d2 in main () at C:\temp\test.c:30
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #37
    
    Program received signal SIGSEGV, Segmentation fault.
    0x004013d2 in main () at C:\temp\test.c:30
    30              printf( "*p[%d] == %d\n", i, *p[i]);
    step #38
    
    Program exited with code 030000000005.
    step #39
    The program is not being run.
    (gdb)
    

    Lamentablemente, desde la secuencia de comandos no se detiene cuando la violación de segmento que pasa, gdb decide simplemente detener la depuración del programa, así que usted no puede hacer más útiles las consultas. Pero el registro todavía puede ser útil.

    Estoy seguro de que hay numerosas maneras en que uno puede hacer el guión más inteligente. Por desgracia, no tengo idea de cómo hacer eso, y el nivel de usuario documentación para el GDB no parecen ser demasiado útil para los detalles. La mejor manera sería si el script se podría detectar la violación de segmento o de la señal que había pasado y acaba de dejar, a continuación, en lugar de depender de arbitraria en el recuento. Me imagino que el gdb/MI interfaz, o probablemente incluso las secuencias de comandos de Python interfaz puede tener un buen mecanismo, pero no sé nada acerca de aquellos.

    Después de su primera ejecución, se podría utilizar el recuento de la muestra (37 en mi ejemplo) y reinicie el programa y le dan un número que está justo por debajo de donde se estrelló antes y tomar el control de forma manual.

    Como he dicho, no es especialmente bonito, pero podría llegar hasta allí.

4 Respuestas