Linuxについて質問がassert()
あります。カーネルで使用できますか?
いいえの場合、たとえば NULL ポインターを入力したくない場合など、通常はどのような手法を使用しますか?
Linuxについて質問がassert()
あります。カーネルで使用できますか?
いいえの場合、たとえば NULL ポインターを入力したくない場合など、通常はどのような手法を使用しますか?
対応するカーネル マクロはBUG_ON
とWARN_ON
です。前者は、カーネルをパニックさせてシステムをダウンさせたい場合 (つまり、回復不能なエラー) に使用します。後者は、何かをカーネル ログに記録したい場合に使用します ( で表示可能dmesg
)。
@Michaelが言うように、カーネルでは、ユーザー空間から来るものをすべて検証し、それが何であれ、それを処理する必要があります。BUG_ON と WARN_ON は、独自のコードのバグやハードウェアの問題をキャッチするためのものです。
abort()
いいえ。カーネル コアではなくモジュールで作業している場合を除き、(技術的には) カーネルがクラッシュしないように最善を尽くす必要があります。NULL ポインターを使用したくない場合は、使用しないでください。使用する前に確認し、そうであればエラーログを作成してください。
致命的なケースを実際に処理している場合に最も近いのは、実行を中止し、診断メッセージ、スタック トレース、およびモジュールのリストを生成するpanic()
関数またはBUG_ON
およびマクロです。WARN_ON
1 つのオプションは、マクロを使用することBUG_ON()
です。printk
メッセージが表示されpanic()
、カーネルがクラッシュします。
http://kernelnewbies.org/KernelHacking-HOWTO/Debugging_Kernel
もちろん、これは最後の手段のエラー処理戦略としてのみ使用する必要があります (のようにassert
)...
まあ、null ポインターを逆参照すると、おっと、問題のあるコードを見つけるために使用できます。ここで、特定の条件を 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()
に処理するかは、次の記事で非常によく説明されています。