2011-03-17 18 views

Respuesta

21

El n El nombre que describe aparece con bastante frecuencia, generalmente en el contexto de some_utility_fn que se llama mucho, pero solo le interesa la llamada que proviene del some_other_fn.

Es probable que pueda crear una secuencia de comandos de toda esta interacción utilizando la nueva compatibilidad incorporada de Python en GDB desde la troncal de CVS.

Sin Python, que están limitados en lo que puede hacer, pero la técnica habitual es tener un punto de interrupción discapacitados en a() y activar desde un comando, unido a un punto de interrupción en b().

Aquí se muestra un ejemplo:

int a(int x) 
{ 
    return x + 1; 
} 

int b() 
{ 
    return a(1); 
} 

int call_a_lots() 
{ 
    int i, sum = 0; 
    for (i = 0; i < 100; i++) 
    sum += a(i); 
} 

int main() 
{ 
    call_a_lots(); 
    return b(); 
} 

gcc -g t.c 
gdb -q ./a.out 
Reading symbols from /tmp/a.out...done. 
(gdb) break a 
Breakpoint 1 at 0x4004cb: file t.c, line 3. 
(gdb) disable 1 
(gdb) break b 
Breakpoint 2 at 0x4004d7: file t.c, line 8. 
(gdb) command 2 
>silent 
>enable 1 
>continue 
>end 
(gdb) run 

Breakpoint 1, a (x=1) at t.c:3 
3  return x + 1; 
(gdb) bt 
#0 a (x=1) at t.c:3 
#1 0x00000000004004e1 in b() at t.c:8 
#2 0x000000000040052c in main() at t.c:21 
(gdb) q 

Voila: hemos dejado en a() llamado desde b(), haciendo caso omiso de 100 llamadas anteriores a a().

+1

¿Qué hace el 'comando 2'? –

+3

@NathanFellman 'command 2' adjunta comandos al breakpoint 2 –

+0

¿Se puede automatizar sin Python? http://stackoverflow.com/questions/41397560/how-to-pass-cli-arguments-to-a-commands-inside-a-define-in-gdb –

4

no estoy seguro de cómo hacerlo por gdb.
Pero se puede declarar la variable global como:

bool call_a = false; 

y cuando b llamar a un

call_a = true; 
a(); 

y establecer call_a a falso cuando otra función llamada A() o después de su punto de interrupción

entonces utilizar la condición punto de ruptura

break [line-number] if call_a == true 
7

he probado esto en GDB 7.6 que ya está disponible, pero no funciona en gdb 7.2 y probablemente en GDB 7.1:

Así que esto es main.cpp:

int a() 
{ 
    int p = 0; 
    p = p +1; 
    return p; 
} 

int b() 
{ 
    return a(); 
} 

int c() 
{ 
    return a(); 
} 

int main() 
{ 
    c(); 
    b(); 
    a(); 
    return 0; 
} 

Entonces g ++ - g main.cpp

ésta es my_check.py:

class MyBreakpoint (gdb.Breakpoint): 
    def stop (self): 
     if gdb.selected_frame().older().name()=="b": 
      gdb.execute("bt") 
      return True 
     else: 
      return False 

MyBreakpoint("a") 

Y así es como funciona:

4>gdb -q -x my_check.py ./a.out 
Reading symbols from /home/a.out...done. 
Breakpoint 1 at 0x400540: file main.cpp, line 3. 
(gdb) r 
Starting program: /home/a.out 
#0 a() at main.cpp:3 
#1 0x0000000000400559 in b() at main.cpp:10 
#2 0x0000000000400574 in main() at main.cpp:21 

Breakpoint 1, a() at main.cpp:3 
3   int p = 0; 
(gdb) c 
Continuing. 
[Inferior 1 (process 16739) exited normally] 
(gdb) quit 
+0

Deberíamos hacer que la función de Python tome 'a' y' b' como argumentos CLI. –

+0

Comenzó un boceto en: https://github.com/cirosantilli/dotfiles/blob/15addf77a231b577ee419923c3236ed7c408f8eb/home/.gdbinit.py#L81 pero se puso flojo. Tenga en cuenta que los puntos de interrupción temporales son posibles en Python puro con 'gdb.Breakpoint (temporary = True)' y que sería bueno subir la cadena '.older()' de la pila hasta el final. –

0

fácil para el brazo es:

Establecer el punto de interrupción en la función que le interesa.

break a 

Adjunte un comando gdb a ese punto de interrupción.

command 1 
up 1 
if $lr == 0x12345678 
    echo match \n 
    down 1 
else 
    echo no match \n 
    echo $lr \n 
    down 1 
    cont 
end 
end 

Cuando cada vez que llegue a la función a(), el comando hace estallar temporalmente marco de una pila y así actualizar el registro de enlace. El valor del registro del enlace de las personas que llaman puede continuarse cuando la persona que llama no es la ruta de ejecución que necesita.

disfrutar.

4

Una solución más simple que las secuencias de comandos de Python es usar un temporary breakpoint.

Parece que este:

b ParentFunction 
command 1 
    tb FunctionImInterestedIn 
    c 
end 

Cada vez que se rompe en ParentFunction, deberá definir un punto de interrupción de una sola vez de la función que está realmente interesado en, a continuación, seguir ejecutando (presumiblemente hasta llegar ese punto de interrupción).

Puesto que usted va a romper exactamente una vez en FunctionImInterestedIn, esto no funcionará si FunctionImInterestedIn se llama varias veces en el contexto de ParentFunction y que desea romper en cada invocación.

+0

Parece que tu última oración fue cortada. ¿Qué quisiste escribir? –

+0

¿Se puede automatizar esto sin Python? http://stackoverflow.com/questions/41397560/how-to-pass-cli-arguments-to-a-commands-inside-a-define-in-gdb –

0

gdb puede manejar esto directamente sin necesidad de Python. Simplemente haz esto:

b a if $_caller_is("b") 
Cuestiones relacionadas