GNU/Linux >> Linux の 問題 >  >> Linux

stdout と stderr でバッファリングを無効にしても安全ですか?

ある意味では「安全」であり、別の意味では安全ではありません。 debug printfs を追加するのは安全ではありません。同じ理由で、stdio バッファリングを変更するコードを追加するのも、メンテナンスの悪夢であるという意味で安全ではありません。あなたがしていることは、良いデバッグ手法ではありません。プログラムでセグメンテーション違反が発生した場合は、コア ダンプを調べて何が起こったのかを確認する必要があります。これで十分でない場合は、プログラムをデバッガーで実行し、ステップ実行してアクションに従います。難しそうに見えますが、実はとてもシンプルで重要なスキルです。サンプルは次のとおりです:

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

そうですね。 あなたは間違っています まさにこの理由で、stderr ではない デフォルトでバッファリングされます。

編集:また、一般的な提案として、printf の代わりにデバッガー ブレークポイントを使用してみてください 秒。生活がずっと楽になります。


考えられる方法は、bool dodebug を持つことです。 グローバル フラグを作成し、たとえば

のようなマクロを定義します
#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

次に、コード内にいくつか

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

もちろん、上記のマクロで fprintf を実行できます。 代わりに... fflush に注意してください およびフォーマットに追加された改行。

パフォーマンス上の理由から、バッファリングを無効にすることはおそらく避けるべきです。


<ブロック引用>

すべてのストリームがデフォルトで行バッファリングされる理由

これらはパフォーマンス上の理由からバッファリングされます。ライブラリは、時間がかかるため、システム コールの実行を回避しようとします。また、それらのすべてがデフォルトでバッファリングされるわけではありません。例えば ​​stderr 通常 バッファなしおよび stdout tty を参照する場合のみ行バッファリングされます。

<ブロック引用>

では、これを行っても安全ですか?

バッファリングを無効にしても安全ですが、最適なデバッグ手法ではないと言わざるを得ません.


Linux
  1. Makefile ルール内の stdout と stderr のパイピング

  2. stdout と stderr をデフォルト値に戻す

  3. Linuxファイル記述子0 1 2がstdin、stdout、およびstderrではない可能性はありますか?

  1. StderrとStdoutを異なる色で印刷するようにシェルを構成しますか?

  2. 「でスクリプトを実行します。 」と「ソース」で?

  3. teeを使用してSTDERRおよびSTDOUTをファイルにキャプチャする

  1. StderrとStdoutを別のファイルにリダイレクトし、ターミナルに表示するにはどうすればよいですか?

  2. Linuxでプロセスが別のプロセスのstdoutとstderrを傍受するにはどうすればよいですか?

  3. XTerm または Konsole で stdout と stderr の出力を異なる色にすることはできますか?