GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ist es sicher, die Pufferung mit stdout und stderr zu deaktivieren?

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.


Linux
  1. Trimmen mit Lvm und Dm-Crypt?

  2. Laufendes Skript mit „. “ Und mit „Quelle“?

  3. Wie kann man Stderr und Stdout in verschiedene Dateien umleiten und auch im Terminal anzeigen?

  4. Piping von stdout und stderr innerhalb einer Makefile-Regel

  5. Wiederherstellen von stdout und stderr auf die Standardwerte

So leiten Sie stderr in Bash auf stdout um

Bildschirmsperre mit Xubuntu 20.04 und Lightdm deaktivieren?

Verwirrt über stdin, stdout und stderr?

Echo sowohl an stdout als auch an stderr

Shell:leite stdout nach /dev/null und stderr nach stdout um

bash:leite stderr auf Datei und stdout + stderr auf Bildschirm um