Es ist in einem Sinne „sicher“ und in einem anderen unsicher. Es ist unsicher, debug printfs hinzuzufügen, und aus demselben Grund unsicher, Code hinzuzufügen, um die stdio-Pufferung zu ändern, in dem Sinne, dass es ein Albtraum für die Wartung ist. Was Sie tun, ist KEINE gute Debugging-Technik. Wenn Ihr Programm einen Segfault erhält, sollten Sie einfach den Core-Dump untersuchen, um zu sehen, was passiert ist. Wenn dies nicht ausreicht, führen Sie das Programm in einem Debugger aus und gehen Sie es schrittweise durch, um die Aktion zu verfolgen. Das klingt schwierig, ist aber wirklich sehr einfach und eine wichtige Fähigkeit, die man haben muss. Hier ist ein Beispiel:
$ 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.
Äh, gut. Du liegst falsch. Genau aus diesem Grund, stderr ist nicht standardmäßig gepuffert.
BEARBEITEN:Als allgemeinen Vorschlag versuchen Sie auch, Debugger-Haltepunkte anstelle von printf
zu verwenden s. Macht das Leben viel einfacher.
Ein möglicher Weg könnte sein, einen bool dodebug
zu haben globales Flag und definiere ein Makro wie z.B.
#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
Dann haben Sie in Ihrem Code etwas
debugprintf("here i=%d", i);
Natürlich könnten Sie im obigen Makro fprintf
ausführen stattdessen... Beachten Sie die fflush
und dem angehängten Zeilenumbruch an das Format.
Das Deaktivieren der Pufferung sollte wahrscheinlich aus Leistungsgründen vermieden werden.
warum alle Streams standardmäßig zeilengepuffert sind
Sie werden aus Performancegründen gepuffert. Die Bibliothek bemüht sich sehr, den Systemaufruf zu vermeiden, da er lange dauert. Und nicht alle sind standardmäßig gepuffert. Zum Beispiel stderr
ist normalerweise ungepuffert und stdout
wird nur dann zeilengepuffert, wenn es sich auf ein tty bezieht.
ist das dann sicher?
Es ist sicher, das Puffern zu deaktivieren, aber ich muss sagen, dass es nicht die beste Debugging-Technik ist.