È "sicuro" in un senso e pericoloso 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 riceve un segfault, dovresti semplicemente esaminare il core dump per vedere cosa è successo. Se ciò non è adeguato, esegui il programma in un debugger e seguilo 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.
Bene. Ti sbagli. Proprio per questo, stderr non bufferizzato per impostazione predefinita.
EDIT:inoltre, come suggerimento generale, prova a utilizzare i punti di interruzione del debugger invece di printf
S. Rende la vita molto più facile.
Un modo possibile potrebbe essere quello di avere un bool dodebug
flag globale e definisci 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
Quindi all'interno del tuo codice, prendine un po'
debugprintf("here i=%d", i);
Certo, potresti, nella macro sopra, fare fprintf
invece... Nota il fflush
e la nuova riga aggiunta al formato.
La disabilitazione del buffering dovrebbe probabilmente essere evitata per motivi di prestazioni.
perché tutti gli stream sono bufferizzati per impostazione predefinita
Sono bufferizzati per motivi di prestazioni. La libreria si sforza di evitare di effettuare la chiamata di sistema perché richiede molto tempo. E non tutti sono bufferizzati per impostazione predefinita. Ad esempio stderr
è di solito senza buffer e stdout
è bufferizzato di riga solo quando fa riferimento a un tty.
allora è sicuro farlo?
È sicuro disabilitare il buffering, ma devo dire che non è la migliore tecnica di debug.