Frage

Ich habe einen Prozess in Linux, die immer einen segmentation fault.Wie kann ich sagen, es generiert einen core-dump, wenn es scheitert?

War es hilfreich?

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:

  1. In /etc/profile kommentieren Sie die Zeile:

    # ulimit -S -c 0 > /dev/null 2>&1
    
  2. In /etc/security/limits.conf kommentieren Sie die Zeile:

    *               soft    core            0
    
  3. führen Sie die cmd limit coredumpsize unlimited und überprüfen Sie es mit cmd limit:

    # 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
    #
    
  4. 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

  1. Überprüfen core-dump " aktiviert:

    ulimit -a
    
  2. Eine der Linien sollte :

    core file size          (blocks, -c) unlimited
    
  3. Wenn nicht :

    gedit ~/.bashrc und hinzufügen ulimit -c unlimited zum Ende der Datei und speichern, re-run terminal.

  4. Erstellen Sie Ihre Anwendung mit debug-Informationen :

    Im Makefile -O0 -g

  5. 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
    
  6. 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top