¿Alguien puede explicar este comportamiento de gdb?
900         memset(&new_ckpt_info,'\0',sizeof(CKPT_INFO));
(gdb)
**903         prev_offset   = cp_node->offset;**
(gdb)
**905         m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_** HDR),i_offset);
(gdb)
**903         prev_offset   = cp_node->offset;**
(gdb)
**905         m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_ HDR),i_offset);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
913         found = cpnd_find_exact_ckptinfo(cb , &ckpt_info , bitmap_offset , &offset , &prev_offset);
(gdb)
916         if(!found)
(gdb) p found
$1 = <value optimized out>
(gdb) set found=0
Left operand of assignment is not an lvalue.
¿Por qué después de ejecutar la línea 903 vuelve a ejecutar lo mismo para 905 908 910?
Otra cosa es que foundes una boolvariable de tipo, entonces, ¿por qué se muestra value optimized out? No puedo establecer el valor de foundtambién.
Esto parece ser una optimización del compilador (en este caso es -O2); ¿Cómo puedo establecer el valor de found?

Respuestas:
Para depurar código optimizado, aprenda lenguaje ensamblador / máquina.
Utilice el modo GDB TUI. Mi copia de GDB lo habilita cuando escribo el signo menos y Enter. Luego escriba Cx 2 (es decir, mantenga presionado Control y presione X, suelte ambos y luego presione 2). Eso lo pondrá en fuente dividida y pantalla de desmontaje. Luego use
stepiynextipara mover una instrucción de máquina a la vez. Utilice Cx o para cambiar entre las ventanas TUI.Descargue un PDF sobre el lenguaje de máquina de su CPU y las convenciones de llamadas a funciones. Aprenderá rápidamente a reconocer lo que se está haciendo con los argumentos de función y los valores de retorno.
Puede mostrar el valor de un registro utilizando un comando GDB como
p $eaxfuente
Vuelva a compilar sin optimizaciones (-O0 en gcc).
fuente
Declarar encontrado como "volátil". Esto debería decirle al compilador que NO lo optimice.
volatile int found = 0;fuente
El compilador comenzará a hacer cosas muy inteligentes con las optimizaciones activadas. El depurador mostrará el código saltando mucho hacia adelante y hacia atrás debido a la forma optimizada en que se almacenan las variables en los registros. Esta es probablemente la razón por la que no puede establecer su variable (o en algunos casos ver su valor), ya que se ha distribuido inteligentemente entre registros para la velocidad, en lugar de tener una ubicación de memoria directa a la que el depurador pueda acceder.
¿Compilar sin optimizaciones?
fuente
Por lo general, los valores booleanos que se utilizan en las ramas inmediatamente después de que se calculan así nunca se almacenan en las variables. En cambio, el compilador simplemente se ramifica directamente de los códigos de condición que se establecieron en la comparación anterior. Por ejemplo,
int a = SomeFunction(); bool result = --a >= 0; // use subtraction as example computation if ( result ) { foo(); } else { bar(); } return;Por lo general, se compila en algo como:
call .SomeFunction ; calls to SomeFunction(), which stores its return value in eax sub eax, 1 ; subtract 1 from eax and store in eax, set S (sign) flag if result is negative jl ELSEBLOCK ; GOTO label "ELSEBLOCK" if S flag is set call .foo ; this is the "if" black, call foo() j FINISH ; GOTO FINISH; skip over the "else" block ELSEBLOCK: ; label this location to the assembler call .bar FINISH: ; both paths end up here ret ; returnObserve cómo el "bool" nunca se almacena en ningún lugar.
fuente
Prácticamente no se puede establecer el valor de encontrado. La depuración de programas optimizados rara vez vale la pena, el compilador puede reorganizar el código de manera que no corresponda de ninguna manera al código fuente (aparte de producir el mismo resultado), lo que confunde a los depuradores sin fin.
fuente
Al depurar programas optimizados (que puede ser necesario si el error no aparece en las compilaciones de depuración), a menudo debe comprender el compilador de ensamblado generado.
En su caso particular, el valor de retorno de
cpnd_find_exact_ckptinfose almacenará en el registro que se utiliza en su plataforma para los valores de retorno. Síix86, eso sería%eax. Activadox86_64:,%raxetc. Es posible que deba buscar en Google '[su procesador] procedimiento que llama a la convención' si no es ninguno de los anteriores.Puede examinar ese registro
GDBy configurarlo. Por ejemplo, enix86:(gdb) p $eax (gdb) set $eax = 0fuente
Estoy usando QtCreator con gdb.
Añadiendo
Funciona bien para mi
fuente