2015-08-05 11 views
10

Ich spiele mit LLDB (debugger) herum und ich habe das folgende Experiment gemacht.Wie PHP-Backtrace auf Live-Skript in lldb Dump dump?

  1. Run PHP-Skript als:

    php -r "sleep(1000);" 
    

    oder:

    echo 'call (void)zif_debug_backtrace()' | lldb -p $(pgrep -fn php) 
    
:

php -r "function r(){sleep(1000);}r();" 
  • auf einer anderen Konsole habe ich direkt zif_debug_backtrace() von lldb genannt

    oben gearbeitet, aber der Prozess mit der folgenden Warnung gestoppt:

    Warning: sleep() expects at most 2 parameters, 1606408648 given in Command line code on line 1 
    Call Stack: 
        0.0016  235152 1. {main}() Command line code:0 
        0.0021  235248 2. sleep(1000) Command line code:1 
    

    Ich bin nicht ganz sicher, warum das Skript zu stoppen hatte und was ich tun muß, um Transparenz zu erreichen (ohne das Skript zu beeinflussen)?

    P.S. Das selbe passiert, wenn zif_debug_print_backtrace() aufgerufen wird und custom_backtrace() es zeigt: Backtrace null function called. Ich benutze xdebug, wenn das etwas ändert.

    Vielleicht muss ich eine andere Funktion wie zend_fetch_debug_backtrace aufrufen (siehe: image dump symtab)? Oder verwenden Sie die richtigen Argumente, wenn ja, welche?

    Ich bin nur an lldb/gdb Lösungen interessiert, um das Backtrace zu drucken.


    ähnlicher Ansatz funktioniert in Ruby, z.B .:

    1. Run: ruby -e 'sleep 1000'.
    2. In einem anderen Terminal: echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby).
  • Antwort

    8

    Sie können interne Funktionen nicht so aufrufen, interne Funktionen erwarten Dinge wie Rahmen, Rückgabewerte und so weiter ... machen Sie es nicht.

    Es gibt eine mit PHP verteilt, darin gibt es eine Funktion mit dem Namen zbacktrace, können Sie das zu lldb portieren.

    Eine andere Sache, die Sie tun könnten, die wahrscheinlich einfacher ist, ist nur die API-Funktion aufrufen, die eine Ablaufverfolgung generiert, aber sie richtig aufrufen.

    Hier ist es für GDB ist (PHP7):

    define ztrace 
        set $var = malloc(sizeof(zval)) 
        call zend_fetch_debug_backtrace($var, 0, 0, 0) 
        call php_var_dump($var, 0) 
        call _zval_ptr_dtor($var, 0, 0) 
        call free($var) 
    end 
    
    document ztrace 
        show a debug backtrace 
    end 
    

    Und für LLDB (PHP7):

    (lldb) expr zval $var; 
    (lldb) expr zend_fetch_debug_backtrace(&$var, 0, 0, 0) 
    (lldb) expr php_var_dump(&$var, 0) 
    (lldb) expr _zval_ptr_dtor(&$var, 0, 0) 
    

    Da Sie gefragt, LLDB für PHP5.6 (no-ZTS):

    (lldb) expr zval *$zp = (zval*) malloc(sizeof(zval)) 
    (lldb) expr zend_fetch_debug_backtrace($zp, 0, 0, 0) 
    (lldb) expr php_var_dump(&$zp, 0) 
    (lldb) expr _zval_ptr_dtor(&$zp, 0, 0) 
    (lldb) expr free($zp) 
    
    1

    spielte ich ein wenig um mit diesem und fand heraus, wie es funktioniert:

    echo 'call (void)zif_debug_print_backtrace(0)' | lldb -p $(pgrep -fn php) 
    

    Für Ihr Beispiel darüber nichts gedruckt wird, weil es keine Backtrace ist. Aber wenn Sie ein Skript wie folgt ausführen:

    php -r "function r(){sleep(1000);}r();" 
    

    Dann wird der LLDB Befehl, um den PHP-Prozess zur Ausgabe verursachen:

    #0 r() called at [Command line code:1] 
    

    Voila. Leider stürzt dies auch das Skript ab.

    Es mit gdb funktioniert, aber:

    echo 'call zif_debug_print_backtrace(0,0,0,0,0)' | gdb -p $(pgrep -fn php) 
    

    beim Abnehmen das Skript läuft weiter. (Getestet auf Debian mit PHP 5.6.14 (DEBUG))

    +1

    Danke für die Antwort. Ich habe getestet und es tötet immer noch den ursprünglichen Prozess, also funktioniert es im Prinzip genauso. Irgendeine Chance, dass es den ursprünglichen Prozess nicht tötet? – kenorb

    +0

    Ich glaube nicht, dass dies vermieden werden kann. PHP ist single threaded. Wenn Sie also einen Befehl extern ausführen möchten, müssen Sie das Skript stoppen. – akirk

    +0

    Es funktioniert in Ruby: 'Ruby -e 'Schlaf 1000'', und' Echo' Aufruf (void) rb_backtrace() '| lldb -p $ (pgrep -nf ruby) '. – kenorb