web-dev-qa-db-ja.com

Linuxカーネルでのアサーションの使用

Linuxのassert()について質問があります。それをカーネルで使用できますか?

いいえの場合、たとえばNULLポインタを入力したくない場合は、通常どのようなテクニックを使用しますか?

29
macindows

対応するカーネルマクロはBUG_ONおよびWARN_ON。前者は、カーネルをパニックにしてシステムを停止したい場合(つまり、回復不能なエラー)です。後者は、カーネルログに何かを記録する場合に使用します(dmesgで表示可能)。

@Michaelが言うように、カーネルでは、ユーザー空間からのものを検証し、それを処理するを検証する必要があります。 BUG_ONとWARN_ONは、独自のコードのバグやハードウェアの問題を検出するためのものです。

42
Nemo

1つのオプションは、マクロBUG_ON()を使用することです。メッセージをprintkしてから、カーネルをpanic()(つまり、クラッシュ)します。

http://kernelnewbies.org/KernelHacking-HOWTO/Debugging_Kernel

もちろん、これは(assertと同様に)最後の手段のエラー処理戦略としてのみ使用する必要があります...

7
sleske

いいえ。カーネルコアではなくモジュールで作業している場合を除き、カーネル(技術的にはabort())がクラッシュしないように最善を尽くす必要があります。 NULLポインタを使用したくない場合は、しないでください。使用する前に確認し、エラーログを生成してください。

致命的なケースを実際に処理している場合、mightが実行したい最も近いことは、 panic() 関数またはBUG_ONおよびWARN_ONマクロ。実行を中止し、診断メッセージ、スタックトレース、モジュールのリストを生成します。

6

まあ、nullポインターを逆参照するとoopsが生成されます。これを使用して問題のコードを見つけることができます。ここで、特定の条件をassert()したい場合は、

BUG_ON(condition)

致命的ではないメカニズムはWARN_ONで、カーネルをクラッシュさせることなくバックトレースを生成します。

4
shodanex

私はこのマクロを使用し、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)
0
LIUB

BUG_ON()が適切なアプローチです。条件が真かどうかをチェックし、マクロBUG()を呼び出します。

BUG()が残りを処理する方法は、次の記事で非常によく説明されています。

http://kernelnewbies.org/FAQ/BUG

0
krazycoder