GNU/Linux >> Linux Esercitazione >  >> Linux

È sicuro disabilitare il buffering con stdout e stderr?

È "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.


Linux
  1. Disabilita l'accesso con l'account root

  2. Invio di lavori SLURM con STDOUT e STDERR scritti su file con JOB_ID

  3. Configurare la shell per stampare Stderr e Stdout in diversi colori?

  4. Taglia con Lvm e Dm-crypt?

  5. Esecuzione dello script con ". ” E con “fonte”?

Come reindirizzare stderr a stdout in Bash

Disabilitare il blocco dello schermo con Xubuntu 20.04 e Lightdm?

Come può un processo intercettare stdout e stderr di un altro processo su Linux?

È possibile rendere l'output di stdout e stderr di colori diversi in XTerm o Konsole?

Confuso su stdin, stdout e stderr?

Shell:reindirizza stdout a /dev/null e stderr a stdout