
MacOS Yosemite (10.10.5). Ich weiß, das ist der Unix/Linux-Abschnitt … aber ich denke, diese Frage passt wahrscheinlich besser hierher als ins MacOS-Land.
Mein Terminal blieb beim Start hängen, bevor eine Eingabeaufforderung angezeigt wurde ... und gleichzeitig stieg die CPU-Auslastung sprunghaft an. Ich kann STRG-C drücken und erhalte dann eine Eingabeaufforderung (vermutlich beendet es eine hängende/laufende .bashrc/.profile/usw.).
Ich habe schnell herausgefunden, dass bestimmte Zeilen in meiner .bashrc das Hängenbleiben verursacht haben. Das ist neu (d. h. ich habe nichts in meiner .bashrc geändert und alles hat vorher einwandfrei funktioniert), also hat sich etwas am System geändert.
Es scheint, dass das Weiterleiten bestimmter längerer Zeichenfolgen zum Hängenbleiben bzw. zu CPU-Spitzen führt.
Ich kann dies reproduzieren, indem ich eine Zeichenfolge weiterleite tr -d '\n'
und sehe, ob sie hängt.
macattack:~ $ openssl rand -base64 93 | tr -d '\n'
eDsz4JqFX/HAVjplNI6WDWwPRp9l9snp6UKp/pLn+GbBvJx0+ZMvSJFS/SuCwjMRRXVXfUvBdkaH1R0UgCr2UOf283MvHVTRusLFEVPcGCIz1t3sFMU/3foRzNWVmattp@macattack:~ $ openssl rand -base64 94 | tr -d '\n'
^C
mattp@macattack:~ $ openssl rand -base64 94 | tr -du '\n'
^C
Scheint, als wäre 93 Zeichen die magische Zahl, bei der tr zu hängen beginnt. openssl hängt nicht (d. h. wenn ich die Pipe entferne, wird tr
alles beendet). Meine ursprüngliche Problemzeile hatte jedoch zufällig eine andere Länge.
mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log;' | tr -d '\n'
^C-bash: echo: write error: Interrupted system call
mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | tr -d '\n'
mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | wc -c
128
mattp@macattack:~ $
Dies ist wahrscheinlich eher ein Pipe-Problem als ein tr
Problem. Ich kann dasselbe Problem mit sed
(Befehl ergibt keinen Sinn ... zeigt nur das Hängen) reproduzieren.
mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log;' | sed 's/\n/ /g'
^C-bash: echo: write error: Interrupted system call
mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | sed 's/\n/ /g'
echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log
mattp@macattack:~
Mir sind die Ideen zur Fehlerbehebung ausgegangen.
Die hängenden Befehle laufen auf einem beliebigen CentOS-Linux-Server einwandfrei. Bis vor Kurzem liefen die Befehle auf MacOS einwandfrei. Ich hatte noch nie ein Problem mit hängenden Pipes. Ich dachte, vielleicht seien es seltsame Zeichen in der Eingabe, die das Problem verursachen ... aber die zufällige OpenSSL-Zeichenfolge zeigt etwas anderes. Die ulimits sind dieselben wie auf einem anderen Mac, der NICHT dasselbe Problem hat.
mattp@macattack:~ $ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 7168
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 709
virtual memory (kbytes, -v) unlimited
dtruss
Die Verwendung tr
scheint beim Aufruf read_nocancel hängen zu bleiben.
Aktualisieren
Fortschritte machen. Habe einen Kommentar zu Hängern und Pipe-Puffergrößen gefunden. Habe ein Testskript von hier geklaut: Wie groß ist der Rohrpuffer?
Beim Ausführen, während das Problem auftritt, wird ein Pipe-Puffer von 128 Bytes angezeigt. Beim Neustart (Problem verschwindet vorübergehend) beträgt der Pipe-Puffer 65536 Bytes. Siehe Testausgabe unten.
Die Frage ist nun, warum/wie „etwas“ die Pipe-Puffergröße im System reduziert.
Mit Problem
$ /bin/bash -c 'for p in {0..18}; do pipe-buffer-test.sh $((2 ** $p)) 0.5; done'
write size: 1; bytes successfully before error: 128
write size: 2; bytes successfully before error: 128
write size: 4; bytes successfully before error: 128
write size: 8; bytes successfully before error: 128
write size: 16; bytes successfully before error: 128
write size: 32; bytes successfully before error: 128
write size: 64; bytes successfully before error: 128
write size: 128; bytes successfully before error: 128
write size: 256; bytes successfully before error: 0
write size: 512; bytes successfully before error: 0
write size: 1024; bytes successfully before error: 0
write size: 2048; bytes successfully before error: 0
write size: 4096; bytes successfully before error: 0
write size: 8192; bytes successfully before error: 0
write size: 16384; bytes successfully before error: 0
write size: 32768; bytes successfully before error: 0
write size: 65536; bytes successfully before error: 0
write size: 131072; bytes successfully before error: 0
write size: 262144; bytes successfully before error: 0
Nach dem Neustart (Problem vorübergehend behoben)
$ /bin/bash -c 'for p in {0..18}; do pipe-buffer-test.sh $((2 ** $p)) 0.5; done'
write size: 1; bytes successfully before error: 65536
write size: 2; bytes successfully before error: 65536
write size: 4; bytes successfully before error: 65536
write size: 8; bytes successfully before error: 65536
write size: 16; bytes successfully before error: 65536
write size: 32; bytes successfully before error: 65536
write size: 64; bytes successfully before error: 65536
write size: 128; bytes successfully before error: 65536
write size: 256; bytes successfully before error: 65536
write size: 512; bytes successfully before error: 65536
write size: 1024; bytes successfully before error: 65536
write size: 2048; bytes successfully before error: 65536
write size: 4096; bytes successfully before error: 65536
write size: 8192; bytes successfully before error: 65536
write size: 16384; bytes successfully before error: 65536
write size: 32768; bytes successfully before error: 65536
write size: 65536; bytes successfully before error: 65536
write size: 131072; bytes successfully before error: 0
write size: 262144; bytes successfully before error: 0
Antwort1
Basierend auf @Barmars Kommentar über undichte Kernel-Puffern habe ich mir die aktuellen Nicht-OS-Kexts angesehen. Mir fiel auf, dass es einen relativ neuen aus einer kürzlichen Installation von BlockBlock gab (https://objective-see.com/products/blockblock.html).
BlockBlock deinstalliert, neu gestartet und das Problem ist nicht erneut aufgetreten. BlockBlock war in diesem Fall also der Übeltäter und ich habe das Problem dem Autor gemeldet.
Dies ist jedoch nicht besonders zufriedenstellend, da ich bei der Ermittlung der Ursache hauptsächlich auf Rate- und Prüfbasis vorgegangen bin und, um ehrlich zu sein, die Grundursache (in Bezug auf das Betriebssystem) nicht wirklich verstehe. Daher bin ich bei der zukünftigen Fehlerbehebung dieser Art von Problemen auch nicht schlauer.
Wenn jemand darauf stößt und genauer erklären kann, was passiert ist, und einen Ansatz zur Fehlerbehebung bereitstellen kann, wäre dies eine viel bessere Antwort als „BlockBlock deinstallieren“.