2008-11-25 6 views
11

Tenemos un servidor (escrito en C y C++) que actualmente captura un SEGV y descarga información interna a un archivo. Me gustaría generar un archivo central y escribirlo en el disco en el momento en que atrapemos la SEGV, para que nuestros representantes de soporte y clientes no tengan que preocuparse por ulimit y luego esperar a que la falla vuelva a ocurrir para obtener un núcleo. archivo. Hemos utilizado la función abortar en el pasado, pero está sujeta a las reglas ulimit y no ayuda.¿Cuál es una buena manera de volcar un archivo central de Linux desde dentro de un proceso?

Tenemos un código heredado que lee/proc/pid/map y genera manualmente un archivo core, pero está desactualizado, y no parece muy portátil (por ejemplo, supongo que no funcionaría) en nuestras versiones de 64 bits). ¿Cuál es la mejor manera de generar y volcar un archivo central en un proceso Linux?

+0

Dudo que sea posible, cuando ulimit reglas prohíben la creación de coredumps –

Respuesta

8

Google tiene una biblioteca para generar núcleos dentro de un proceso en ejecución llamado google-coredumper. Esto debería ignorar ulimit y otros mecanismos.

La documentación para la llamada que genera el archivo principal es here. De acuerdo con la documentación, parece que es factible generar un archivo central en un manejador de señal, aunque no se garantiza que siempre funcione.

+0

¡Esto parece muy prometedor! Voy a intentarlo mañana. –

+0

+1, que se ve muy práctico, muy fácil y tiene una licencia muy poco restrictiva :) –

3

Algunas soluciones posibles formas^W de hacer frente a esta situación:

  1. Fix ulimit !!!
  2. Acepte que no obtiene un archivo core y ejecute gdb, con guiones para hacer un "thread all apply bt" en SIGSEGV
  3. Acepte que no obtiene un archivo core y adquiere un rastro de pila desde dentro la aplicación. El artículo Stack Backtracing Inside Your Program es bastante antiguo, pero debería ser posible en estos días también.
+0

Gracias por el enlace a la traza. 1 y 2 actualmente lo hacemos hoy cuando ayudamos a los clientes, pero estoy buscando una forma más automatizada de recuperar el archivo central. En Windows llamamos a una API que genera un archivo de volcado y puede recuperarlo automáticamente. Me gustaría algo similar en nuestra versión de Linux. –

4

Trate de usar el comando gcore Linux

uso: gcore [nombre de archivo -o] pid

Necesitará sistema (o ejecutivo) y getpid() utiliza para construir el comando de la derecha línea para llamar desde dentro de su proceso

5

Vi pmbrett's post y pensé "hey, thats cool", pero no pude encontrar esa utilidad en cualquier lugar de mi sistema (Gentoo).

Así que hice un poco de insistencia, y descubrí que GDB tiene esta opción.

gdb --pid=4049 --batch -ex gcore

Parecía que funcionaba bien para mí.

No obstante, no es muy útil porque atrapa la función más baja que estaba en uso en ese momento, pero aún así hace un buen trabajo (sin limitaciones de memoria, foto descargada de 350M de un proceso de Firefox)

+2

FYI, el comando "gcore" de "linux" es en realidad un comando de RedHat linux. Es un script bourne shell que invoca gdb y usa el comando gcore de gdb para generar el archivo core. –

1

También puede cambiar el ulimit() desde dentro de su programa con setrlimit (2). Al igual que el comando ulimit shell, esto puede reducir los límites o subirlos tan fuerte como lo permita el límite estricto. En el arranque setrlimit() para permitir la descarga del núcleo, y estás bien.

0

sistema ("matar -6")

que le daría una oportunidad si usted todavía está buscando algo

0

uso traza y backtrace_symbols glibc llama para obtener la traza, sólo tener en cuenta que backtrace_symbols usa malloc internamente y en caso de corrupción del montón puede fallar.

1

Supongo que tiene un manejador de señales que atrapa SEGV, por ejemplo, y hace algo así como imprimir un mensaje y llamar a _exit(). (¡De lo contrario, tendrías un archivo central en primer lugar!). Podrías hacer algo como lo siguiente.

void my_handler(int sig) 
{ 
    ... 
    if (wantCore_ && !fork()) { 
     setrlimit(...); // ulimit -Sc unlimited 
     sigset(sig, SIG_DFL); // reset default handler 
     raise(sig); // doesn't return, generates a core file 
    } 
    _exit(1); 
} 
Cuestiones relacionadas