2009-10-16 14 views
5

Mi piacerebbe essere in grado (ragionevolmente) di impostare arbitrariamente il mio punto di esecuzione nel debugger Perl. Ad esempio, spostandosi immediatamente prima di un if dal corpo del if e impostando una variabile.Come si sposta il punto di istruzione nel debugger Perl?

Rovistare il perldebug (e perldebguts e la pagina POD debugger perl) suggerisce che questo tipo di funzionalità non è supportato o non è documentato.

+3

Sto cercando di immaginare cosa vuoi fare, ma non posso. Io indovino invece. B :: Util o B :: Hooks :: OP :: Check può essere utile; modifica l'optree e imposta l'op successivo su quello che vuoi eseguire; o aggancia un op e lancia il codice quando viene eseguito. Può essere utile anche un runloop personalizzato. Ma fondamentalmente, sei da solo qui; il viaggio nel tempo non è una caratteristica di perl5db. – jrockway

+0

Non viaggio nel tempo. Sto cercando di impostare arbitrariamente il punto del tempo di esecuzione in un determinato luogo, * senza molto riguardo * per la sanità mentale di farlo. –

+0

Il runloop personalizzato suona bene allora. Quello che vuoi fare è molto strano, ed è per questo che non è implementato. – jrockway

risposta

-1

Questo non può essere eseguito con il debugger esistente.

+0

Aspetta un secondo, finora ogni risposta è "no" e io vengo messo giù? Veramente? – nick

+1

La tua risposta non era "no". La tua risposta ci ha solo detto cosa non credi. Non sembra molto sicuro. Quindi in realtà non conosci la risposta e non hai alternative da suggerire. La tua risposta non è stata utile ed è stata quindi degna di un voto negativo. (Pensavo che -1 fosse sufficiente, quindi non ho votato io stesso.) Inoltre, le altre risposte non erano "no". Non era una domanda si/no. Era una domanda "come". Se non sai come, e non sai che è impossibile, quale contributo darai davvero alla tua risposta? –

0

I punti di interruzione possono essere impostati solo sulla prima riga di un'istruzione.

+0

Non sto cercando di impostare un punto di interruzione. Voglio spostare il mio punto di esecuzione - il puntatore di istruzioni della VM Perl. –

+2

Quello che Paolo sta chiedendo non è quello che fanno i breakpoint. Mentre il programma è in pausa, Paul vuole indicare una linea specifica e dire "Riprendi a correre proprio qui, ora. Non eseguire più nulla in anticipo". Un punto di interruzione non consente di saltare il codice o rieseguire il codice appena passato. Lo spostamento dell'IP lo fa. –

+1

Rob ha corretto. –

1

Una soluzione scomoda consisterebbe nell'aggiungere etichette e condizionali goto dichiarazioni nel codice. Ma a seconda di quanto vuoi emulare questa funzionalità, potrebbe valerne la pena.

POINT1: $GOTO="";  # $GOTO is our fake variable that we only set from the debugger 
($a,$b,$c)=(1,2,3); 
POINT2: $GOTO=""; 
if ($a < $b) { 
    goto $GOTO if $GOTO; 
    if ($a > $c) { 
     goto $GOTO if $GOTO; 
     print "foo\n"; 
    } else { 
     goto $GOTO if $GOTO; 
     print "bar\n"; 
    } 
    goto $GOTO if $GOTO; 
} else { 
    goto $GOTO if $GOTO; 
    print "nothing\n"; 
    goto $GOTO if $GOTO; 
} 

Esempio sessione di debug:

$ perl -d debuggoto.pl 

Loading DB routines from perl5db.pl version 1.28 
Editor support available. 

Enter h or `h h' for help, or `man perldebug' for more help. 

main::(debuggoto.pl:1): POINT1: $GOTO="";  # $GOTO is our fake variable that we only set from the debugger 
    DB<1> n 
main::(debuggoto.pl:2): ($a,$b,$c)=(1,2,3); 
    DB<1> 
main::(debuggoto.pl:3): POINT2: $GOTO=""; 
    DB<1> 
main::(debuggoto.pl:4): if ($a < $b) { 
    DB<1> 
main::(debuggoto.pl:5): goto $GOTO if $GOTO; 
    DB<1> 
main::(debuggoto.pl:6): if ($a > $c) { 
    DB<1> 
main::(debuggoto.pl:10):    goto $GOTO if $GOTO; 
    DB<1> 
main::(debuggoto.pl:11):    print "bar\n"; 
    DB<1> 
bar 
main::(debuggoto.pl:13):   goto $GOTO if $GOTO; 
    DB<1> $GOTO="POINT2" 

    DB<2> n 
main::(debuggoto.pl:3): POINT2: $GOTO=""; 
    DB<2> $c=0 

    DB<3> n 
main::(debuggoto.pl:4): if ($a < $b) { 
    DB<3> 
main::(debuggoto.pl:5): goto $GOTO if $GOTO; 
    DB<3> 
main::(debuggoto.pl:6): if ($a > $c) { 
    DB<3> 
main::(debuggoto.pl:7):  goto $GOTO if $GOTO; 
    DB<3> 
main::(debuggoto.pl:8):  print "foo\n"; 
    DB<3> 
foo 
main::(debuggoto.pl:13):   goto $GOTO if $GOTO; 
    DB<3> 
Debugged program terminated. Use q to quit or R to restart, 
    use o inhibit_exit to avoid stopping after program termination, 
    h q, h R or h o to get additional info. 
    DB<3> 
Use `q' to quit or `R' to restart. `h q' for details. 
    DB<3> 

mi chiedo se sarebbe stato possibile costruire un debugger che utilizza questa idea.

+1

Hunh. Non vorrei * manualmente * mandare a fuoco il codice sorgente a quel livello, ma creare una fonte automatizzata per modificare ed eseguire il debugger ... ora c'è un'idea. –

1

Non sono ancora sicuro di cosa esattamente riuscirò a ottenere, ma scommetto che un programma personalizzato che salta le operazioni di cui non ti importa fino a quando non inizierai a occuparti di nuovo potrebbe risolvere il tuo problema.

Un buon runloop per cargo-cult è Runops::Switch. Rimuovi l'istruzione switch e scrivi una funzione che salta ops fino a quando non sei su quello che vuoi eseguire; quindi chiama semplicemente il normale runloop per eseguire effettivamente quell'op.

codice rilevante: http://cpansearch.perl.org/src/RGARCIA/Runops-Switch-0.04/Switch.xs

Questo è tutto handwaving, non ho mai scritto una runloop prima. Anche l'idea di goto in un altro post è buona, ma questo implica scrivere meno codice.

Problemi correlati