デバイスドライバのデバッグ手法とデバッグ手法と手法とと使い分けい分け分けけ

Yoichi Yuasa
OSAKA NDS Embedded Linux Cross Forum #9

自己紹介
●

湯浅陽一

●

1999年よりよりLinux kernel開発に参加に参加参加●

MIPSアーキテクチャのいくつかののデバッグ手法とい分けくつかのデバッグ手法とCPUへLinuxkernelを移植移植

本日の内容のデバッグ手法と内容●

デバイスドライバデバッグ手法と手法と●デバイスドライバデバッグ手法と手法とのデバッグ手法と使い分けい分け分けけ

デバイスドライバデバッグ手法と手法と●printk●ftrace●Kprobe●debugfs

printk●●●

利用が簡単が簡単簡単
出力追加に参加はkernel/デバイスドライバモジュールのビルドのデバッグ手法とビルのビルドドが簡単必要
出力レベルのビルドを移植設定可能(コンソールのビルド上に出力するに参加出力する/しない分けを移植選択可能)– KERN_DEBUG、KERN_INFO、KERN_NOTICE...

●

シリアルのビルドコンソールのビルドと組み合わせると出力の保存を             み合わせると出力の保存を             合わせると出力の保存を             わせると出力のデバッグ手法と保存を             を移植外部に依存できるに参加依存を             できるprintk●kernel全体で利用されるので排他制御などもありそれほどで利用が簡単されるのデバッグ手法とで排他制御などもありそれほどなどもありそれほど軽い処理ではないい分け処理ではないではない分け– 動作に影響がある可能性に参加影響がある可能性が簡単ある可能性– 追加すると不具合わせると出力の保存を             現象が発生しなくなるか頻度が下がる可能性が簡単発に参加生しなくなるか頻度が下がる可能性しなくなるか頻度が下がる可能性が簡単下がる可能性が簡単る可能性●

種類がいくつかあるが同じものが簡単い分けくつかあるが簡単同じものじものデバッグ手法と– printk(KERN_INFO “Some information\n”);– pr_info(“Some information\n”);– dev_info(dev, “Some information\n”);ftrace●●OSAKA NDS Embedded Linux Cross Forum#4で詳細に紹介に参加紹介(資料が簡単ダウンロード可能)
Kernel Function Tracer– Linux kernel標準搭載ののデバッグ手法とKernel Tracerのデバッグ手法と一つ– Kernel Function Graph Traceとい分けう階層表示も可能階層表示も可能も可能●●

コンパイルのビルド時プロファイリング用プローブ関数を各関数の先頭にプロファイリング手法と用が簡単プローブ関数を各関数の先頭に関数を各関数の先頭にを移植各関数を各関数の先頭にのデバッグ手法と先頭にに参加
挿入してトレースデータを取得してトレースデータを取得トレースデータを取得を移植取得
利用が簡単するに参加はKernel Function Tracer/Kernel Function Graph
Tracerを移植オンに参加してトレースデータを取得kernelを移植ビルのビルドドしてトレースデータを取得おく必要が簡単ある

Kernel Function Tracer●trace内容– 実行プロセスプロセス(タを取得スク)– 実行プロセスCPU番号– 割込み禁止み合わせると出力の保存を             禁止/許可– スケジュールのビルド要求– ハードIRQ/ソフトIRQ– プリエンプト深ささ– タを取得イムスタを取得ンプ– 関数を各関数の先頭におよび呼び出し関係呼び出し関係び呼び出し関係出し関係

8

Kernel Function Trace表示も可能# tracer: function## entries-in-buffer/entries-written: 44736/44736#P:4##_-----=> irqs-off#/ _----=> need-resched#| / _---=> hardirq/softirq#|| / _--=> preempt-depth#||| /delay#TASK-PID
CPU# ||||TIMESTAMP FUNCTION#| ||||||||
rcar3_create_ga-2030 [000] ...1249.796155: mutex_unlock <-rb_simple_write
rcar3_create_ga-2030 [000] ...1249.796164: __fsnotify_parent <-vfs_write
rcar3_create_ga-2030 [000] ...1249.796165: fsnotify <-vfs_write
rcar3_create_ga-2030 [000] ...1249.796167: __sb_end_write <-vfs_write
rcar3_create_ga-2030 [000] ...1
249.796167: percpu_up_read <-__sb_end_write
rcar3_create_ga-2030 [000] ...1
249.796168: update_fast_ctr <-percpu_up_read9

Kernel Function Graph Trace表示も可能# tracer: function_graph## CPU DURATIONFUNCTION CALLS# |||||||
1)0.720 us| mutex_unlock();
1)
0.120 us
| __fsnotify_parent();1)
0.120 us| fsnotify();
1)| __sb_end_write() {1)|
percpu_up_read() {1)|
update_fast_ctr() {1)0.120 us|preempt_count_add();1)
0.120 us|preempt_count_sub();
1)
2.640 us|}1)
4.320 us|}1)5.520 us
| }10

