2011-01-06 17 views
5

Tengo una aplicación multiplataforma muy compleja. Recientemente mi equipo y yo hemos estado realizando pruebas de estrés y nos hemos encontrado con varios bloqueos (y volcados de núcleo que los acompañan). Algunos de estos volcados centrales son muy precisos y me muestran la ubicación exacta donde ocurrió el bloqueo con alrededor de 10 o más marcos de pila. Otros a veces tienen solo un marco de pila con ?? siendo el único símbolo!¿Cómo aumentar la probabilidad de que los volcados centrales de Linux coincidan con los símbolos?

Lo que me gustaría saber es:

  1. ¿Hay una manera de aumentar la probabilidad de núcleo vertederos apuntando en la dirección correcta?
  2. ¿Por qué no se informa la cantidad de cuadros de pila consistentes?
  3. Cualquier recomendación de mejores prácticas para la administración de volcados de núcleo.

Así es como puedo compilar los binarios (en modo de lanzamiento):

  1. compilador y la plataforma: g ++ con glibc-2.3.2-95.50 en CentOS 3.6 x86_64 - Esto me ayuda a mantener la compatibilidad con versiones anteriores de versiones de Linux.
  2. Todos los archivos se compilan con el distintivo -g.
  3. Los símbolos de depuración se eliminan del archivo binario final y se guardan en un archivo separado.
  4. Cuando tengo un volcado del núcleo, uso GDB con el ejecutable que creó el núcleo y el archivo de símbolos. GDB nunca se queja de que haya un desajuste entre el núcleo/binario/símbolos.

Sin embargo, a veces obtengo almacenes sin ningún símbolo. Es comprensible que esté enlazando con una versión sin depuración de libstdC++ y libgcc, pero sería bueno si al menos el rastreo de la pila me muestra dónde en mi código se originó la llamada a la instrucción defectuosa (aunque en última instancia puede terminar en ??) .

Respuesta

7

Otros a veces solo tienen un marco de pila con "??" siendo el único símbolo!

Puede haber muchas razones para ello, entre otros:

  • que la pila se papelera (sobrescrito)
  • EBP/RBP (x86/x64) actualmente no está llevando a cabo ningún valor significativo - Esto puede suceder, por ejemplo en unidades compilados con o asm unidades que lo hacen

Nota que el segundo punto se puede producir simplemente mediante, por ejemplo, glibc siendo compilado de tal manera. Tener la información de depuración para tales bibliotecas del sistema instaladas podría mitigar esto (algo así como lo que los paquetes glibc-debug {info, source} están en openSUSE).

gdb tiene más control sobre el programa que glibc, por lo que la llamada de backtrace de glibc tampoco podría imprimir una traza inversa si gdb tampoco puede hacerlo.

Pero el envío de la fuente sería mucho más fácil :-)

+2

Esto es altamente probable que sea el problema - si el marco de pila se ha roto por el insecto, luego se ha ido. – caf

+0

Upvoted. Si el error está destruyendo la pila, no hay sustituto para fallar temprano y en voz alta. assert() es tu amigo. – user47559

2
  1. ¿Ha intentado instalar símbolos de depuración de las diversas bibliotecas que está utilizando? Por ejemplo, mi distribución (Ubuntu) proporciona libc6-dbg, libstdc++6-4.5-dbg, etc. libgcc1-dbg
  2. Si usted está construyendo con la optimización activada (por ejemplo. -O2), el compilador puede difuminar los límites entre los marcos de pila, por ejemplo, mediante procesos en línea. No estoy seguro de que esto cause retrocesos con solo un stack frame, pero en general la regla es esperar una gran dificultad de depuración ya que el código que está buscando en el volcado del núcleo ha sido modificado y por lo tanto no se corresponde necesariamente con su fuente .
3

Como alternativa, en un sistema de glibc, se puede utilizar la llamada backtrace función (o backtrace_symbols o backtrace_symbols_fd) y filtrar los resultados usted mismo, por lo que sólo se muestran los símbolos que pertenecen a su propio código. Es un poco más trabajo, pero luego, realmente puedes adaptarlo a tus necesidades.

Cuestiones relacionadas