Cómo causar un volcado de núcleo en C/C++ mediante programación
linux coredump (10)
Me gustaría forzar un volcado de memoria en una ubicación específica en mi aplicación C ++.
Sé que puedo hacerlo haciendo algo como:
int * crash = NULL;
*crash = 1;
Pero me gustaría saber si hay una manera más limpia?
Estoy usando Linux por cierto.
A veces puede ser apropiado hacer algo así:
int st = 0;
pid_t p = fork();
if (!p) {
signal(SIGABRT, SIG_DFL);
abort(); // having the coredump of the exact copy of the calling thread
} else {
waitpid(p, &st, 0); // rip the zombie
}
// here the original process continues to live
Un problema con este enfoque simple es que solo se fusionará un hilo.
Aumentar la señal número 6 ( SIGABRT
en Linux) es una forma de hacerlo (aunque tenga en cuenta que no se requiere que SIGABRT sea 6 en todas las implementaciones POSIX, por lo que puede utilizar el valor SIGABRT
si esto no es rápido ''n''dirty debug code).
#include <signal.h>
: : :
raise (SIGABRT);
Llamar a abort()
también provocará un volcado del núcleo, e incluso puede hacer esto sin finalizar su proceso llamando a fork()
seguido de abort()
en el elemento secundario - vea esta respuesta para más detalles.
Como se enumera en la página de manual de señal , cualquier señal con la acción enumerada como ''núcleo'' forzará un volcado de núcleo. Algunos ejemplos son:
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating point exception
SIGSEGV 11 Core Invalid memory reference
Asegúrese de habilitar vuelcos principales:
ulimit -c unlimited
Hace unos años, Google lanzó la biblioteca de coredumper .
Visión de conjunto
La biblioteca de coredumper se puede compilar en aplicaciones para crear volcados de núcleo del programa en ejecución, sin terminar. Admite volcados de núcleos de subprocesos múltiples y múltiples, incluso si el kernel no es compatible de forma nativa con los archivos principales de subprocesos múltiples.
Coredumper se distribuye bajo los términos de la licencia BSD.
Ejemplo
Esto de ninguna manera es un ejemplo completo; simplemente te da una idea de cómo es la API de coredumper.
#include <google/coredumper.h> ... WriteCoreDump(''core.myprogram''); /* Keep going, we generated a core file, * but we didn''t crash. */
No es lo que estabas pidiendo, pero tal vez es aún mejor :)
Otra forma de generar un volcado de núcleo:
$ bash
$ kill -s SIGSEGV $$
Simplemente crea una nueva instancia del bash y mátalo con la señal especificada. El $$
es el PID del shell. De lo contrario, estás matando a tu bash actual y se cerrará la sesión, la terminal se cerrará o desconectará.
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
Puede usar kill(2) para enviar la señal.
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Asi que,
kill(getpid(), SIGSEGV);
abortar();
Relacionado, a veces desearía un rastreo posterior sin un volcado de núcleo real, y permitir que el programa continúe ejecutándose: consulte las funciones de backtrace () y backtrace_symbols () de glibc: http://www.gnu.org/s/libc/manual/html_node/Backtraces.html
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("/n");
printf("Process is aborting/n");
abort();
printf("Control not reaching here/n");
return 0;
}
utiliza este enfoque donde quieras :)
#include <assert.h>
.
.
.
assert(!"this should not happen");
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}