Erhalte einen Stack-Trace eines PHP-Skripts

8

Ich habe ein Skript, das jede Nacht von einem Cron-Job läuft. In letzter Zeit hat es nach einigen Minuten völlig eingefroren angefangen, und ich kann nicht verstehen warum. Wenn dies Java wäre, könnte ich einfach kill -3 PID ausführen und es würde einen Thread-Dump in stdout ausgeben. Gibt es eine Entsprechung in PHP, wo ich einen Dump der aktuellen Stack-Trace (und idealerweise Speicher-Info) auf einem laufenden PHP-Skript erhalten könnte?

    
Cory Gagliardi 10.01.2013, 15:52
quelle

5 Antworten

7

Das Beste, was Sie tun können, ist, PHP selbst mit --enable-debug während configure zu kompilieren. Wenn der Prozess dann noch nicht reagiert, können Sie mithilfe von gdb und einigen Makros einen Stacktrace auf PHP-Ebene mithilfe der folgenden Schritte erstellen:

%Vor%

Und dann debug im Voraus: -)

Beachten Sie, dass dafür eine PHP-Binärdatei mit Symbolinformationen erforderlich ist, --enable-debug stellt dies sicher.

    
johannes 10.01.2013, 16:04
quelle
2

Ja. Sie können ein Backtrace mit debug_backtrace erhalten. Möglicherweise benötigen Sie auch memory_get_usage .

    
Thomas Kekeisen 10.01.2013 15:56
quelle
2

Ich habe bemerkt, dass es eine mögliche Lösung gibt, die pcntl_signal verwendet. Ich habe es selbst nicht versucht, Sie können hier einen Beispielcode finden:

Ссылка

%Vor%     
romaninsh 01.07.2014 15:53
quelle
2

Sofern Sie gdb- und debugging-Symbole für PHP installiert haben, können Sie eine vollständige PHP-Rückverfolgung erhalten.

Die Methode zum Installieren von Debugging-Symbolen kann von Distribution zu Distribution variieren. Zum Beispiel lief ich auf Amazon Linux rpm -qa | grep php56-common und übergab das Ergebnis an debuginfo-install . Beachten Sie, dass das Installieren von Debugging-Symbolen mit dem Standard-Paket-Manager möglicherweise nicht das gewünschte Ergebnis bringt - bei Amazon Linux habe ich Debugging-Symbole für eine andere PHP-Version erhalten, wenn yum install php56-debuginfo und gdb das nicht taten.

Wenn Sie Ihren Computer so konfiguriert haben, dass Core-Dumps erstellt werden , brauchen Sie den Prozess nicht einmal laufen, um ein Backtrace zu bekommen. Sie können kill -ABRT $pid und den Core Dump später überprüfen.

Sie können dann einen laufenden Prozess mit gdb -p $pid oder einen Core-Dump mit gdb /usr/bin/php $path_to_core_dump debuggen.

Wenn Sie bt eingeben, erhalten Sie einen C-Stack-Trace. Dies wird manchmal genug sein, um Ihnen einen Hinweis darauf zu geben, was falsch sein könnte. Stellen Sie sicher, dass die Debugsymbole korrekt installiert sind. bt sollte auf Dateinamen und Zeilennummern im PHP-Quellcode zeigen.

Probieren Sie jetzt p executor_globals.current_execute_data . Es sollte etwas wie = (struct _zend_execute_data *) 0x7f3a9bcb12d0 ausgeben. Wenn dies der Fall ist, kann gdb die Interna von PHP überprüfen.

Mit ein wenig Python-Skripting können Sie ein komplettes PHP-Backtrace erstellen. Geben Sie python-interactive ein und fügen Sie dann dieses kleine Skript ein:

%Vor%

Beachten Sie, dass diese Methode stark von den Interna von PHP abhängt, daher funktioniert sie bei früheren oder späteren Versionen möglicherweise nicht. Ich habe das mit PHP 5.6.14 gemacht. Der Vorteil dieser Methode ist, dass sie sowohl für laufende Prozesse als auch für Core-Dumps funktioniert. Außerdem müssen Sie PHP nicht neu kompilieren oder Ihr PHP-Skript neu starten. Sie können sogar gdb und Debugging-Symbole installieren nachdem Sie einen hängenden Prozess entdecken.

    
sqaxomonophonen 18.01.2016 11:40
quelle
1

Ein PHP-Skript sollte einen Timeout haben, wenn es die maximale Laufzeit überschreitet. Sicher würde das das Problem für dich lösen; warte nur darauf, dass es kaputtgeht, und da ist deine Stack-Spur.

Ich denke, es ist möglich, dass Sie etwas in Ihrem Code (oder php.ini) haben, das die maximale Laufzeit auf Null setzt, um das Brechen zu stoppen. Wenn Sie das haben, dann entfernen Sie es (oder setzen Sie es auf ein sehr großes Timeout, wenn der Standard wirklich zu klein ist).

Sie können auch versuchen, es mit xDebug oder einem ähnlichen Tool auszuführen, das Ihnen einen Profiler-Trace liefert, der Ihnen einen Aufrufbaum des Programms gibt, und Ihnen auch erlaubt, den Code in Ihrer IDE durchzugehen Sie können genau sehen, was passiert. Wenn dort eine Endlosschleife ist, sollten Sie in der Lage sein, sie ziemlich schnell zu identifizieren.

    
SDC 10.01.2013 15:58
quelle

Tags und Links