2009-09-26 10 views
6

Tengo una aplicación de servidor que se ejecuta bajo Cent OS. El servidor responde muchas solicitudes por segundo, pero se bloquea repetidamente después de cada hora o más y crea un archivo de volcado de bloqueo. La situación es realmente mala y necesito descubrir la causa del accidente tan pronto como sea posible.Cómo analizar un archivo de volcado de bloqueo usando GDB

Sospecho que el problema es un problema de concurrencia, pero no estoy seguro. Tengo acceso al código fuente y a los archivos de volcado de emergencia, pero no sé cómo usar los volcados de emergencia para identificar el problema.

Cualquier sugerencia es muy apreciada.

Respuesta

7

Lo primero que hay que buscar es el mensaje de error que se obtiene cuando el programa se bloquea. Esto a menudo le dirá qué tipo de error ocurrió. Por ejemplo, "fallo de segmentación" o "SIGSEGV" casi con seguridad significa que su programa ha desreferenciado un puntero NULL o inválido. Si el programa está escrito en C++, el mensaje de error a menudo le dirá el nombre de cualquier excepción no detectada.

Si no aparece el mensaje de error, ejecute el programa desde la línea de comandos o canalice su salida a un archivo.

Para que un archivo core sea realmente útil, debe compilar su programa sin optimización y con información de depuración. GCC necesita las siguientes opciones: -g -O0. (Asegúrese de que su compilación no tenga ninguna otra opción de -O.)

Una vez que tenga el archivo de memoria, y luego abrirlo en GDB con:

gdb YOUR-APP COREFILE 

Tipo where para ver el punto donde ocurrió el accidente. Básicamente estás en una sesión de depuración normal: puedes examinar variables, subir y bajar la pila, alternar entre hilos y lo que sea.

Si su programa se ha bloqueado, es probable que sea un acceso de memoria no válido, por lo que debe buscar un puntero que tenga valor cero o que apunte a datos de aspecto incorrecto. Puede que no encuentres el problema en la parte inferior de la pila, es posible que tengas que subir algunos niveles antes de encontrar el problema.

¡Buena suerte!

0

¿Su aplicación crea un archivo central? Si es así, usaría gdb para solucionar este problema.

9

Si el problema demora aproximadamente una hora en manifestarse, podría tratarse de un problema de memoria, quizás quedarse sin memoria, o quizás pisotear (utilizando la memoria ya liberada, por ejemplo).

Dice que tiene los archivos de volcado de emergencia: ¿eso es un volcado?

Asumiendo que tiene un volcado de memoria, entonces el primer paso debe ser probablemente para imprimir la traza de pila:

gdb program core 
> where 

Esto debe decirle donde el programa fue cuando ocurrió el accidente. ¿Qué más está disponible depende de cómo se compiló el servidor? Si es posible, recompile con la depuración habilitada (eso sería con el indicador '-g' con GCC). Esto le daría más información de la traza inversa.

Si su problema está relacionado con la memoria, considere ejecutar con valgrind.

También considere construir y ejecutar con una versión de depuración de malloc(). Una versión de depuración detectará los abusos de memoria que las versiones normales fallan, o se bloquean.

+0

Gracias por su respuesta detallada. El servidor ha sido compilado con información de depuración y crea un volcado de núcleo cuando se bloquea. El servidor inicializa muchos hilos. Cuando los subprocesos son inferiores a 200, el servidor permanece funcionando durante poco más de una hora, pero cuando el aumento en el número de solicitudes aumenta el número de subprocesos en el grupo a aproximadamente 300, el servidor se bloquea mucho antes. ¿Puede decirme por favor cómo puede ayudar el uso de una versión de depuración de malloc? –

+0

En cuanto a 'depuración Malloc': si el problema es el abuso de memoria, entonces la depuración malloc ayudará al registrar más información sobre el espacio asignado, generalmente asignando más espacio, por lo que cuando se invocan sus funciones, pueden detectar varios géneros de abuso de memoria al principio del proceso, lo que limita el daño causado y generalmente facilita la detección del problema. Por ejemplo, si libera un trozo de memoria ya liberado, puede informarlo, en lugar de simplemente tomarlo gratis y trabajar con la información que realmente no existe. Consulte K & R para una implementación simple de malloc(). –

+0

Con respecto a 'menos de 200 hilos OK; más de 300 choques antes "; ¿ha investigado si el servidor asigna un grupo de tamaño fijo de algún recurso (tal vez 200, tal vez 256) y no verifica adecuadamente el agotamiento de ese recurso. Puede ser un conjunto de mutexes, semáforos u otra cosa que desencadene un abuso de memoria. ¿El código del servidor que escribiste? ¿Debería considerar limitar el número de hilos en el trabajo? –

5
gdb -c core.file exename 
bt 

Suponiendo que exename fue construido con símbolos de depuración (y toda ella es dinámico dependencias están en el camino) que le consiga un rastreo de origen. 'arriba' y 'abajo' lo moverán hacia arriba y hacia abajo en la pila, y p varname se pueden usar para examinar locales y parámetros.

también se podría tratar de ejecutarlo bajo valgrind:

valgrind --tool=memcheck --leak-check=full exename 
Cuestiones relacionadas