2010-12-01 26 views
80

¿Cómo puedo establecer un punto de interrupción en C o código de C++ programáticamente que funcionará para gdb en Linux?Establecer el punto de interrupción en el código C o C++ programáticamente para gdb en Linux

es decir .:

int main(int argc, char** argv) 
{ 
    /* set breakpoint here! */ 
    int a = 3; 
    a++; /* In gdb> print a; expect result to be 3 */ 
    return 0; 
} 
+7

mucho una nota lateral (lo siento que pequeñez), pero si usted está preocupado acerca de la portabilidad entonces usted está probablemente también preocupado corrección, de ahí 'int main' en lugar de' void main'. –

+0

@Stuart - Reparado. Debería haber hecho eso hace un tiempo. –

+3

@ J.Polfer: ¡el 'return 0' no es necesario, sin embargo, y es solo ruido! –

Respuesta

77

Una forma es para señalar una interrupción:

#include <csignal> 

// Generate an interrupt 
std::raise(SIGINT); 

En C:

#include <signal.h> 
raise(SIGINT); 

ACTUALIZACIÓN: MSDN states que Windows no apoya realmente SIGINT, por lo que si la portabilidad es una preocupación, probablemente sea mejor que utilices SIGABRT.

+0

Esto es más portátil, ¿verdad? –

+0

Sí, esto debería funcionar en todos los sistemas operativos/compiladores/depuradores. –

+1

No conozco otros depuradores, pero gdb es bastante flexible sobre [manejo de señal] (http://www.delorie.com/gnu/docs/gdb/gdb_39.html). – Cascabel

18

Al observar here, he encontrado la siguiente manera:

void main(int argc, char** argv) 
{ 
    asm("int $3"); 
    int a = 3; 
    a++; // In gdb> print a; expect result to be 3 
} 

Esto parece un toque hacker para mí. Y creo que esto solo funciona en la arquitectura x86.

+3

Y solo con compiladores compatibles con la sintaxis de ensamblaje de AT & T. En particular, el compilador de Microsoft ('cl.exe') no admite esta sintaxis, pero usa una sintaxis diferente. –

+0

la pregunta era sobre Linux, así que supongo que podemos suponer que la sintaxis de gcc funcionará para x86. –

+0

BTW - He intentado lo anterior en mi máquina x86 y funcionó. Tenía curiosidad si había una mejor manera de hacerlo. Parece que hay –

25

En un proyecto de trabajo en, hacemos esto:

raise(SIGABRT); /* To continue from here in GDB: "signal 0". */ 

(En nuestro caso hemos querido chocar duro si esto ocurrió fuera del depurador, la generación de un informe de bloqueo si es posible que esa es una razón por la que utilizamos. .. SIGABRT Hacer esto de forma portátil a través de Windows, Mac y Linux tomó varios intentos terminamos con unos #ifdefs, amablemente comentadas aquí:. http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66)

+2

Como siempre, Windows no se parece a los demás :) – mathk

+0

¿Es posible emitir "señal 0" para continuar programando el programa en estado de pausa? Sería bueno poder usar 'n' o 's' desde este punto, sin una 'c' emitida. –

+1

@JasonDoucette Si realmente desea que el programa se detenga, es posible que desee agregar una función 'breakpoint()' en su programa (puede estar vacía o simplemente contener una declaración de impresión) y agregar 'break breakpoint' a su' ~/.gdbinit'. –

9

__asm__("int $3"); debería funcionar:

int main(int argc, char** argv) 
{ 
    /* set breakpoint here! */ 
    int a = 3; 
    __asm__("int $3"); 
    a++; /* In gdb> print a; expect result to be 3 */ 
    return 0; 
} 
+0

¡Impresionante, gracias! – leishman

+1

Me gusta '# definir' esto, por lo que no tengo que recordar la sintaxis. Lo tengo rociado a lo largo de mi código, a veces en lugar de 'assert()', ya que al detener el debiugger vamos a examinar todas las variables y la pila. Y, por supuesto, como assert, no tengo que eliminarlo para el código de producción – Mawg

1

En OS X sólo puede llamar std::abort() (que podría ser el mismo en Linux)

+0

¿Qué biblioteca? – Alex

Cuestiones relacionadas