KprobeOSAKA NDS Embedded Linux Cross Forum#3で詳細に紹介に参加紹介(資料が簡単ダウンロード可能)●ブ関数を各関数の先頭にレイクポイント命令などを利用してなどを移植利用が簡単してトレースデータを取得kernelを移植動的に変更に参加変更●●

指定位置に処理に参加処理ではない(プローブ関数を各関数の先頭に)を移植追加(複数を各関数の先頭に可)●

ほとんどのデバッグ手法と位置に処理に参加プローブ関数を各関数の先頭にを移植追加可能(制限はありはあり)– 割込み禁止み合わせると出力の保存を             処理ではないでも追加可能●

Loadable moduleとしてトレースデータを取得後からプローブを追加可能からプローブを追加可能プローブ関数を各関数の先頭にを移植追加可能●

プローブ関数を各関数の先頭に内に参加てトレースデータを取得kernel内データを取得を移植変更可能●

Kprobes, Jprobes, Return probesのデバッグ手法と3種類がいくつかあるが同じものが簡単ある●

利用が簡単するに参加はKprobesを移植オンに参加してトレースデータを取得kernelを移植ビルのビルドドしてトレースデータを取得おく必要が簡単ある

Kprobesではできない分けこと●

Kprobes機能自体で利用されるので排他制御などもありそれほどへのデバッグ手法とKprobes– 内部に依存できるで利用が簡単してトレースデータを取得い分けるページフォルのビルドト処理ではないとnotifier_call_chainも含むむ●

インライン展開関数を各関数の先頭にへのデバッグ手法とシンボルのビルド名でのプローブ設定でのデバッグ手法とプローブ関数を各関数の先頭に設定●

複数を各関数の先頭にプローブ関数を各関数の先頭に設定間での競合解決でのデバッグ手法と競合わせると出力の保存を             解決– プローブ関数を各関数の先頭に処理ではない中に別プローブ処理が起きる場合などに参加別プローブ処理が起きる場合などプローブ関数を各関数の先頭に処理ではないが簡単起きる場合などきる場合わせると出力の保存を             など

●内部に依存できるでのデバッグ手法とmutexとメモリ確保処理ではない(register時プロファイリング用プローブ関数を各関数の先頭には除くく)●

CPU yield処理ではない(内部に依存できるはpreemption disable)処理ではないKprobes動作に影響がある可能性●

指定アドレス or シンボルのビルドに参加ブ関数を各関数の先頭にレイク命令などを利用してを移植挿入してトレースデータを取得●

ブ関数を各関数の先頭にレイク例外が簡単発に参加生しなくなるか頻度が下がる可能性●

例外ハンドラに参加てトレースデータを取得レジスタを取得を移植保存を             

●例外ハンドラからプローブを追加可能のデバッグ手法と通知ででKprobes処理ではないを移植実行プロセス●

pre_handlerを移植実行プロセス●

シング手法とルのビルドステップ実行プロセスで指定位置に処理を移植実行プロセス●

post_handlerを移植実行プロセス

debugfs●●

kernel開発に参加者がユーザースペースへ大きなデバッグが簡単ユーザースペースへ大きなデバッグきなデバッグ手法とデータを取得を移植渡すための方法を提供すためのデバッグ手法と方法とを移植提供
フルのビルドのデバッグ手法とファイルのビルドアクセス提供– read/write以外に参加seekなど利用が簡単可能●●

ftraceもインタを取得ーフェースに参加利用が簡単
利用が簡単するに参加はDebug Filesystemを移植オンに参加してトレースデータを取得kernelを移植
ビルのビルドドしてトレースデータを取得おく必要が簡単あるdebugfs作に影響がある可能性成
struct dentry *dir, *file;
dir = debugfs_create_dir("foo", NULL);
if (!dir)
return -ENOMEM;
file = debugfs_create_file("bar", 0644, dir, NULL, &bar_fops);
if (!file) {debugfs_remove(dir);
return -ENOMEM;}

debugfs operations
static const struct file_operations bar_fops = {.open = bar_open,.read = bar_read,.write = bar_write,.release = bar_release,.llseek = default_llseek,};

debugfsのデバッグ手法とmount●

mount -t debugfs none /sys/kernel/debug●

通常ははmountされてトレースデータを取得い分けない分けことが簡単多いい分け●

mountするとデバイスドライバで作に影響がある可能性成したディレクトリとファイルのビルドに参加アクセスできるよう階層表示も可能に参加なる

