gdb imprime valores incorrectos al modificar argumentos

4 minutos de lectura

gdb imprime valores incorrectos al modificar argumentos
Teybéo

Sistema

Instalación nueva de Codeblocks 12.11 + paquete mingw.

  • ganar7 64
  • CCG 4.7.1
  • gdb 7.5

Código de ejemplo

Compilado con -g y sin optimización.

#include <stdio.h>

void foo(int a, int b);

int main() {

    foo(400, 42);

    return 0;
}

void foo(int a, int b) {

    a = a - 10;
    b = a + 1;

    printf("y2 %d\n", b);

}

Problema

Pongo un punto de interrupción en “void foo(int a, int b)” y busco el valor de b mientras paso por las 3 líneas. Ya sea con las funciones de depuración de Codeblocks o con la línea de comando gdb, el valor de b es 42 en lugar de ser 391. La salida de la consola es correcta, 391.

Comandos GDB

C:\DebugTest>"C:\Program Files (x86)\CodeBlocks\MinGW\bin\gdb.exe"
GNU gdb (GDB) 7.5
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:  
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file bin/Debug/DebugTest.exe
Reading symbols from C:\DebugTest\bin\Debug\DebugTest.exe...done.
(gdb) break foo
Breakpoint 1 at 0x401363: file C:\DebugTest\main.c, line 14.
(gdb) run
Starting program: C:\DebugTest\bin\Debug\DebugTest.exe
[New Thread 3596.0x658]

Breakpoint 1, foo (a=400, b=42) at C:\DebugTest\main.c:14
14          a = a - 10;
(gdb) print b
$1 = 42
(gdb) step
15          b = a + 1;
(gdb) print b
$2 = 42
(gdb) step
17          printf("y2 %d\n", b);
(gdb) print b
$3 = 42
(gdb)

Observaciones

  • Cuando el mismas operaciones están hechos sin una función, con a y b como variables locales dentro de main, la salida de depuración es correcto.
  • Cuando se compila con gcc 4.4.1, la salida de depuración es correcto.

¿Alguna idea de lo que podría estar mal? =)

  • Estoy usando Code Blocks 10.05 (GNU gdb 6.8), muestra b como 391.

    – SS Hegde

    6 de febrero de 2013 a las 16:46


  • ¿Estás imprimiendo el valor de b en gdb después de la asignación b = a + 1;?

    – ks1322

    6 de febrero de 2013 a las 16:49


  • a qué te refieres con step inside foo? break foo, run luego print b?

    – David Berra

    6 de febrero de 2013 a las 16:53


  • Sí, imprimo b tanto antes como después b = a + 1 línea. @DavideBerra puse un punto de interrupción en el void foo(int a, int b) { usando bloques de código, no uso el comando gdb excepto imprimir. Actualicé la publicación.

    – Teybéo

    06/02/2013 a las 19:40


  • Un conjunto completo de comandos gdb que muestren el problema podría confirmar o refutar algunas de esas sospechas de que podría ser solo un mal uso o un malentendido…

    – Aschepler

    6 de febrero de 2013 a las 19:47

Busqué en gcc bugzilla y encontré este informe de error:

Aunque el informe es sobre gcc 4.8 y estoy usando 4.7, probé la solución propuesta y ¡funciona!

Compilando con -fvar-tracking permite que GDB imprima el valor correcto para b después de la asignación.

  • Estoy usando gcc 4.8.2 y tuve el mismo problema (y -fvar-tracking arreglado). No hay problemas en otra máquina con gcc 5.3.1.

    – yano

    16 de noviembre de 2017 a las 16:33

gcc no genera información de depuración correctamente para valores que están en registros, ya sea valores que se han puesto en registros o valores que comienzan allí debido a las convenciones de llamadas. Este es un problema de larga data con gcc desde al menos 4.0, y hace que sea complicado depurar las cosas.

  • Acabo de intentar compilar el código. con gcc 4.4.1. Con el mismo gdb (7.5) y exactamente los mismos comandos, b tiene el correcto valor después de la asignación (391). ¿Tiene algún enlace para obtener más información sobre el problema que está describiendo?

    – Teybéo

    7 febrero 2013 a las 18:59


A veces, el optimizador es más inteligente que el depurador. Intente depurar el código no optimizado, o paso a paso el desensamblado y observe los registros HW directamente en lugar de recorrer las líneas fuente de C y observar la idea del depurador de cuáles son las variables.

  • El código no está optimizado y el registro muestra el valor correcto. Así que podría usar solo la vista de registro, pero tal vez esté de acuerdo en que no es la forma más conveniente ^^’

    – Teybéo

    6 de febrero de 2013 a las 16:48


  • Acordado. Desafortunadamente, a veces ese es el único juego en la ciudad.

    –Carl Norum

    6 de febrero de 2013 a las 16:59

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad