Was hat meinen Prozess getötet und warum?

614

Meine Anwendung wird als Hintergrundprozess unter Linux ausgeführt. Es wird derzeit über die Befehlszeile in einem Terminalfenster gestartet.

Kürzlich hat ein Benutzer die Anwendung für eine Weile ausgeführt und sie ist auf mysteriöse Weise gestorben. Der Text:

Getötet

war auf dem Terminal. Dies geschah zweimal. Ich habe gefragt, ob jemand an einem anderen Terminal den Befehl kill verwendet hat, um den Prozess abzubrechen. Nein.

Unter welchen Bedingungen würde Linux beschließen, meinen Prozess abzubrechen? Ich glaube, die Shell zeigte "getötet" an, weil der Prozess nach dem Empfang des Kill (9) -Signals gestorben ist. Wenn Linux das Kill-Signal gesendet hat, sollte sich irgendwo in einem Systemprotokoll eine Meldung befinden, die erklärt, warum es getötet wurde?

sbq
quelle
23
Linux hat meinen Prozess beendet und ihn in / var / log / messages auf redhat angemeldet
Dean Hiller
1
Siehe auch diese Antwort auf unix.stackexchange.com.
Richard
In diesem Fall gibt es 3 Spieler: (1) Der Prozess, der (häufige Ursache) zu viel Speicher benötigt und die OOM-Bedingung verursacht. (2) Der Kernel, der den SIGKILL (Signal 9) sendet, um ihn zu beenden und die Tatsache in einem System zu protokollieren log like /var/log/messages(3) Die Shell, unter der der Prozess ausgeführt wurde. Killedwaitpid(2)
Dies
Nachdem ich die Antwort von @ DeanHiller gelesen hatte, fand ich unter Ubuntu unter/var/log/syslog
Dinei

Antworten:

403

Wenn der Benutzer oder Sysadmin das Programm nicht beendet hat, hat der Kernel möglicherweise. Der Kernel würde einen Prozess nur unter außergewöhnlichen Umständen wie extremem Ressourcenmangel beenden (denken Sie an mem + Swap-Erschöpfung).

dwc
quelle
25
Wenn der Kernel den Prozess beenden würde, würde er irgendwo eine Nachricht in ein Protokoll einfügen?
sbq
186
Ich habe gerade ein Programm geschrieben, das Speicher in einer Endlosschleife speichert. Nachdem das System langsam geworden war, wurde im Terminal "Getötet" angezeigt und der Prozess wurde beendet. Die Datei /var/log/kern.log enthielt viele Informationen zur Beendigung. -Danke für den Zeiger.
sbq
6
Das ist es fast definitiv. Ich habe das oft gesehen, als ich TAing. Viele Schüler würden vergessen, ihre Objekte freizugeben, und die Apps würden schließlich 3 GB virtuellen Speicher nutzen. Sobald es diesen Punkt erreichte, wurde es getötet.
Herms
8
Wenn das "Programm einfach abstürzt", ist das das Betriebssystem, das den Prozess tatsächlich beendet!
Bernd Jendrissek
79
Verwenden Sie dmesgdiese Option , um das Kernel-Protokoll anzuzeigen: Hier finde ich meine Python-Prozesse, die vom Kernel aufgrund des extremen Verbrauchs an virtuellem Speicher beendet wurden.
Caneta
273

Versuchen:

dmesg -T| grep -E -i -B100 'killed process'

Wobei -B100die Anzahl der Zeilen vor dem Kill angegeben ist.

Lassen Sie -T unter Mac OS weg .

Ravindranath Akila
quelle
6
Zu Ihrer Information, von info egrep: "egrep ist dasselbe wie grep -E. ... Direkter Aufruf, da entweder egrep oder fgrep veraltet sind"
Air
9
Im Falle eines einfachen Musters, wie 'killed process'Sie es verwenden können, grepanstatt egrepohne weitere Änderungen. Für ein komplexeres Muster würden Sie das Ersetzen ändern, z . B. egrep -i -B100 'foo|ba[rz]'durch grep -E -i -B100 'foo|ba[rz]'. Diese Fragen und Antworten enthalten weitere Einzelheiten.
Luft
2
Ich würde auch vorschlagen, dmesg -Tzu verwenden, um lesbare Zeitstempel zu erhalten
Gukoff
171

Dies sieht nach einem guten Artikel zu diesem Thema aus: Den OOM-Killer zähmen .

