2011-05-26 8 views
8

Estoy desarrollando una aplicación (un servicio/daemon, realmente) en Linux en C++ que necesita interconectarse con una pieza de hardware. Si mi programa no libera los recursos para esta pieza de hardware limpiamente al finalizar, entonces tengo que volver a cargar el controlador del dispositivo, un proceso que toma alrededor de 10 minutos y por razones obvias tener que esperar 10 minutos entre cada prueba del programa lo haría ser frustranteSeñales al depurar

Así que he utilizado la función sigaction() para capturar un SIGINT (a ctrl-c) para que mi programa pueda cerrarse limpiamente cuando haya terminado con él. Cuando se ejecuta el programa desde la consola, funciona bien. Sin embargo, al depurar en Netbeans o Eclipse (he probado ambos), las cosas no funcionan.

  • En Eclipse, si golpeo Ctrl-C en la consola que proporciona, no parece registrar que un SIGINT nunca ocurrió
  • En Eclipse, si se me acaba el programa en modo de depuración y luego usar kill -SIGINT <pid>, el programa simplemente se rompe como si tocara un punto de interrupción
  • Netbeans parece darse cuenta de que se ha enviado una señal cuando presiono ctrl-c en la consola, y aparece un cuadro de diálogo preguntándome si quiero reenviarlo a la aplicación . Al hacer clic en "Adelante y continuar", parece que se rompe el programa y la aplicación no recibe la señal. También dice que puedo configurar esto en Debug -> Dbx configure, un elemento de menú que no existe
  • En Netbeans, si ejecuto el programa en modo de depuración y luego uso kill -SIGINT <pid>, el comportamiento es el mismo que el anterior
  • Luego agregué un controlador SIGQUIT e intenté enviarlo a través del kill al depurar en Netbeans. Esta vez, no aparece ningún diálogo y el manejador de señal nunca se dispara.

necesito alguna manera de forma limpia apagado mi aplicación mientras estoy depuración. ¿Algunas ideas?

Respuesta

7

Resulta que el problema no tenía nada que ver con Netbeans o Eclipse, sino con gdb.

gdb se puede configurar para manejar las señales de diferentes maneras. Si ejecuta:

gdb

continuación, escriba:

info signals

que obtendrá una lista de señales y GDB acciones sobre qué hacer si recibe esa señal:

Signal  Stop  Print Pass to program Description 

SIGHUP  Yes  Yes  Yes    Hangup 
SIGINT  Yes  Yes  No    Interrupt 
SIGQUIT  Yes  Yes  Yes    Quit 
SIGILL  Yes  Yes  Yes    Illegal instruction 
SIGTRAP  Yes  Yes  No    Trace/breakpoint trap 

etc ...

Mi tempo El trabajo ha sido utilizar SIGALRM, que gdb establece como predeterminado no interrumpir y enviar al proceso. Sin embargo, también puede personalizar la configuración de gdb predeterminada creando un archivo .gdbinit donde puede configurar estos

+0

Entonces, ¿es posible hacer que gdb maneje SIGINT con sensatez? ¿Cuál sería el contenido de '.gdbinit' para hacerlo? –

2

Solución simple ... Intente utilizar las macros DEBUG para manejar su situación.

// Register the signal handler to stop service. 
#ifdef _DEBUG 
     signal(SIGKILL, <your signal handler>); 
#endif 

Además, puede intentar limpiar su aplicación antes de salir.

+0

Gracias por eso, sino cómo ¿Elegiría cuándo terminar la aplicación? Si pongo esto al final de mi bloque principal() o similar, el servicio se iniciará y se detendrá inmediatamente. – Frederik

+1

Explicar '¿cómo elegiría cuándo finalizar la aplicación?' :) –

+0

Como dije, este será un servicio o un daemon. Algunas veces tendré que probarlo solo por unos segundos, otras veces necesitaré realizar pruebas más extensas. El punto es que no puedo decir Sleep por 15 segundos y luego enviar una señal: necesito poder finalizar el programa en el momento que elija. – Frederik

6

Incluso esta publicación es antigua, espero que pueda ayudar a otros.

Para evitar que Eclipse capture Ctrl + C, puede configurar su gdb usando el archivo .gbdinit. Se crea un .gdinit con este contenido

#we want Ctrl+C to be no break, pass to application and printed by the debugger 
handle SIGINT nostop 
handle SIGINT pass 
handle SIGINT print 

En la configuración de Eclipse, puede definir dónde está su archivo .gdbinit para utilizar en su configuración de depuración

Eclipse capture