GNU/Linux >> Belajar Linux >  >> Linux

Apakah aman untuk menonaktifkan buffering dengan stdout dan stderr?

Itu "aman" di satu sisi, dan tidak aman di sisi lain. Tidak aman untuk menambahkan printfs debug, dan untuk alasan yang sama tidak aman untuk menambahkan kode untuk memodifikasi buffering stdio, dalam arti bahwa ini adalah mimpi buruk pemeliharaan. Apa yang Anda lakukan BUKAN merupakan teknik debugging yang baik. Jika program Anda mengalami segfault, Anda cukup memeriksa core dump untuk melihat apa yang terjadi. Jika itu tidak memadai, jalankan program dalam debugger dan lewati untuk mengikuti tindakan. Kedengarannya sulit, tetapi sebenarnya sangat sederhana dan merupakan keterampilan yang penting untuk dimiliki. Berikut contohnya:

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

Baiklah. Anda salah. Justru karena alasan ini, stderr adalah tidak buffer secara default.

EDIT:Selain itu, sebagai saran umum, coba gunakan breakpoint debugger alih-alih printf s. Membuat hidup jauh lebih mudah.


Cara yang mungkin adalah dengan memiliki bool dodebug bendera global dan tentukan makro seperti mis.

#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

Kemudian di dalam kode Anda, miliki beberapa

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

Tentu saja, dalam makro di atas, Anda dapat melakukan fprintf sebagai gantinya... Perhatikan fflush dan baris baru yang ditambahkan ke format.

Menonaktifkan buffering mungkin sebaiknya dihindari karena alasan performa.


mengapa semua aliran secara default disangga baris

Mereka disangga karena alasan kinerja. Perpustakaan berusaha keras untuk menghindari panggilan sistem karena butuh waktu lama. Dan tidak semuanya di-buffer secara default. Misalnya stderr adalah biasanya tanpa buffer dan stdout di-buffer baris hanya jika merujuk ke tty.

lalu apakah aman untuk melakukan ini?

Menonaktifkan buffering aman, tetapi saya harus mengatakan bahwa ini bukan teknik debugging terbaik.


Linux
  1. Nonaktifkan masuk dengan akun root

  2. Konfigurasikan Shell Untuk Mencetak Stderr Dan Stdout Dalam Berbagai Warna?

  3. Pangkas Dengan Lvm Dan Dm-crypt?

  1. Tampilkan Hanya Stderr Di Layar Tetapi Tulis Stdout Dan Stderr Ke File?

  2. Gema ke stdout dan stderr

  3. Piping stdout dan stderr di dalam aturan Makefile

  1. Mengirimkan pekerjaan SLURM dengan STDOUT &STDERR yang ditulis ke file dengan JOB_ID

  2. Shell:redirect stdout ke /dev/null dan stderr ke stdout

  3. Menangkap STDERR dan STDOUT ke file menggunakan tee