Der Kern ist , dass Linux overcommitsErinnerung. Wenn ein Prozess mehr Speicherplatz benötigt, gibt Linux ihm diesen Speicherplatz, auch wenn er von einem anderen Prozess beansprucht wird, unter der Annahme, dass niemand tatsächlich den gesamten von ihm angeforderten Speicher verwendet. Der Prozess verwendet ausschließlich den Speicher, den er zugewiesen hat, wenn er ihn tatsächlich verwendet, und nicht, wenn er danach fragt. Dies macht die Zuweisung schnell und ermöglicht es Ihnen möglicherweise, mehr Speicher zu "betrügen" und zuzuweisen, als Sie wirklich haben. Sobald Prozesse diesen Speicher verwenden, stellt Linux möglicherweise fest, dass die Zuweisung von nicht vorhandenem Speicher zu großzügig war, und muss einen Prozess abbrechen, um einige freizugeben. Der abzubrechende Prozess basiert auf einer Bewertung, die die Laufzeit (lang laufende Prozesse sind sicherer), die Speichernutzung (gierige Prozesse sind weniger sicher) und einige andere Faktoren berücksichtigt. einschließlich eines Werts, den Sie anpassen können, um die Wahrscheinlichkeit zu verringern, dass ein Prozess abgebrochen wird. Es ist alles im Artikel viel detaillierter beschrieben.

Bearbeiten: Und hier ist ein weiterer Artikel , der ziemlich gut erklärt, wie ein Prozess ausgewählt wird (kommentiert mit einigen Kernel-Codebeispielen). Das Tolle daran ist, dass es einige Kommentare zu den Gründen für die verschiedenen badness()Regeln enthält.

Adam Jaskiewicz
quelle
3
Ich liebe die Artikel-Links wirklich. Ich würde jedem empfehlen, der sich für das Thema interessiert, es zu lesen - insbesondere die Kommentare zum lwn-Artikel.
Jon Bringhurst
4
"Linux wird ihm diesen Speicherplatz geben, auch wenn er von einem anderen Prozess beansprucht wird." So funktioniert virtueller Speicher nicht ganz ...
Mooing Duck
1
Der Artikel ist ziemlich alt (2009) und nicht alle im Artikel vorgeschlagenen Funktionen sind in der Hauptzeile.
Alex
50

Lassen Sie mich zunächst erklären, wann und warum OOMKiller aufgerufen wird.

Angenommen, Sie haben 512 RAM + 1 GB Swap-Speicher. Theoretisch hat Ihre CPU also Zugriff auf insgesamt 1,5 GB virtuellen Speicher.

Jetzt läuft seit einiger Zeit alles einwandfrei innerhalb von 1,5 GB Gesamtspeicher. Aber plötzlich (oder allmählich) verbraucht Ihr System immer mehr Speicher und erreicht zu einem Zeitpunkt etwa 95% des gesamten verwendeten Speichers.

Angenommen, ein Prozess hat vom Kernel einen großen Speicherplatz angefordert. Der Kernel überprüft den verfügbaren Speicher und stellt fest, dass Ihr Prozess auf keinen Fall mehr Speicher zuweisen kann. Es wird also versucht, Speicherplatz freizugeben, der OOMKiller ( http://linux-mm.org/OOM ) aufruft / aufruft .

OOMKiller hat einen eigenen Algorithmus, um den Rang für jeden Prozess zu ermitteln. In der Regel wird der Prozess, der mehr Speicher benötigt, zum Opfer, das getötet werden muss.

Wo finde ich Protokolle von OOMKiller?

Normalerweise im Verzeichnis / var / log. Entweder /var/log/kern.log oder / var / log / dmesg

Hoffe das wird dir helfen.

Einige typische Lösungen:

  1. Speicher erhöhen (nicht tauschen)
  2. Suchen Sie die Speicherlecks in Ihrem Programm und beheben Sie sie
  3. Beschränken Sie den Speicher, den jeder Prozess belegen kann (z. B. kann der JVM-Speicher mithilfe von JAVA_OPTS eingeschränkt werden).
  4. Siehe die Protokolle und Google :)
Jadav Bheda
quelle
17

Dies ist der Linux Out of Memory Manager (OOM) . Ihr Prozess wurde aufgrund von " Schlechtigkeit " ausgewählt - einer Kombination aus Aktualität, Größe des Bewohners (nicht genutzter Speicher) und anderen Faktoren.

sudo journalctl -xb

Sie sehen eine Nachricht wie:

