GNU/Linux >> Tutoriels Linux >  >> Linux

Est-il sûr de désactiver la mise en mémoire tampon avec stdout et stderr ?

C'est "sûr" dans un sens, et dangereux dans un autre. Il n'est pas sûr d'ajouter des printfs de débogage et, pour la même raison, d'ajouter du code pour modifier la mise en mémoire tampon de stdio, dans le sens où c'est un cauchemar de maintenance. Ce que vous faites n'est PAS une bonne technique de débogage. Si votre programme reçoit une erreur de segmentation, vous devez simplement examiner le vidage mémoire pour voir ce qui s'est passé. Si cela ne suffit pas, exécutez le programme dans un débogueur et parcourez-le pour suivre l'action. Cela semble difficile, mais c'est vraiment très simple et c'est une compétence importante à avoir. Voici un exemple :

$ 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.

Eh bien. Vous vous trompez. Précisément pour cette raison, stderr n'est pas mis en mémoire tampon par défaut.

EDIT :Aussi, comme suggestion générale, essayez d'utiliser les points d'arrêt du débogueur au lieu de printf s. Rend la vie beaucoup plus facile.


Un moyen possible pourrait être d'avoir un bool dodebug drapeau global et définir une macro comme par exemple

#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

Ensuite, dans votre code, ayez quelques

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

Bien sûr, vous pourriez, dans la macro ci-dessus, faire fprintf à la place... Remarquez le fflush et la nouvelle ligne ajoutée au format.

La désactivation de la mise en mémoire tampon devrait probablement être évitée pour des raisons de performances.


pourquoi tous les flux sont mis en mémoire tampon par défaut

Ils sont mis en mémoire tampon pour des raisons de performances. La bibliothèque s'efforce d'éviter de faire l'appel système car cela prend du temps. Et tous ne sont pas mis en mémoire tampon par défaut. Par exemple stderr est habituellement sans tampon et stdout est mis en mémoire tampon uniquement lorsqu'il fait référence à un tty.

alors est-ce sûr de le faire ?

Il est prudent de désactiver la mise en mémoire tampon, mais je dois dire que ce n'est pas la meilleure technique de débogage.


Linux
  1. Désactiver la connexion avec le compte root

  2. Soumission de travaux SLURM avec STDOUT et STDERR écrits dans des fichiers wrt JOB_ID

  3. Configurer le shell pour imprimer Stderr et Stdout dans différentes couleurs ?

  4. Couper avec Lvm et Dm-crypt ?

  5. Exécution du script avec ". » Et avec « source » ?

Comment rediriger stderr vers stdout dans Bash

Désactiver le verrouillage de l'écran avec Xubuntu 20.04 et Lightdm ?

Confus à propos de stdin, stdout et stderr ?

Tuyauterie stdout et stderr à l'intérieur d'une règle Makefile

Restauration de stdout et stderr à la valeur par défaut

Est-il possible que le descripteur de fichier Linux 0 1 2 ne soit pas pour stdin, stdout et stderr ?