ある意味では「安全」であり、別の意味では安全ではありません。 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 を参照する場合のみ行バッファリングされます。
では、これを行っても安全ですか?
バッファリングを無効にしても安全ですが、最適なデバッグ手法ではないと言わざるを得ません.