Jul 20 11:05:00 someapp kernel: Mem-Info:
Jul 20 11:05:00 someapp kernel: Node 0 DMA per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:    0, btch:   1 usd:   0
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:  186, btch:  31 usd:  30
Jul 20 11:05:00 someapp kernel: active_anon:206043 inactive_anon:6347 isolated_anon:0
                                    active_file:722 inactive_file:4126 isolated_file:0
                                    unevictable:0 dirty:5 writeback:0 unstable:0
                                    free:12202 slab_reclaimable:3849 slab_unreclaimable:14574
                                    mapped:792 shmem:12802 pagetables:1651 bounce:0
                                    free_cma:0
Jul 20 11:05:00 someapp kernel: Node 0 DMA free:4576kB min:708kB low:884kB high:1060kB active_anon:10012kB inactive_anon:488kB active_file:4kB inactive_file:4kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 968 968 968
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 free:44232kB min:44344kB low:55428kB high:66516kB active_anon:814160kB inactive_anon:24900kB active_file:2884kB inactive_file:16500kB unevictable:0kB isolated(anon):0kB isolated
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 0 0 0
Jul 20 11:05:00 someapp kernel: Node 0 DMA: 17*4kB (UEM) 22*8kB (UEM) 15*16kB (UEM) 12*32kB (UEM) 8*64kB (E) 9*128kB (UEM) 2*256kB (UE) 3*512kB (UM) 0*1024kB 0*2048kB 0*4096kB = 4580kB
Jul 20 11:05:00 someapp kernel: Node 0 DMA32: 216*4kB (UE) 601*8kB (UE) 448*16kB (UE) 311*32kB (UEM) 135*64kB (UEM) 74*128kB (UEM) 5*256kB (EM) 0*512kB 0*1024kB 1*2048kB (R) 0*4096kB = 44232kB
Jul 20 11:05:00 someapp kernel: Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
Jul 20 11:05:00 someapp kernel: 17656 total pagecache pages
Jul 20 11:05:00 someapp kernel: 0 pages in swap cache
Jul 20 11:05:00 someapp kernel: Swap cache stats: add 0, delete 0, find 0/0
Jul 20 11:05:00 someapp kernel: Free swap  = 0kB
Jul 20 11:05:00 someapp kernel: Total swap = 0kB
Jul 20 11:05:00 someapp kernel: 262141 pages RAM
Jul 20 11:05:00 someapp kernel: 7645 pages reserved
Jul 20 11:05:00 someapp kernel: 264073 pages shared
Jul 20 11:05:00 someapp kernel: 240240 pages non-shared
Jul 20 11:05:00 someapp kernel: [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
Jul 20 11:05:00 someapp kernel: [  241]     0   241    13581     1610      26        0             0 systemd-journal
Jul 20 11:05:00 someapp kernel: [  246]     0   246    10494      133      22        0         -1000 systemd-udevd
Jul 20 11:05:00 someapp kernel: [  264]     0   264    29174      121      26        0         -1000 auditd
Jul 20 11:05:00 someapp kernel: [  342]     0   342    94449      466      67        0             0 NetworkManager
Jul 20 11:05:00 someapp kernel: [  346]     0   346   137495     3125      88        0             0 tuned
Jul 20 11:05:00 someapp kernel: [  348]     0   348    79595      726      60        0             0 rsyslogd
Jul 20 11:05:00 someapp kernel: [  353]    70   353     6986       72      19        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  362]    70   362     6986       58      18        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  378]     0   378     1621       25       8        0             0 iprinit
Jul 20 11:05:00 someapp kernel: [  380]     0   380     1621       26       9        0             0 iprupdate
Jul 20 11:05:00 someapp kernel: [  384]    81   384     6676      142      18        0          -900 dbus-daemon
Jul 20 11:05:00 someapp kernel: [  385]     0   385     8671       83      21        0             0 systemd-logind
Jul 20 11:05:00 someapp kernel: [  386]     0   386    31573      153      15        0             0 crond
Jul 20 11:05:00 someapp kernel: [  391]   999   391   128531     2440      48        0             0 polkitd
Jul 20 11:05:00 someapp kernel: [  400]     0   400     9781       23       8        0             0 iprdump
Jul 20 11:05:00 someapp kernel: [  419]     0   419    27501       32      10        0             0 agetty
Jul 20 11:05:00 someapp kernel: [  855]     0   855    22883      258      43        0             0 master
Jul 20 11:05:00 someapp kernel: [  862]    89   862    22926      254      44        0             0 qmgr
Jul 20 11:05:00 someapp kernel: [23631]     0 23631    20698      211      43        0         -1000 sshd
Jul 20 11:05:00 someapp kernel: [12884]     0 12884    81885     3754      80        0             0 firewalld
Jul 20 11:05:00 someapp kernel: [18130]     0 18130    33359      291      65        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18132]  1000 18132    33791      748      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18133]  1000 18133    28867      122      13        0             0 bash
Jul 20 11:05:00 someapp kernel: [18428]    99 18428   208627    42909     151        0             0 node
Jul 20 11:05:00 someapp kernel: [18486]    89 18486    22909      250      46        0             0 pickup
Jul 20 11:05:00 someapp kernel: [18515]  1000 18515   352905   141851     470        0             0 npm
Jul 20 11:05:00 someapp kernel: [18520]     0 18520    33359      291      66        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18522]  1000 18522    33359      294      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18523]  1000 18523    28866      115      12        0             0 bash
Jul 20 11:05:00 someapp kernel: Out of memory: Kill process 18515 (npm) score 559 or sacrifice child
Jul 20 11:05:00 someapp kernel: Killed process 18515 (npm) total-vm:1411620kB, anon-rss:567404kB, file-rss:0kB
Mikemaccana
quelle
12

