Es gibt häufig Fälle, in denen Sie eine Verbindung zu einem Python-Prozess herstellen möchten, der bereits ausgeführt wird, und ein lebendes Objekt bearbeiten möchten.
――Es ist gut, ein Diagramm zu erstellen, dessen Vorverarbeitung lange dauert, aber ich habe vergessen, den Prozess zum Speichern der Daten zu schreiben. ――Das Training des Modells, das mehrere Tage dauert, wurde fehlerfrei abgebrochen. Ich möchte wissen, wo es aufgehört hat. --Debuggen von Python-Skripten, die aus einem riesigen Dienst hervorgegangen sind ――Ich möchte mich an einen Prozess anhängen, der zu einem Zombie oder einer Waise geworden ist
Es mag einfach sein, wenn die IDE in einer lokalen Umgebung funktioniert, aber es wird problematischer, wenn Sie SSH-Verbindungen zu einem GPU-Computer oder dergleichen herstellen.
Dieses Mal werde ich Ihnen zeigen, wie Sie diese Probleme mit einer Kombination aus leichten und tragbaren Werkzeugen lösen können.
- Klein ist schön. ――Die UNIX-Philosophie――
Wählen Sie beispielsweise ein Programm aus, das jede Sekunde die Anzahl der verstrichenen Sekunden anzeigt. Der Punkt ist, dass Sie keine zusätzlichen Bibliotheken importieren oder Snippets im Voraus einfügen müssen.
roop.py
import time
n = 0
while True:
print(n)
time.sleep(1)
n += 1
Lassen Sie uns experimentieren, indem wir einen Prozess erstellen, der absichtlich isoliert ist und kein Steuerterminal hat.
$ nohup python roop.py & ; exit
Nehmen Sie zuerst die Standardeingabe / -ausgabe des Ziels und ersetzen Sie sie durch das vorbereitete Terminal.
# -s Zieldateideskriptor 0,1,Stehlen Sie auch dann, wenn 2 nicht mit TTY verbunden ist.
$ reptyr -s $PID
Fügen Sie als Nächstes den folgenden Debugger-Startcode in das Ziel ein.
$ pyrasite $PID set_pudb.py
Schreiben Sie die Variable n
aus der internen Shell des zuletzt gestarteten Debuggers neu und versuchen Sie, einen Schritt zu machen.
set_pudb.py
import pudb
pudb.set_trace()
Indem ich es mit Reptyr nahm, berührte ich das Protokoll, das in der Vergangenheit verschwunden war. Sie können auch sehen, dass es die Ausführung jeder Schleife und die Änderung von "n = -100" widerspiegelt, indem Sie einen Haltepunkt einfügen.
Hinweis: Unterwegs wird "Kein Quellcode verfügbar" angezeigt. Sie können jedoch "n" drücken, bis Sie von der C-Funktion zurückkehren.
Zum Schluss werde ich ein Skript veröffentlichen, das den Inhalt bisher schön macht.
injector.sh
#!/bin/bash
tmpfile=`mktemp`
PID=`pgrep -a python|fzf|awk '{print $1}'`
[ -z "$PID" ] && exit 1
cat << EOF > $tmpfile
import pudb
pudb.set_trace()
EOF
pyrasite $PID $tmpfile &
reptyr -s $PID
Recommended Posts