コードをきれいにしましょう:Linuxドライバーでデバッグメッセージを出力するニュアンス

多くの人が知っているように、ドライバーに関するLinuxでのデバッグメッセージの出力は、マクロと関数のいくつかのサブセットによって実現されます。 すべてのアナログが互換性があり、一見論理的に見えるように機能するわけではありません。 これは、この短いメモで説明します。

まず、カーネルの内部APIで提供されている既知のメッセージ出力関数を見てみましょう。

基本機能
printk(LEVEL "message\n"); 

それからマクロのセットがあります(最も一般的に使用されます):
 pr_err("message\n"); pr_warn("message\n"); pr_info("message\n"); pr_debug("message\n"); 

などなど。

ドライバーの場合、対応する出力レベルを持つdev_*プレフィックスを持つ一連の関数が使用され、 netdev_*プレフィックスを持つネットワークカードドライバー用に個別に使用されます。 一般に、一般的なルールは、カーネルサブシステムまたはドライバーが、メッセージ出力レベルのサフィックスとともに独自のプレフィックスを使用することです。

それらはすべてpr_*printk(LEVEL …) pr_*完全な類似物であり、 pr_debug()dev_dbg()を除いてpr_debug() dev_*およびnetdev_*場合と同じです。

それでは、どのような条件下で異なるオプションでメッセージが表示されるのでしょうか?

printk(KERN_DEBUG "message\n")

およびpr_debug("message\n")

dev_dbg()およびnetdev_dbg()についても同じことがdev_dbg()ます。

さらに、有用なCONFIG_DYNAMIC_DEBUGオプションにも特別な注意を払う必要があります。 すべてのダイナミズムについては、カーネルロード自体で機能し始めるわけではないため、すべてのモジュールがそれに依存できるわけではありません。

製品バージョンで使用するものに関する別のジレンマ: CONFIG_DYNAMIC_DEBUG または標準出力、型条件の接頭辞:
 #define mydbg(dev, format, arg…) \ do { \ if (mycooldriver->debug > 0) \ dev_printk(KERN_DEBUG, dev, format, ##arg); \ } while (0) 

そのため、ここでの違いは、カーネルソースコードの詳細を掘り下げた場合、つまり最初のケースでは出力がノーオペレーション(空の操作)に等しくなり、2番目のケースではそうではないことは明らかです。 したがって、タイムクリティカルなモジュールに上記のコードを入力しないでください。 さらに、最適なオプションはそのような場所でトレースポイントを使用することですが、将来的にはこのことについていつか話します。

print_hex_dump_bytes()関数print_hex_dump_bytes()最近Dynamic Debugからサポートを得たというボーナスを追加します。

Source: https://habr.com/ru/post/J262791/


All Articles