Wie dwc und Adam Jaskiewicz festgestellt haben, ist der Schuldige wahrscheinlich der OOM Killer. Die nächste Frage lautet jedoch: Wie verhindere ich dies?

Es gibt verschiedene Möglichkeiten:

  1. Geben Sie Ihrem System mehr RAM, wenn Sie können (einfach, wenn es sich um eine VM handelt).
  2. Stellen Sie sicher, dass der OOM-Killer einen anderen Prozess wählt.
  3. Deaktivieren Sie den OOM Killer
  4. Wählen Sie eine Linux-Distribution, die mit deaktiviertem OOM Killer geliefert wird.

Ich fand (2) dank dieses Artikels besonders einfach zu implementieren .

Carl
quelle
2
Es war der RAM für mich. Ich habe ein Upgrade von 2 auf 4 GB RAM durchgeführt und das Problem ist behoben. Jetzt ist das Problem mit der Rechnung: P
Gus
9

Die PAM - Modul zu begrenzen Ressourcen verursachen genau die Ergebnisse , die Sie beschrieben: Mein Prozess starb auf mysteriöse Weise mit dem Text getötet auf dem Konsolenfenster. Keine Protokollausgabe, weder in syslog noch in kern.log . Mit dem Top- Programm konnte ich feststellen, dass mein Prozess genau nach einer Minute CPU-Auslastung beendet wird.

Christian Ammer
quelle
8

Ein Tool wie systemtap (oder ein Tracer) kann die Kernel-Signalübertragungslogik überwachen und Berichte erstellen. Beispiel: https://sourceware.org/systemtap/examples/process/sigmon.stp

# stap .../sigmon.stp -x 31994 SIGKILL
   SPID     SNAME            RPID  RNAME            SIGNUM SIGNAME
   5609     bash             31994 find             9      SIGKILL

Der Filterblock ifin diesem Skript kann nach Geschmack angepasst oder entfernt werden, um den systemweiten Signalverkehr zu verfolgen. Die Ursachen können durch Sammeln von Backtraces weiter isoliert werden (fügen Sie ein print_backtrace()und / oder print_ubacktrace()zur Sonde für den Kernel- bzw. den User-Space hinzu).

fche
quelle
4

In einer lsf-Umgebung (interaktiv oder auf andere Weise) werden die Prozesse beendet, wenn die Anwendung die Speicherauslastung über einen von den Administratoren in der Warteschlange festgelegten Schwellenwert oder die Ressourcenanforderung beim Senden an die Warteschlange hinaus überschreitet, damit andere Benutzer nicht einem potenziellen Opfer zum Opfer fallen Renn weg. Es wird nicht immer eine E-Mail gesendet, wenn dies der Fall ist, je nachdem, wie es eingerichtet ist.

Eine Lösung in diesem Fall besteht darin, eine Warteschlange mit größeren Ressourcen zu finden oder größere Ressourcenanforderungen in der Übermittlung zu definieren.

Möglicherweise möchten Sie auch überprüfen man ulimit

Obwohl ich mich nicht daran erinnere, ulimitdass Killedes eine Weile her ist, seit ich das brauchte.

alter Mann
quelle
2

Wir hatten wiederkehrende Probleme unter Linux bei einem Kundenstandort (Red Hat, glaube ich), wobei OOMKiller (Out-of-Memory-Killer) sowohl unsere Hauptanwendung (dh den Grund, warum der Server existiert) als auch seine Datenbankprozesse tötete.

