2010-02-12 22 views
13

Quiero crear un volcado del núcleo cada vez que se bloquea mi proceso. Actualmente estoy siguiendo este enfoque:Volcado del núcleo en Linux

  1. Cree una versión especial de "depuración" del programa utilizando "-g" de gcc/g ++.
  2. Ejecutar "ulimit -c unlimited"
  3. Ahora obtenemos el volcado del núcleo cada vez que el programa falla.

Pero yo quiero minimizar el número de pasos de modo que:

  • volcado del núcleo deben conseguir siempre creados. Incluso si se trata de una versión de "lanzamiento". No se le debe pedir al usuario que ejecute el comando "ulimit -c unlimited" manualmente.
  • Ese backtrace del volcado del núcleo debe poder dar el archivo, la función, el número de línea de las llamadas. Esa es la traza de pila en una forma legible por humanos.
  • No quiero construir el programa como una versión de depuración con "-g". O al menos no debería contener ninguna otra información de depuración que no sea necesaria para generar el rastreo de pila legible por el ser humano. Porque esto sería una versión de lanzamiento del programa.

así que tengo dos preguntas:

  1. cómo crear un volcado de memoria en la construcción de "liberación" de un programa?
  2. Siempre. Sin ejecutar manualmente el "ulimit -c unlimited"

Respuesta

7

La solución habitual es construir con -g y quitar la información de depuración antes de liberar el archivo. Busque el comando 'strip'. Mantiene el archivo con la información de depuración y lo usa para depurar volcados del núcleo que obtiene de los clientes.

Si desea imprimir la traza inversa legible por el ser humano en la máquina de los usuarios, deberá distribuir los archivos binarios con (alguna) información de depuración. Busque la función 'backtrace()' en glibc.

Tenga en cuenta que se crearán volcados del núcleo (si ulimit está configurado correctamente), incluso si su binario no contiene información de depuración.

La mejor manera de garantizar la creación de un volcado del núcleo es ejecutar su binario desde un script que establece ulimit antes de ejecutar el binario.

-3

Difícilmente obtendrá una stack stack decente en forma humana si el código es un modo de lanzamiento/versión altamente optimizada. Usa el modificador -g u olvida hacer una stacktrace ... ¡no puedes tener ambas cosas! Lo que nos lleva a este punto, parece que anticipamos que el código se bloqueará incluso en el entorno de producción?

¿Por qué no se soluciona el código y asegurarse de que funciona primero ... código huele .... sniff sniff

Editar: Ok, puede que haya llegado a través de un poco duro en mi comentario anterior, no tenía la intención de ser duro allí ... para el beneficio de los lectores, he incluido un enlace a otra pregunta publicada aquí, y en ese answer di, utilizo señales para crear un seguimiento de la pila y redirigir a un archivo.Será de ayuda a la pregunta del OP y le ayuda en la solución de problemas ...

+0

Es importante entender que los niveles de '-g' y optimización son completamente ajenos. '-g' significa que la información de depuración se agregará al binario. No significa que el código no será optimizado. 'gcc -g -O3 ...' es una cosa perfectamente razonable que hacer (en el entendimiento de que el código puede ser un poco más difícil de depurar). –

+0

Bueno, porque a veces los bloqueos son muy difíciles de reproducir. Y los errores no siempre son predecibles, ¿verdad? Esa vez no quiero perder la información. – Sabya

+0

Incluso con la optimización, una traza de pila por lo general parece dar la función correcta (si no necesariamente la línea correcta). Por lo general, no está muy lejos. Al menos esa es mi experiencia. – MarkR

11
  • En cuanto al límite del núcleo, puede hacerlo usted mismo en C llamando setrlimit.
  • En un sistema GNU (glibc) o BSD, puede obtener una traza inversa llamando al backtrace y las llamadas al sistema relacionadas. A continuación, deberá traducir las direcciones de las funciones a nombres de funciones ejecutando addr2line (o duplicando su funcionalidad).
  • Simplemente no use -g, aún puede obtener una traza inversa (excepto que las funciones en línea no aparecerán).
1
  1. No hay tal cosa como una versión de "liberación" y la versión "depuración" en Linux. Usted acaba de construir un programa con información de depuración cuando usa "-g". Puedes quitar esta información.

Actualizado
En realidad creo que debo decir acerca de una posible diferencia entre depurar y liberar versiones que no he mencionado en mi mensaje. Las versiones de lanzamiento se pueden construir con la definición de NDEBUG para deshacerse de todos assert() en el programa. Las versiones de depuración, por el contrario, deben construirse sin definir NDEBUG como assert() ayuda a encontrar errores.

Sin embargo, si no utiliza assert(), no habrá diferencia.

  1. Un usuario puede establecer ulimit -c unlimited en su perfil.

  2. Backtrace de un programa compilado con cierta optimización a menudo no da un número de línea que es útil.

  3. Puede crear una versión con información de depuración y ponerla en su archivo. Luego quítelo y entregue los binarios sin etiquetas a sus clientes. Si un cliente le proporciona un archivo central, simplemente use la versión con información de depuración y el archivo principal del cliente.

  4. How to create a core dump in the "release" build of a program? No es su responsabilidad, es responsabilidad del sistema operativo.

3

Puede probar Google-coredumper:

Una herramienta para la creación ordenada BGF coredumps legibles de las aplicaciones multitarea, - mientras que el programa se está ejecutando. La biblioteca de coredumper se puede compilar en aplicaciones para crear volcados de núcleo del programa en ejecución, sin terminar.

http://sourceforge.net/projects/goog-coredumper/

Cuestiones relacionadas