2012-02-11 10 views
7

A volte abbiamo messo alcune stampe di debug nel nostro codice questo modoÈ sicuro disabilitare il buffering con stdout e stderr?

printf("successfully reached at debug-point 1\n"); 

some code is here 

printf("successfully reached at debug-point 2"); 

Here segmantaion fault occur due to some reason 

Ora, in questa condizione solo debug-point1 sarà stampare su di debug-point stdio 2 di stampa è stato scritto per stdio tampone, ma la sua non è arrossato, perché non ha ancora ottenere \n così abbiamo pensa che si scontrano si verificano dopo il debug-point1

a più di venire da questo se disattivo opzione buffer con stdio e stderr flusso come questo senso

setvbuf(stdout, NULL, _IONBF, 0); 
setvbuf(stderr, NULL, _IONBF, 0); 

allora è questo sicuro di farlo?

perché tutti i flussi sono per impostazione predefinita con buffer di linea?

Edit:

Di solito ciò che è la dimensione di tali dal buffer di default assegnato per qualsiasi flusso di file? penso che il suo os dipendesse. mi piacerebbe sapere di Linux?

risposta

3

perché tutto flusso sono di linea di default tamponata

Essi sono tamponati per motivi di prestazioni. La libreria cerca di evitare di effettuare la chiamata di sistema perché impiega molto tempo. E non tutti sono bufferati di default. Ad esempio, stderr è di solito senza buffer e stdout è in modalità line buffer solo quando fa riferimento a una tty.

quindi è sicuro farlo?

È possibile disattivare il buffering in modo sicuro, ma devo dire che non è la migliore tecnica di debug.

2

Uh, bene. Ti stai sbagliando. Proprio per questo motivo, stderr è non bufferizzato per impostazione predefinita.

MODIFICA: Inoltre, come suggerimento generale, provare a utilizzare i punti di interruzione del debugger invece di printf s. Rende la vita molto più facile.

6

Un modo possibile potrebbe essere di avere un flag globale bool dodebug e definire una macro come ad es.

#ifdef NDEBUG 
#define debugprintf(Fmt,...) do{} while(0) 
#else 
#define debugprintf(Fmt,...) do {if (dodebug) {     \ 
    printf("%s:%d " Fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ 
    fflush(stdout); }} while(0) 
#endif 

poi dentro il codice, hanno qualche

debugprintf("here i=%d", i); 

Naturalmente, si potrebbe, nella macro sopra, fare fprintf invece ... Si noti il ​​fflush e il ritorno a capo allegata al formato.

La disabilitazione del buffering dovrebbe essere evitata per motivi di prestazioni.

2

È "sicuro" in un certo senso e insicuro in un altro.Non è sicuro aggiungere debug printfs e, per lo stesso motivo, non è sicuro aggiungere codice per modificare il buffering stdio, nel senso che è un incubo di manutenzione. Quello che stai facendo NON è una buona tecnica di debug. Se il tuo programma ottiene un segfault, dovresti semplicemente esaminare il core dump per vedere cosa è successo. Se ciò non è adeguato, esegui il programma in un debugger e attraversalo per seguire l'azione. Sembra difficile, ma è davvero molto semplice ed è un'abilità importante da avere. Ecco un esempio:

 
$ gcc -o segfault -g segfault.c # compile with -g to get debugging symbols 
$ ulimit -c unlimited    # allow core dumps to be written 
$ ./segfault      # run the program 
Segmentation fault (core dumped) 
$ gdb -q segfault /cores/core.3632 # On linux, the core dump will exist in 
            # whatever directory was current for the 
            # process at the time it crashed. Usually 
            # this is the directory from which you ran 
            # the program. 
Reading symbols for shared libraries .. done 
Reading symbols for shared libraries . done 
Reading symbols for shared libraries .. done 
#0 0x0000000100000f3c in main() at segfault.c:5 
5    return *x;   <--- Oh, my, the segfault occured at line 5 
(gdb) print x      <--- And it's because the program dereferenced 
$1 = (int *) 0x0      ... a NULL pointer. 
2

Se il programma scrive un sacco di uscita, disabilitando il buffer probabilmente farà da qualche parte tra 10 e 1000 volte più lento. Questo di solito è indesiderabile. Se il tuo obiettivo è solo la consistenza dell'output durante il debug, prova ad aggiungere chiamate esplicite allo fflush in cui desideri che l'output venga svuotato anziché disattivare il buffering a livello globale. E preferibilmente non scrivere codice in crash ...