How to generate a core dump Linux auf einem segmentation fault?
Frage
Ich habe einen Prozess in Linux, die immer einen segmentation fault.Wie kann ich sagen, es generiert einen core-dump, wenn es scheitert?
Lösung
Dies hängt davon ab, welche shell Sie verwenden.Wenn Sie bash verwenden, dann die ulimit-Befehl steuert mehrere Einstellungen in Bezug auf die Ausführung des Programms, so als ob Sie sollten dump core.Wenn Sie
ulimit -c unlimited
dann, dass wird Ihnen sagen, bash, der die Programme dump Kerne jeder Größe.Sie können eine Größe angeben wie 52M anstelle der unbegrenzten wenn Sie wollen, aber in der Praxis sollte dies nicht notwendig sein, da die Größe der core-Dateien werden wahrscheinlich nie ein Problem für Sie.
In tcsh, du würdest Typ
limit coredumpsize unlimited
Andere Tipps
Wie oben erklärt, die wirkliche Frage hier ist, wie zu aktivieren Sie core-dumps auf einem system, auf dem Sie nicht aktiviert sind.Diese Frage wird hier beantwortet.
Wenn Sie hier gekommen in der Hoffnung, zu lernen, wie zu erzeugen eine core-dump-für ein blockierter Prozess, die Antwort ist
gcore <pid>
wenn gcore ist nicht auf Ihrem system vorhanden, dann
kill -ABRT <pid>
Verwenden Sie nicht töten -SEGV wie oft aufrufen, die ein signal-handler, die es schwerer zu diagnostizieren, den Prozess stecken
Was ich getan habe, war am Ende befestigen Sie den gdb dazu, den Prozess, bevor es abgestürzt, und dann, als es schon der segfault ich ausgeführt generate-core-file
Befehl.Gezwungen generation der core dump.
Um zu überprüfen, wo die core-dumps erzeugt werden, starten:
sysctl kernel.core_pattern
oder:
cat /proc/sys/kernel/core_pattern
wo %e
ist der Prozess Namen und %t
die system-Zeit.Sie können es ändern in /etc/sysctl.conf
und nachladen von sysctl -p
.
Wenn die core-Dateien werden nicht generiert (es testen, indem Sie: sleep 10 &
und killall -SIGSEGV sleep
), überprüfen Sie die Grenzwerte: ulimit -a
.
Wenn Ihr core-Datei, die Größe begrenzt ist, ausgeführt:
ulimit -c unlimited
machen Sie unbegrenzt.
Dann erneut testen, wenn die core-dumping ist erfolgreich, Sie werden sehen "(core dumped)" nach dem "segmentation fault" - Anzeige wie unten:
Segmentation fault:11 (core dumped)
Siehe auch: core dumped - aber eine core-Datei nicht im aktuellen Verzeichnis?
Ubuntu
In Ubuntu werden die core-dumps werden von Apport und können sich in /var/crash/
.Es ist jedoch standardmäßig deaktiviert in der stabilen Versionen.
Für mehr details, bitte überprüfen: Wo finde ich die core-dump in Ubuntu?.
macOS
Für macOS finden Sie unter: Wie generieren Sie core-dumps in Mac OS X?
Vielleicht könnte man es so machen, dieses Programm ist eine demonstration, wie man trap "segmentation fault" und Schalen aus ein debugger (dies ist der ursprüngliche code verwendet unter der AIX
) und druckt den stack-trace-bis zu dem Punkt, segmentation fault.Sie müssen die sprintf
variable verwenden gdb
im Falle von Linux.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>
static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);
struct sigaction sigact;
char *progname;
int main(int argc, char **argv) {
char *s;
progname = *(argv);
atexit(cleanup);
init_signals();
printf("About to seg fault by assigning zero to *s\n");
*s = 0;
sigemptyset(&sigact.sa_mask);
return 0;
}
void init_signals(void) {
sigact.sa_handler = signal_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGSEGV);
sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGBUS);
sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGQUIT);
sigaction(SIGQUIT, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGHUP);
sigaction(SIGHUP, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGKILL);
sigaction(SIGKILL, &sigact, (struct sigaction *)NULL);
}
static void signal_handler(int sig) {
if (sig == SIGHUP) panic("FATAL: Program hanged up\n");
if (sig == SIGSEGV || sig == SIGBUS){
dumpstack();
panic("FATAL: %s Fault. Logged StackTrace\n", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
}
if (sig == SIGQUIT) panic("QUIT signal ended program\n");
if (sig == SIGKILL) panic("KILL signal ended program\n");
if (sig == SIGINT) ;
}
void panic(const char *fmt, ...) {
char buf[50];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, buf);
exit(-1);
}
static void dumpstack(void) {
/* Got this routine from http://www.whitefang.com/unix/faq_toc.html
** Section 6.5. Modified to redirect to file to prevent clutter
*/
/* This needs to be changed... */
char dbx[160];
sprintf(dbx, "echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);
/* Change the dbx to gdb */
system(dbx);
return;
}
void cleanup(void) {
sigemptyset(&sigact.sa_mask);
/* Do any cleaning up chores here */
}
Sie können zusätzlich einen parameter hinzufügen, um zu bekommen, gdb dump core, wie gezeigt, hier in diesem blog hier.
Es gibt mehrere Dinge, die Einfluss auf die generation der core dump.Ich traf diesen:
- das Verzeichnis für die Müllkippe muss beschreibbar sein.Dies ist standardmäßig das aktuelle Verzeichnis des Prozesses, aber das kann geändert werden durch Einstellung
/proc/sys/kernel/core_pattern
. - in einigen Bedingungen, die kernel-Wert in
/proc/sys/fs/suid_dumpable
kann verhindern, dass der Kern erzeugt werden.
Es gibt mehr Situationen, die möglicherweise verhindern, dass die generation, die beschrieben werden, in der man - Seite- versuchen man core
.
Damit aktivieren Sie die core-dump tun die folgenden:
In
/etc/profile
kommentieren Sie die Zeile:# ulimit -S -c 0 > /dev/null 2>&1
In
/etc/security/limits.conf
kommentieren Sie die Zeile:* soft core 0
führen Sie die cmd
limit coredumpsize unlimited
und überprüfen Sie es mit cmdlimit
:# limit coredumpsize unlimited # limit cputime unlimited filesize unlimited datasize unlimited stacksize 10240 kbytes coredumpsize unlimited memoryuse unlimited vmemoryuse unlimited descriptors 1024 memorylocked 32 kbytes maxproc 528383 #
um zu überprüfen, ob der corefile geschrieben wird können Sie töten, die in Bezug Prozess mit cmd
kill -s SEGV <PID>
(sollte nicht nötig sein, nur im Fall, dass keine core-Datei, die geschrieben wird, dies kann verwendet werden als ein prüfen):# kill -s SEGV <PID>
Sobald das corefile geschrieben wurde, stellen Sie sicher, deaktivieren Sie die coredump-Einstellungen wieder in den entsprechenden Dateien (1./2./3.) !
Für Ubuntu 14.04
Überprüfen core-dump " aktiviert:
ulimit -a
Eine der Linien sollte :
core file size (blocks, -c) unlimited
Wenn nicht :
gedit ~/.bashrc
und hinzufügenulimit -c unlimited
zum Ende der Datei und speichern, re-run terminal.Erstellen Sie Ihre Anwendung mit debug-Informationen :
Im Makefile
-O0 -g
Führen Sie die Anwendung, erstellen Sie ein core dump (core dump-Datei mit dem Namen "Kern" erstellt werden sollte, in der Nähe von Anwendungsname-Datei):
./application_name
Unter gdb:
gdb application_name core
Standardmäßig erhalten Sie eine core-Datei.Überprüfen Sie, dass das aktuelle Verzeichnis des Prozesses beschreibbar ist, oder keine core-Datei erstellt werden.
Besser zu aktivieren Kern dump programmgesteuert mithilfe der system call setrlimit
.
Beispiel:
#include <sys/resource.h>
bool enable_core_dump(){
struct rlimit corelim;
corelim.rlim_cur = RLIM_INFINITY;
corelim.rlim_max = RLIM_INFINITY;
return (0 == setrlimit(RLIMIT_CORE, &corelim));
}
Warten.Es automatisch macht.Keine Notwendigkeit, es zu machen
Es ist erwähnenswert, dass, wenn Sie haben ein systemd dann sind die Dinge ein bisschen anders.Das set-up normalerweise haben die core-Dateien geleitet werden, durch core_pattern
sysctl-Wert, durch systemd-coredump(8)
.Die core-Datei, die Größe rlimit würde in der Regel konfiguriert werden, die als "unbegrenzt" schon.
Es ist dann möglich, zum abrufen der core-dumps verwenden coredumpctl(1)
.
Die Speicherung von core-dumps, etc.konfiguriert ist coredump.conf(5)
.Es gibt Beispiele, wie man den Kern Dateien in der coredumpctl Mann-Seite, aber kurz gesagt, es würde so Aussehen:
Finden Sie die core-Datei:
[vps@phoenix]~$ coredumpctl list test_me | tail -1
Sun 2019-01-20 11:17:33 CET 16163 1224 1224 11 present /home/vps/test_me
Holen Sie sich die core-Datei:
[vps@phoenix]~$ coredumpctl -o test_me.core dump 16163