In jedem Fall entschied OOMKiller einfach, dass die Prozesse zu viele Ressourcen verbrauchten ... die Maschine würde nicht einmal aus Mangel an Ressourcen ausfallen. Weder die Anwendung noch ihre Datenbank haben Probleme mit Speicherlecks (oder anderen Ressourcenlecks).

Ich bin kein Linux-Experte, aber ich habe den Algorithmus zusammengestellt, um zu entscheiden, wann etwas getötet werden soll und was zu töten ist, ist komplex. Außerdem wurde mir gesagt (ich kann nicht über die Genauigkeit sprechen), dass OOMKiller in den Kernel eingebrannt ist und man es nicht einfach nicht ausführen kann.

Lawrence Dol
quelle
1
IIRC, OOMKiller wird nur als letztes Mittel aufgerufen. Ich denke, das System wird sogar ein Signal an verschiedene Apps senden und sie bitten, einige Ressourcen aufzugeben, bevor es gezwungen ist, OOMKiller aufzurufen. Nehmen Sie mit einem Körnchen Salz, wie es lange her ist ...
rmeador
1
Sie können es einfach nicht ausführen. Es ist in den Kernel eingebrannt, aber es gibt Optionen, um zu optimieren, wie es ausgeführt wird und sogar welche Prozesse es wahrscheinlich abbricht. Es wird ausgeführt, wenn das gesamte System nicht über genügend Arbeitsspeicher verfügt und nicht, wenn ein bestimmter Prozess zu viel verwendet. Siehe meine Antwort für weitere Details.
Adam Jaskiewicz
6
Oomkiller nicht laufen zu lassen ist ziemlich einfach. echo "2" > /proc/sys/vm/overcommit_memory
R .. GitHub STOP HELPING ICE
Red Hat will nicht, dass es geändert wird: sudo echo "2" > /proc/sys/vm/overcommit_memory/ proc / sys / vm / overcommit_memory: Erlaubnis verweigert
Brent Faust
2
Versuchen Sieecho 2 | sudo tee /proc/sys/vm/overcommit_memory
Hypershadsy
2

In meinem Fall geschah dies mit einem Laravel-Warteschlangenarbeiter. In den Systemprotokollen wurde kein Kill erwähnt, daher habe ich weiter nachgesehen und es stellte sich heraus, dass der Worker sich aufgrund eines Jobs, der das Speicherlimit (das standardmäßig auf 128 MB festgelegt ist) überschritten hat, im Grunde selbst getötet hat.

Ausführen des Warteschlangenarbeiters mit --timeout=600und --memory=1024Behebung des Problems für mich.

iSWORD
quelle
0

Der Benutzer hat die Möglichkeit, seine eigenen Programme mit kill oder Control + C zu beenden, aber ich habe den Eindruck, dass dies nicht der Fall ist und dass sich der Benutzer bei Ihnen beschwert hat.

root hat natürlich die Fähigkeit, Programme zu beenden, aber wenn jemand root auf Ihrem Computer hat und Sachen tötet, haben Sie größere Probleme.

Wenn Sie nicht der Systemadministrator sind, hat der Systemadministrator möglicherweise Kontingente für CPU, RAM, oder Festplattennutzung eingerichtet und Prozesse, die diese überschreiten, automatisch beendet.

Abgesehen von diesen Vermutungen bin ich mir ohne weitere Informationen über das Programm nicht sicher.

Tom Ritter
quelle
6
STRG-C sendet einen anderen Kill als das gemeldete OP (SIGINT (2), wie ich mich erinnere, während das Programm ein SIGKILL (9) empfängt).
Powerlord
0

Ich bin in letzter Zeit auf dieses Problem gestoßen. Schließlich stellte ich fest, dass meine Prozesse unmittelbar nach dem automatischen Aufruf des Opensuse Zypper-Updates abgebrochen wurden. Das Deaktivieren des Zypper-Updates hat mein Problem gelöst.

armer Entwickler
quelle
Ich sehe das gleiche Problem. Wie haben Sie herausgefunden, welcher Prozess Ihren Prozess beendet hat? Anscheinend gibt es ein Tool, mit dem überprüft werden kann, wer SIGKILL an einen Prozess sendet.
Howy
0

Dieses Problem wurde durch Erhöhen der Swap-Größe behoben :

/ubuntu/1075505/how-do-i-increase-swapfile-in-ubuntu-18-04

Lejla
quelle
3
Bitte posten Sie keine Nur-Link-Antworten auf andere Fragen zu Stack Exchange. Fügen Sie stattdessen die wesentlichen Teile der Antwort hier ein und passen Sie die Antwort auf diese spezielle Frage an.
Doppel-Piepton