debugfs利用が簡単方法と●●●デバイスドライバに参加てトレースデータを取得デバッグ手法と用が簡単に参加記録したい  したい分け
内容を移植ローカルのビルドバッファなどに参加保存を             してトレースデータを取得おく
メモリ上に出力するに参加記録したい  する場合わせると出力の保存を             はデバイスドライバ側ののデバッグ手法と処理ではないは軽い処理ではないい分け
debugfsのデバッグ手法とread処理ではないに参加てトレースデータを取得ローカルのビルドバッファ上に出力するのデバッグ手法とデバッグ手法とデータを取得を移植ユーザーランドに参加転送して解析してトレースデータを取得解析

デバッグ手法と手法とのデバッグ手法と使い分けい分け分けけ●

開発に参加初期●全体で利用されるので排他制御などもありそれほど的に変更な動作に影響がある可能性を移植解析する場合わせると出力の保存を             

●長期的に変更に参加動作に影響がある可能性を移植解析する場合わせると出力の保存を             開発に参加初期のデバッグ手法とデバッグ手法と●printk一択●

デバイスドライバのデバッグ手法と動作に影響がある可能性が簡単不安定でも利用が簡単できる●●

シリアルのビルドコンソールのビルドを移植利用が簡単すればprintk出力ログ手法とは別プローブ処理が起きる場合などのデバッグ手法とマシンに参加保存を             できるのデバッグ手法とでデバッグ手法と中に別プローブ処理が起きる場合などのデバッグ手法とシステムが簡単どんなに参加
不安定でも問題ないない分け
JTAG対応も無い初期のも無い初期のい分け初期のデバッグ手法とkernel移植もprintkデバッグ手法とで行プロセスう階層表示も可能– 起きる場合など動のデバッグ手法と初期からプローブを追加可能シリアルのビルドコンソールのビルドに参加出力できるearlyconのデバッグ手法と仕組み合わせると出力の保存を             み合わせると出力の保存を             が簡単ある

全体で利用されるので排他制御などもありそれほど的に変更な動作に影響がある可能性を移植解析するデバッグ手法と●昔、関数を各関数の先頭にのデバッグ手法と最初と終わりにわりに参加printkを移植入してトレースデータを取得れてトレースデータを取得おく●

今、まずftrace●

ftraceでデバッグ手法と箇所を絞り込めたらを移植絞り込めたらり込み禁止めたらプローブを追加可能– 関数を各関数の先頭にのデバッグ手法と引数を各関数の先頭にや戻り値を見たい場合は戻り値を見たい場合はり値を見たい場合はを移植見たい場合はたい分け場合わせると出力の保存を             はKprobe– 関数を各関数の先頭に内部に依存できるのデバッグ手法と細に紹介かな処理ではないを移植見たい場合はたい分け場合わせると出力の保存を             はprintk●

kprobeだとアセンブ関数を各関数の先頭にラを移植見たい場合はる必要が簡単あるのデバッグ手法とでprintkが簡単容易長期的に変更に参加動作に影響がある可能性を移植解析するデバッグ手法と●●●デバッグ手法とデータを取得のデバッグ手法と出力先を移植debugfsに参加する
printkとシリアルのビルドコンソールのビルドも可だが簡単printk出力を移植工夫ししない分けと現象が発生しなくなるか頻度が下がる可能性発に参加生しなくなるか頻度が下がる可能性頻度が下がる可能性が簡単下がる可能性が簡単ったりデバッグ手法とデータを取得が簡単膨大きなデバッグに参加なりや戻り値を見たい場合はすい分け
ローカルのビルドバッファに参加デバッグ手法とデータを取得を移植保存を             してトレースデータを取得debugfs
からプローブを追加可能読み出し解析するみ合わせると出力の保存を             出し解析する– ローカルのビルドバッファは固定的に変更に参加確保するなど大きなデバッグきな領域を割りを移植割り当てることも可能てトレースデータを取得ることも可能長期的に変更に参加動作に影響がある可能性を移植解析するデバッグ手法と●まれに参加処理ではない時プロファイリング用プローブ関数を各関数の先頭に間での競合解決が簡単かかる場合わせると出力の保存を             が簡単あるよう階層表示も可能に参加見たい場合はえる場合わせると出力の保存を             – 時プロファイリング用プローブ関数を各関数の先頭に間での競合解決計測処理ではないを移植入してトレースデータを取得れてトレースデータを取得ローカルのビルドバッファに参加計測データを取得などを移植保存を             してトレースデータを取得おきdebugfsからプローブを追加可能読み出し解析するみ合わせると出力の保存を             出してトレースデータを取得検証– 時プロファイリング用プローブ関数を各関数の先頭に間での競合解決計測処理ではないは関数を各関数の先頭に処理ではない時プロファイリング用プローブ関数を各関数の先頭に間での競合解決であればKprobe(Return probe)で入してトレースデータを取得れることも可能

参考●https://www.nds-osk.co.jp/forum/onlcf3.html●

https://www.nds-osk.co.jp/forum/onlcf4.html●

Linux kernel source code
– Documentation/filesystem/debugfs.txt– Documentation/kprobe.txt– Documentation/trace/ftrace.rst