Linuxのassert()
について質問があります。それをカーネルで使用できますか?
いいえの場合、たとえばNULLポインタを入力したくない場合は、通常どのようなテクニックを使用しますか?
対応するカーネルマクロはBUG_ON
およびWARN_ON
。前者は、カーネルをパニックにしてシステムを停止したい場合(つまり、回復不能なエラー)です。後者は、カーネルログに何かを記録する場合に使用します(dmesg
で表示可能)。
@Michaelが言うように、カーネルでは、ユーザー空間からのものを検証し、それを処理するを検証する必要があります。 BUG_ONとWARN_ONは、独自のコードのバグやハードウェアの問題を検出するためのものです。
1つのオプションは、マクロBUG_ON()
を使用することです。メッセージをprintk
してから、カーネルをpanic()
(つまり、クラッシュ)します。
http://kernelnewbies.org/KernelHacking-HOWTO/Debugging_Kernel
もちろん、これは(assert
と同様に)最後の手段のエラー処理戦略としてのみ使用する必要があります...
いいえ。カーネルコアではなくモジュールで作業している場合を除き、カーネル(技術的にはabort()
)がクラッシュしないように最善を尽くす必要があります。 NULLポインタを使用したくない場合は、しないでください。使用する前に確認し、エラーログを生成してください。
致命的なケースを実際に処理している場合、mightが実行したい最も近いことは、 panic()
関数またはBUG_ON
およびWARN_ON
マクロ。実行を中止し、診断メッセージ、スタックトレース、モジュールのリストを生成します。
まあ、nullポインターを逆参照するとoopsが生成されます。これを使用して問題のコードを見つけることができます。ここで、特定の条件をassert()したい場合は、
BUG_ON(condition)
致命的ではないメカニズムはWARN_ONで、カーネルをクラッシュさせることなくバックトレースを生成します。
私はこのマクロを使用し、BUG()を使用していますが、通常デバッグに使用する情報を追加しています。もちろん、必要に応じて編集して、より多くの情報を含めることができます。
#define ASSERT(x) \
do { if (x) break; \
printk(KERN_EMERG "### ASSERTION FAILED %s: %s: %d: %s\n", \
__FILE__, __func__, __LINE__, #x); dump_stack(); BUG(); \
} while (0)
BUG_ON()
が適切なアプローチです。条件が真かどうかをチェックし、マクロBUG()
を呼び出します。
BUG()
が残りを処理する方法は、次の記事で非常によく説明されています。