2012-02-11 10 views
7

A veces ponemos algunas impresiones de depuración en nuestro código de esta manera¿Es seguro deshabilitar el almacenamiento en búfer con stdout y 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 

Ahora, en esta condición sólo de depuración-point1 será imprimir en stdio depuración de punto 2 de impresión fue escrito para stdio búfer pero no es enrojecida porque didnt obtener \n por lo que cree que se producen después de accidente de depuración-point1

a venir más de esta opción si el búfer desactivo con stdio y stderr como corriente de esta manera

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

es éste seguro para hacer esto?

¿por qué todas las transmisiones están predeterminadas por línea?

Editar:

Solemos cuál es el tamaño de los mismos por búfer predeterminado asignado para cualquier secuencia de archivo? creo que su OS dependía Me gustaría saber sobre Linux?

Respuesta

3

por qué todos los flujos son por línea por defecto tamponada

Ellos se almacenan temporalmente por razones de rendimiento. La biblioteca intenta evitar la llamada al sistema porque lleva mucho tiempo. Y no todos están almacenados de forma predeterminada. Por ejemplo, stderr es generalmente sin búfer y stdout está búfer de línea solo cuando se refiere a un tty.

¿entonces esto es seguro para hacer esto?

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

2

Uh, bueno. Estás equivocado. Precisamente por este motivo, stderr es no almacenado de manera predeterminada.

EDIT: Además, como sugerencia general, intente utilizar los puntos de corte del depurador en lugar de printf s. Hace la vida mucho más fácil.

6

Una posible forma podría ser tener un indicador global bool dodebug 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 

A continuación, dentro de su código, tienen algún

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

Por supuesto, usted puede, en la macro anterior, hacer fprintf lugar ... Note la fflush y el salto de línea anexa al formato.

Probablemente deba evitarse el deshabilitar el almacenamiento en búfer por motivos de rendimiento.

2

Es "seguro" en un sentido, y no es seguro en otro.No es seguro agregar errores de depuración y, por la misma razón, no es seguro agregar código para modificar el almacenamiento intermedio 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 una segfault, simplemente debe examinar el volcado del núcleo para ver qué sucedió. Si eso no es adecuado, ejecute el programa en un depurador y páselo para seguir la acción. Esto suena difícil, pero es realmente muy simple y es una habilidad importante de tener. He aquí 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. 
2

Si su programa escribe una gran cantidad de la producción, la desactivación de amortiguación es probable que sea en algún lugar entre 10 y 1000 veces más lento. Esto generalmente no es deseable. Si su objetivo es solo la consistencia del resultado al realizar la depuración, intente agregar llamadas explícitas fflush donde desee que se elimine la salida en lugar de desactivar el almacenamiento en búfer de forma global. Y preferiblemente no escriba el código de bloqueo ...

Cuestiones relacionadas