GNU/Linux >> Tutoriales Linux >  >> Linux

¿Es seguro deshabilitar el almacenamiento en búfer con stdout y stderr?

Es "seguro" en un sentido e inseguro en otro. No es seguro agregar printfs de depuración y, por la misma razón, no es seguro agregar código para modificar el almacenamiento en búfer de stdio, en el sentido de que es una pesadilla de mantenimiento. Lo que estás haciendo NO es una buena técnica de depuración. Si su programa obtiene un error de segmento, simplemente debe examinar el volcado del núcleo para ver qué sucedió. Si eso no es adecuado, ejecute el programa en un depurador y revíselo para seguir la acción. Esto suena difícil, pero en realidad es muy simple y es una habilidad importante. Aquí hay una muestra:

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

bueno Estás equivocado. Precisamente por eso, stderr es no almacenado en búfer de forma predeterminada.

EDITAR:Además, como sugerencia general, intente usar puntos de interrupción del depurador en lugar de printf s. Hace la vida mucho más fácil.


Una forma posible podría ser tener un bool dodebug bandera global y definir una macro como, por ejemplo,

#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

Luego, dentro de su código, tenga algunos

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

Por supuesto, podría, en la macro de arriba, hacer fprintf en cambio... Observe el fflush y la nueva línea adjunta al formato.

Probablemente debería evitarse deshabilitar el almacenamiento en búfer por razones de rendimiento.


por qué todas las secuencias tienen un búfer de línea predeterminado

Se almacenan en búfer por motivos de rendimiento. La biblioteca se esfuerza por evitar realizar la llamada al sistema porque lleva mucho tiempo. Y no todos ellos están almacenados en búfer de forma predeterminada. Por ejemplo stderr es normalmente sin búfer y stdout tiene búfer de línea solo cuando se refiere a un tty.

entonces, ¿es seguro hacer esto?

Es seguro deshabilitar el almacenamiento en búfer, pero debo decir que no es la mejor técnica de depuración.


Linux
  1. Deshabilitar el inicio de sesión con la cuenta raíz

  2. Envío de trabajos SLURM con STDOUT y STDERR escritos en archivos wrt JOB_ID

  3. ¿Configurar el Shell para imprimir Stderr y Stdout en diferentes colores?

  4. ¿Recortar con Lvm y Dm-crypt?

  5. Ejecutar secuencia de comandos con ". ¿Y con “fuente”?

Cómo redirigir stderr a stdout en Bash

¿Deshabilitar el bloqueo de pantalla con Xubuntu 20.04 y Lightdm?

¿Confundido acerca de stdin, stdout y stderr?

Canalización de stdout y stderr dentro de una regla Makefile

bash:redirigir stderr al archivo y stdout + stderr a la pantalla

Captura de STDERR y STDOUT para archivar usando tee