Interrupción condicional de GDB en el parámetro de función

5 minutos de lectura

Quiero establecer un punto de interrupción en un parámetro de función si es mayor que un cierto valor. Código ficticio a continuación:

int main(void)
{
    uint64_t num = 123456;
    uint64_t x   = 847534;

    uint64_t other = (num*x) - (x/num);

    .... other stuff here (multithreaded stuff)

    calc(other);
}

void calc(uint64_t size)
{
    ...do some stuff with size
}

He intentado establecer un punto de interrupción por:

(gdb) b calc if size == 852479

pero no sabe qué tamaño es ya que es un parámetro que supongo. ¿Cómo me rompería si el parámetro es igual a un cierto número? NO es una opción interrumpir todas las llamadas a esta función porque se llama mil millones de veces en el entorno de subprocesos múltiples.

  • posible duplicado de ¿Cómo configuro un punto de interrupción condicional en gdb, cuando char* x apunta a una cadena cuyo valor es igual a “hola”?

    –Ricky Mutschlechner

    12 de noviembre de 2014 a las 16:46

  • ¿Ha intentado establecer el punto de interrupción en la primera línea del código de función?

    – Leeor

    12 de noviembre de 2014 a las 16:49

  • @RickyMutschlechner He mirado ese 1 y no es un duplicado porque en el caso de ese código x (la variable en cuestión) se supone que gdb está disponible para interrumpir porque es una variable declarada fuera de una función. En mi caso esta variable es el parámetro de una función. Puedo interrumpir con éxito las variables declaradas fuera de una función, pero no puedo interrumpir los parámetros a través de una interrupción condicional

    – Nick.D

    12 de noviembre de 2014 a las 16:51

  • @Nick.D, quise decir un descanso condicional

    – Leeor

    12 de noviembre de 2014 a las 17:02

  • Ese comando de punto de interrupción condicional funciona bien para mí (gcc 4.8.2, gdb 7.6.1-51.el7 en CentOS 7). Lo escribo justo después de iniciar gdb, sin ejecutar el objetivo. ¿En qué versiones de gcc/gdb y sistema operativo ve este problema?

    –Mark Plotnick

    12 de noviembre de 2014 a las 17:21


avatar de usuario de bph
bph

desde el gdb inmediato:

break "file.c":100 if (size=852479)

o

break "file.c":100 if (size>852479)

aquí asumo que desea el punto de interrupción condicional en la línea 100 y su archivo src es file.c

es decir, si desea interrumpir la línea que llama calcentonces esa sería la línea 100 – modifíquela según corresponda (también tendría que sustituir size con other en este caso)

si usaste una línea no. esa fue una de las primeras declaraciones en el calc entonces te quedarías con size

  • El problema que tengo es que gdb no conoce el “tamaño” antes de iniciar el programa, posiblemente porque es un nombre de parámetro y no una variable declarada fuera de una función. Una cosa que estoy intentando en este momento es establecer un punto de interrupción en la función, ejecutar el programa, ahora gdb es consciente de la variable de tamaño y ahora estoy haciendo una interrupción de condición en esa variable. Ejemplo a continuación (gdb) break file.c:calc (gdb) ejecute Breakpoint 1, calc (size=48) at file.c:67 in file.c (gdb) b if size = 852479 //Aquí es donde realmente está el tamaño reconocido por gdb (gdb) c

    – Nick.D

    12/11/2014 a las 17:00


  • gdb está al tanto de algo antes comenzando el programa? ‘otro’ es una variable que se declara e instancia antes de la llamada a calc; por lo tanto, no debería tener problemas para establecer un punto de interrupción condicional (¿tal vez todavía estoy entendiendo mal la pregunta aquí?)

    – bph

    12 de noviembre de 2014 a las 17:05


  • el tamaño debe tener un “==” en lugar de un “=”, debe ser este: romper “archivo.c”: 100 si (tamaño == 852479)

    – richmb

    11 de agosto de 2020 a las 14:06


Avatar de usuario de Grzegorz Szpetkowski
Grzegorz Szpetkowski

Asumiendo convenciones de llamadas x86-64 en la plataforma GNU/Linux podrías examinar %rdi (64 bits) regístrese directamente para verificar el primer parámetro de la función:

b calc if $rdi == 852479

Esto le permite interrumpir la función calc incluso si no tiene símbolos de depuración cargados (por lo tanto, no hay una lista de códigos, es decir, por list calc).

Tenga en cuenta que este método fallaría si la función está en línea con compilador optimizador.

Si break foo if arg1 == 14 no funciona por algún motivo (he encontrado algunas funciones/binarios en los que funciona y en los que no), puede intentar sustituirlo por commands.

commands le permite configurar algunos comandos gdb que se ejecutarán cada vez que se alcance un punto de interrupción. Para lograr el efecto deseado, un punto de interrupción condicional, puede hacer lo siguiente:

(gdb) b foo
Breakpoint 1 at 0x400633: file test.c, line 6.
(gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>if arg1 != 14
 >cont
 >end
>end

La ejecución se detendrá en el punto de interrupción solo si arg1 == 14.

El único inconveniente es que silent suprime el mensaje típico de “golpe de punto de interrupción”. Puedes eliminar silentpero luego gdb imprimirá el mensaje incluso si se omite el punto de interrupción commands secuencia de comandos, que no es deseable si el punto de interrupción se alcanza con mucha frecuencia.

Puede agregar alguna notificación personalizada dentro command guión, sin embargo.

¿Ha sido útil esta solución?