¿Es posible “saltar”/”saltar” en el depurador GDB?

4 minutos de lectura

avatar de usuario
nueva letra

¿Es posible saltar a alguna ubicación/dirección en el código/ejecutable durante la depuración en GDB?

Digamos que tengo algo similar a lo siguiente

int main()
{
  caller_f1() {  

   f1();  // breakpoint  
   f2() } // want to skip f2() and jump 

  caller_f2() { // jump to this this location ??       
   f1();  
   f2(); }  
}

  • @CiroSantilli六四事件法轮功纳米比亚威视 La pregunta tiene 4 años en este momento. Déjalo ir. Gracias !

    – letra nueva

    29 de julio de 2015 a las 19:08

Para reanudar la ejecución en una nueva dirección, utilice jump (forma corta: j):

jump LINENUM
jump *ADDRESS

El manual del BGF sugiere usar tbreak (punto de interrupción temporal) antes de saltar.

El lino puede ser cualquiera linespec expresión, como +1 para la siguiente línea.

Consulte la respuesta de @gospes sobre una pregunta relacionada para obtener una útil skip macro que hace exactamente eso.


Utilizando jump solo es “seguro” en código no optimizado (-O0), e incluso entonces solo dentro de la función actual. Eso solamente modifica el contador del programa; no cambia ningún otro registro o memoria.

Solamente gcc -O0 compila cada declaración fuente (¿o línea?) en un bloque independiente de instrucciones que carga valores variables de la memoria y almacena los resultados. Esto le permite modificar los valores de las variables con un depurador en cualquier punto de interrupción y hace jumpCambiar entre líneas en el código máquina funciona como saltar entre líneas en la fuente C.

Esto es parte de por qué -O0 hace un código tan lento: no solo el compilador no dedica tiempo a la optimización, sino que se requiere para hacer un código lento que derrama/recarga todo después de cada declaración para admitir la modificación asincrónica de variables e incluso el contador de programa. (La latencia de almacenamiento/recarga es de aproximadamente 5 ciclos en un x86 típico, por lo que 1 ciclo add lleva 6 ciclos en -O0 construye).

El manual de gcc sugiere usar -Og para el ciclo habitual de edición-compilación-depuración, pero incluso ese ligero nivel de optimización se romperá jump y modificación asíncrona de variables. Si no quiere hacer eso durante la depuración, es una buena opción, especialmente para proyectos donde -O0 corre tan lento que es un problema.


Para configurar el contador de programa / puntero de instrucción en una nueva dirección sin reanudartambién puedes usar esto:

set $pc = 0x4005a5

Copiar/pegar direcciones desde la ventana de desmontaje (layout asm / layout reg).

Esto es equivalente a tbreak + jump, pero no puede usar números de línea, solo direcciones de instrucciones. (Y no recibe una advertencia + solicitud de confirmación por saltar fuera de la función actual).

Entonces tú puedes stepi desde allí. $pc es un nombre gdb genérico para cualquier nombre que se le dé al registro en la arquitectura de destino. por ejemplo, RIP en x86-64. (Consulte también la parte inferior de la wiki de etiquetas x86 para obtener consejos de depuración de asm para gdb).

  • Buena explicación. ¿Hay algún artículo con ejemplos de lo que podría pasar al saltar en código optimizado? Como romper la pila. No me puedo imaginar que no se estrelle o haga cosas raras todo el tiempo, pero recuerdo que normalmente estaba bien en la práctica.

    – Trass3r

    2 sep 2020 a las 22:01

  • @ Trass3r: No que yo sepa; No he escrito uno y no he ido a buscar; Nunca he querido intentar hacer eso. Por lo general, las funciones hacen toda su asignación de pila por adelantado, al ingresar la función. La limpieza de la pila después de una llamada con argumentos de pila empujados a menudo es parte del mismo “bloque” que la llamada, por lo que saltar no lo romperá. (A menos que salte a instrucciones arbitrarias en lugar de a líneas fuente C).

    – Peter Cordes

    3 de septiembre de 2020 a las 0:34

  • Lo que es probable es romper alguna lógica como la propagación constante u otras invariantes. por ejemplo, no espere volver a ejecutar el i++ en un cuerpo de bucle para que funcione si también hay un ptr++ y están optimizados en uno. O saltar a un bucle muy probablemente no habría ejecutado la configuración del bucle y se habría roto por completo. Básicamente, cualquier cosa que involucre valores de registro es probable que se rompa.

    – Peter Cordes

    3 de septiembre de 2020 a las 0:35

avatar de usuario
hojusaram

Parece que hay un comando de salto que es exactamente lo que está buscando:

http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163

Enlace actualizado:
http://web.archive.org/web/20140101193811/http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163

¿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