ver tuberias salida redireccionamiento pipes guardar filtros ejemplos contenido comandos comando basicos archivo linux gdb

tuberias - ¿Cuál es una buena forma de volcar un archivo central de Linux desde dentro de un proceso?



tuberias y filtros en linux (8)

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.

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 nuestros 64 bits). construcciones). ¿Cuál es la mejor manera de generar y volcar un archivo central en un proceso Linux?


Algunas posibles soluciones ^ formas de lidiar con esta situación:

  1. ¡Arregla el ulimit!
  2. Acepte que no obtiene un archivo core y ejecute gdb, con un script para hacer un "thread all apply bt" en SIGSEGV
  3. Acepte que no obtiene un archivo principal y que ha adquirido un seguimiento de la pila desde la aplicación. El artículo de Backtracing de pila dentro del programa es bastante antiguo, pero también debería ser posible en estos días.

Intente usar el comando de Linux gcore

uso: gcore [-o nombre de archivo] pid

Tendrá que usar system (o exec) y getpid () para crear la línea de comando correcta para llamar desde dentro de su proceso


Google tiene una biblioteca para generar núcleos desde 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 central está aquí . De acuerdo con la documentación, parece que es factible generar un archivo central en un controlador de señal, aunque no se garantiza que siempre funcione.


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.


sistema ("matar -6")

Lo probaría si todavía estás buscando algo


use backtrace y backtrace_symbols glibc calls para obtener la traza, solo tenga en cuenta que backtrace_symbols utiliza malloc internamente y en caso de corrupción del montón puede fallar.


Supongo que tiene un manejador de señales que atrapa a 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); }


Vi la publicación de pmbrett y pensé "hey, thats cool", pero no pude encontrar esa utilidad en 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 funcionar 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 fuera de eso (sin limitaciones de memoria, la copia de 350M descargada de un proceso de Firefox con ella)