La stampa su console / stdout è una buona strategia di debug?

8

Diciamo che abbiamo una funzione come questa:

public void myStart()
{
    for (int i = 0; i<10; i++) myFunction(i); 
}


private int myFunction(int a)
{

    a = foo(a);
    a = bar(a);
    return a; 
}

private int foo(int a)
{
    //do something here

    //something gnarly here

    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Ora, per qualsiasi motivo, il nostro codice non funziona. Forse sta generando un errore, forse sta restituendo il valore sbagliato, forse è rimasto bloccato in un ciclo infinito.

La prima cosa che ogni programmatore del primo anno è stampare su console / std out (avendo imparato come stampare Hello World prima di imparare a utilizzare un debugger).

Ad esempio per eseguire il debug di questo codice, potrebbero eseguire le seguenti operazioni:

private int myFunction(int a)
{
    print("before foo: a=" + a); 
    a = foo(a);
    print("before bar: a=" + a);
    a = bar(a);

    return a; 
}

private int foo(int a)
{
    //do something here
    print ("foo step1: a=" + a); 

    //something gnarly here
    print ("foo step2: a=" + a + " someOtherValue="+ someOtherValue + " array.length= " + someArray.length()); 
    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Ora eseguono il codice, ottengono una grande console stampata, che possono passare per tracciare dove le cose vanno male.

Un'alternativa, naturalmente, è quella di impostare punti di interruzione e scorrere il codice in ogni punto.

Uno dei principali vantaggi della stampa su console è che lo sviluppatore può vedere il flusso dei valori in un colpo solo, senza dover fare clic sui passaggi ecc.

Ma lo svantaggio è che il tuo codice è pieno di tutte queste dichiarazioni di stampa che devono essere rimosse.

(È possibile forse dire al debugger di stampare solo determinati valori in un log ?, i punti di interruzione possono quindi essere facilmente aggiunti o rimossi senza realmente modificare il codice.)

Uso ancora la stampa da console come metodo di debug primario, mi chiedo quanto sia comune / efficace rispetto a qualcos'altro là fuori.

    
posta dwjohnston 23.01.2014 - 23:09
fonte

3 risposte

21

Le istruzioni di stampa e il debugger non si escludono a vicenda. Sono solo diversi strumenti disponibili per individuare / identificare i bug. C'è chi pretende di non toccare mai un debugger e c'è chi non ha una singola istruzione di logging / print in nessuna parte del codice che scrive. Il mio consiglio è di non voler essere in uno di questi gruppi.

Impara invece a usare la registrazione e impara a usare un debugger. Con l'esperienza (quasi senza pensarci su) scegli lo strumento giusto e svolgi il lavoro in modo accurato ed efficiente. A volte, senza esperienza, ne sceglierai uno sull'altro, e forse ti ci vorrà un po 'di più a curiosare tra le variabili o a passare al setaccio i file di registro, ma questo è tutto parte del processo di apprendimento.

Quindi, per rispondere alla tua domanda specifica. Sì. L'uso di stampe per tracciare l'esecuzione è una strategia di debug valida e ampiamente utilizzata. Tuttavia ...

Invece di usare le istruzioni di stampa, considera l'utilizzo di un framework di registrazione. I framework di registrazione hanno un concetto di livelli di registrazione in modo da poter aggiungere un intero gruppo di messaggi di registro, ma scegliere un livello per ciascuno. Quando la tua applicazione è in esecuzione in condizioni normali, il tuo livello sarebbe ERRORE o AVVISO in modo che vengano segnalati solo gli elementi importanti. Tuttavia, quando si traccia il codice e si ha bisogno di capire il flusso di esecuzione, è possibile modificare il logger in INFO o DEBUG e ora tutte quelle istruzioni di "stampa" già presenti nel codice segnaleranno ulteriori informazioni.

Utilizzo di un framework di registrazione ...

  1. non avrai bisogno di cancellare tutte le stampe dopo aver finito.
  2. le impronte lasciate nel codice, possono aiutare te o qualsiasi altro sviluppatore a eseguire il debug dello stesso codice in futuro
  3. sarai in grado di eseguire il debug di questo codice nel campo senza doverlo ricostruire ogni volta solo per aggiungere le stampe che hai eliminato.
  4. sarai in grado di reindirizzare i messaggi di registrazione ovunque tu voglia, non solo una console. Potrebbero andare in un file, syslog, DB, socket ... ecc.

Aggiornamento: Ho appena notato che alla fine stavi chiedendo, "È possibile forse dire al debugger di stampare solo determinati valori in un log". A seconda del debugger che usi. Molti debugger moderni consentono di definire un'azione da richiamare quando viene colpito un punto di interruzione. In alcuni (l'ho fatto in VS e WinDbg), è possibile specificare "print this and resume". Visual Studio li chiama "tracepoints" anziché "breakpoints"

    
risposta data 23.01.2014 - 23:52
fonte
3

Loging / printing e debugger sono tecniche complementari che hanno punti di forza e punti deboli diversi: è meglio usare entrambi. Ma nel complesso, direi che i debugger sono lo strumento migliore nella maggior parte dei casi e dovrebbero essere usati prima, con la registrazione / stampa utilizzata solo per le cose in cui è meglio.

Vantaggi dei debugger:

  • È possibile controllare l'intero stato del programma, non solo i valori che si pensava di stampare in anticipo. Ciò può massivamente accelerare il processo di debug riducendo il ciclo di feedback a meno di un secondo. Particolarmente importante quando ci vuole del tempo per raggiungere il bug.
  • Puoi vedere da dove provengono le chiamate e persino esaminare i valori sulla traccia dello stack.
  • Puoi (in una certa misura dipende dal linguaggio / platfrom) il codice di debug che non puoi modificare facilmente perché hai solo il codice binario o byte compilato.

Vantaggi della registrazione / stampa:

  • Non richiede una build o configurazione di debug speciale. Funziona sempre.
  • Può essere usato per analizzare errori che sono difficili da riprodurre e si verificano raramente
  • Può essere usato per analizzare gli errori dipendenti dal tempo in cui la pausa causata da un debugger può facilmente far scomparire il bug.
  • Fornisce informazioni permanenti che puoi analizzare a tuo piacimento. Puoi saltare avanti e indietro tra l'output in diversi punti nel flusso del programma.
risposta data 24.01.2014 - 13:32
fonte
1

Stampare sullo standard output in un modo può essere una buona strategia per eseguire il debug del codice, ad esempio

  • uso molte dichiarazioni di stampa per vedere cosa succede nei diversi livelli del mio codice, specialmente se non capisco perfettamente l'errore

  • o forse l'errore non ha informazioni dettagliate che potrebbero indirizzarmi verso quale parte del codice sta causando esattamente il problema.

Tuttavia è necessario abituarsi agli strumenti di debug, ci sono molti là fuori a seconda della lingua o della piattaforma che usi.

Anche un altro metodo sta registrando, registro gli errori tutto il tempo quando lavoro su applicazioni Android, anche con gestione delle eccezioni, si può facilmente registrare una traccia di stack o un messaggio di errore dell'eccezione che viene sollevata.

    
risposta data 24.01.2014 - 02:15
fonte

Leggi altre domande sui tag