SGI KDBを使ったカーネルデバッグスレ
■ このスレッドは過去ログ倉庫に格納されています
1名無しさん@お腹いっぱい。
NGNGカーネルデバッグの話はここで存分にどうぞ
2名無しさん@お腹いっぱい。
NGNGage
31
NGNG1.http://oss.sgi.com/projects/kdb/ より、使用しているカーネルにあった
パッチをダウンロードし、カーネルソースにパッチを当てる。
2.make xconfigなりのカーネルコンフィグアプリを起動。
Kernel Hackingの項目が追加されているので、
"Build-in Kernel Debugger support"をyにする。ついでに
"compile the kernel with frame pointers"もyにしたほうがスタック
トレースがとりやすくなる。
3.カーネル再構築。
4.lilo.confに以下のように"kdb=on"のカーネルブートオプションをつける。
>image=/boot/vmlinuz-2.4.4-test
> label=test
> read-only
> root=/dev/hda2
> append="kdb=on"
5.liloを実行し、ブート情報を書き込み、ブートオプションをつけたカーネルから
ブート。
6.Pauseキーを押すとカーネルデバッガに入る。"g"コマンドで再開。
パッチをダウンロードし、カーネルソースにパッチを当てる。
2.make xconfigなりのカーネルコンフィグアプリを起動。
Kernel Hackingの項目が追加されているので、
"Build-in Kernel Debugger support"をyにする。ついでに
"compile the kernel with frame pointers"もyにしたほうがスタック
トレースがとりやすくなる。
3.カーネル再構築。
4.lilo.confに以下のように"kdb=on"のカーネルブートオプションをつける。
>image=/boot/vmlinuz-2.4.4-test
> label=test
> read-only
> root=/dev/hda2
> append="kdb=on"
5.liloを実行し、ブート情報を書き込み、ブートオプションをつけたカーネルから
ブート。
6.Pauseキーを押すとカーネルデバッガに入る。"g"コマンドで再開。
4別のスレの1
NGNGリモートの場合。
1.同じくクロスシリアルケーブルを用意しターゲットとターミナルを繋ぐ。
2.ターミナルマシン上で適当なターミナルプログラムを起動する。
3.liloのappendコマンドを以下のように変更。
append="kdb=on console=ttyS0,38400"
これで、シリアルコンソールにデバッガの出力が表示される。
停止はターゲットでPauseキーか、ターミナルでCTRL-A。
4.ただこれだと、ブートメッセージがターミナルにしか表示されなく
なるので、以下のようにしたほうがいいかも。
append="kdb=on console=ttyS0,38400 console=tty0"
これで、ブートメッセージは両方に出力される。そのかわりCTRL-Aでの
Breakinはできなくなる。
Initは最後に指定されたコンソールに出力するらしく、
append="kdb=on console=tty0 console=ttyS0,38400"
のようにしてしまうとInitの出力がターミナルだけになってしまうため
不便。
1.同じくクロスシリアルケーブルを用意しターゲットとターミナルを繋ぐ。
2.ターミナルマシン上で適当なターミナルプログラムを起動する。
3.liloのappendコマンドを以下のように変更。
append="kdb=on console=ttyS0,38400"
これで、シリアルコンソールにデバッガの出力が表示される。
停止はターゲットでPauseキーか、ターミナルでCTRL-A。
4.ただこれだと、ブートメッセージがターミナルにしか表示されなく
なるので、以下のようにしたほうがいいかも。
append="kdb=on console=ttyS0,38400 console=tty0"
これで、ブートメッセージは両方に出力される。そのかわりCTRL-Aでの
Breakinはできなくなる。
Initは最後に指定されたコンソールに出力するらしく、
append="kdb=on console=tty0 console=ttyS0,38400"
のようにしてしまうとInitの出力がターミナルだけになってしまうため
不便。
5別のスレの1
NGNGとりあえず、Linuxカーネルのなかで実際に止めてみて、どんな感じになるか見てみよう。
えっと、とりあえずSGI KDBは動いてるとします。で、なんかユーザーが特定の
操作をやったらとまる場所を探そう。俺が今回使うのはipv4のicmpのコード。
ユーザーがping叩けばそこ必ずとおるからね。普段はあまり通らないから変に
たくさん止まることもないと。
ソースをみていい止める関数を探してもいいが、今回俺はsystem.mapを使った。
system.mapをエディタで開いてみるとこんな感じでicmpがらみの関数がある。
c0206a60 t icmp_reply
c0206be0 T icmp_send
c0206f60 t icmp_unreach
c0207220 t icmp_redirect
c02072d0 t icmp_echo
c0207320 t icmp_timestamp
c0207410 t icmp_address
c0207420 t icmp_address_reply
c0207570 t icmp_discard
c0207580 T icmp_rcv
icmp_unreachなんかがいいかね。多分icmpが届かなかった場合にくるファンクション
だろう。はい、ターゲットマシンでPauseキーを押してbreakinしましょう。
[1]kdb> とかいうプロンプトがでるな。最初の数字はプロセッサナンバーだ。
シングルプロセッサで動かしてるなら常に0になる。
で、icmp_unreachにbreakpoint張るわけだが、system.mapを見て
[1]kdb> bp c0206f60 とじかにアドレス指定してもいいんだが、もっと簡単に
[1]kdb> bp icmp_unreach とシンボルを指定してもできる。
うまくbreakpoint張れたら
Instruction(i) BP #0 at 0xc0206f60 (icmp_unreach)
is enabled globally adjust 1
とか出るはず。あと、とりあえず、breakpoint張る前に実際のそのアドレスが
ファンクションの先頭であるか確認したほうがいいな。
ディスアセンブルはidコマンドだ。
[1]kdb> id icmp_unreach
0xc0206f60 icmp_unreachpush %ebp
0xc0206f61 icmp_unreach+0x1mov %esp,%ebp
0xc0206f63 icmp_unreach+0x3mov $0x14,%eax
0xc0206f68 icmp_unreach+0x8push %edi
0xc0206f69 icmp_unreach+0x9push %esi
0xc0206f6a icmp_unreach+0xapush %ebx
こんな風に先頭2インストラクションが push %ebpとpush %esp,%ebp ならそれは
まず間違いなく関数の先頭だ。これはC言語のStackFramを作るコードだ。
えっと、とりあえずSGI KDBは動いてるとします。で、なんかユーザーが特定の
操作をやったらとまる場所を探そう。俺が今回使うのはipv4のicmpのコード。
ユーザーがping叩けばそこ必ずとおるからね。普段はあまり通らないから変に
たくさん止まることもないと。
ソースをみていい止める関数を探してもいいが、今回俺はsystem.mapを使った。
system.mapをエディタで開いてみるとこんな感じでicmpがらみの関数がある。
c0206a60 t icmp_reply
c0206be0 T icmp_send
c0206f60 t icmp_unreach
c0207220 t icmp_redirect
c02072d0 t icmp_echo
c0207320 t icmp_timestamp
c0207410 t icmp_address
c0207420 t icmp_address_reply
c0207570 t icmp_discard
c0207580 T icmp_rcv
icmp_unreachなんかがいいかね。多分icmpが届かなかった場合にくるファンクション
だろう。はい、ターゲットマシンでPauseキーを押してbreakinしましょう。
[1]kdb> とかいうプロンプトがでるな。最初の数字はプロセッサナンバーだ。
シングルプロセッサで動かしてるなら常に0になる。
で、icmp_unreachにbreakpoint張るわけだが、system.mapを見て
[1]kdb> bp c0206f60 とじかにアドレス指定してもいいんだが、もっと簡単に
[1]kdb> bp icmp_unreach とシンボルを指定してもできる。
うまくbreakpoint張れたら
Instruction(i) BP #0 at 0xc0206f60 (icmp_unreach)
is enabled globally adjust 1
とか出るはず。あと、とりあえず、breakpoint張る前に実際のそのアドレスが
ファンクションの先頭であるか確認したほうがいいな。
ディスアセンブルはidコマンドだ。
[1]kdb> id icmp_unreach
0xc0206f60 icmp_unreachpush %ebp
0xc0206f61 icmp_unreach+0x1mov %esp,%ebp
0xc0206f63 icmp_unreach+0x3mov $0x14,%eax
0xc0206f68 icmp_unreach+0x8push %edi
0xc0206f69 icmp_unreach+0x9push %esi
0xc0206f6a icmp_unreach+0xapush %ebx
こんな風に先頭2インストラクションが push %ebpとpush %esp,%ebp ならそれは
まず間違いなく関数の先頭だ。これはC言語のStackFramを作るコードだ。
6別のスレの1
NGNGbreakpointが張れたらgコマンドで再開。icmp_unreach関数を呼ぶために
適当な存在しないipアドレスへpingを送ってみよう。
breakpointにHitしたら
Instruction(i) breakpoint #0 at 0xc0206f60 (adjusted)
0xc0206f60 icmp_unreachint3
Entering kdb (current=0xc1228000, pid 0) on processor 1 due to Breakpoint @ 0xc0206f60
のようなメッセージが出てコマンド待ちになる。
なにはともかく。止まったらスタックバックトレースを取ろう。コマンドはbtだ。
[1]kdb> bt
EBP EIP Function(args)
0xc1229e5c 0xc0206f60 icmp_unreach (0xc01051b0, 0xffffe000, 0xc1228000, 0xc1228000, 0xc1228000)
kernel .text 0xc0100000 0xc0206f60 0xc0207220
0xc0106fac ret_from_intr
kernel .text 0xc0100000 0xc0106fac 0xc0106fcc
Interrupt registers:
eax = 0x00000000 ebx = 0xc01051b0 ecx = 0xffffe000 edx = 0xc1228000
esi = 0xc1228000 edi = 0xc1228000 esp = 0xc1229fac eip = 0xc01051df
ebp = 0xc1229fac xss = 0x00000018 xcs = 0x00000010 eflags = 0x00000246
xds = 0xc1220018 xes = 0xc1220018 origeax = 0xffffff00 ®s = 0xc1229f78
0xc01051df default_idle+0x2f
kernel .text 0xc0100000 0xc01051b0 0xc01051f0
0xc1229fc0 0xc0105272 cpu_idle+0x52
kernel .text 0xc0100000 0xc0105220 0xc0105290
うーん、なんかうまく取れてないね。StackFrameがちゃんと作られてないと
完全には取れないんだね。でも関数の頭を見る限り全部StackFrameは
作られてるんだけどね。謎だ。KDBのソースを見て調べてみるしかないね。
適当な存在しないipアドレスへpingを送ってみよう。
breakpointにHitしたら
Instruction(i) breakpoint #0 at 0xc0206f60 (adjusted)
0xc0206f60 icmp_unreachint3
Entering kdb (current=0xc1228000, pid 0) on processor 1 due to Breakpoint @ 0xc0206f60
のようなメッセージが出てコマンド待ちになる。
なにはともかく。止まったらスタックバックトレースを取ろう。コマンドはbtだ。
[1]kdb> bt
EBP EIP Function(args)
0xc1229e5c 0xc0206f60 icmp_unreach (0xc01051b0, 0xffffe000, 0xc1228000, 0xc1228000, 0xc1228000)
kernel .text 0xc0100000 0xc0206f60 0xc0207220
0xc0106fac ret_from_intr
kernel .text 0xc0100000 0xc0106fac 0xc0106fcc
Interrupt registers:
eax = 0x00000000 ebx = 0xc01051b0 ecx = 0xffffe000 edx = 0xc1228000
esi = 0xc1228000 edi = 0xc1228000 esp = 0xc1229fac eip = 0xc01051df
ebp = 0xc1229fac xss = 0x00000018 xcs = 0x00000010 eflags = 0x00000246
xds = 0xc1220018 xes = 0xc1220018 origeax = 0xffffff00 ®s = 0xc1229f78
0xc01051df default_idle+0x2f
kernel .text 0xc0100000 0xc01051b0 0xc01051f0
0xc1229fc0 0xc0105272 cpu_idle+0x52
kernel .text 0xc0100000 0xc0105220 0xc0105290
うーん、なんかうまく取れてないね。StackFrameがちゃんと作られてないと
完全には取れないんだね。でも関数の頭を見る限り全部StackFrameは
作られてるんだけどね。謎だ。KDBのソースを見て調べてみるしかないね。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 「スマホ注文なのに客用Wi-Fiがない」のはなぜか? 導入しない飲食店側の事情 [少考さん★]
- 【片山さつき財務相】「挑戦なき国に発展はなし」「最後のチャンス」★2 [ぐれ★]
- 「NISAやってるやつバカなの?」GACKT、NISAを投資商品と思い込んで否定 以前の動画がXで拡散しツッコミが続出 [muffin★]
- 【訃報】脚本家の倉本聰さん死去 91歳、「北の国から」 [少考さん★]
- 【声優】緒方恵美、自身への反論アカウントに疑念 「こうして情報操作が行われているのかも」 [少考さん★]
- 34歳タレント小原ブラス「アンチ柔軟剤の人って過激派多くない?」問題提起「過敏すぎ…あんたの問題よ」 [muffin★]
- 高市首相の国連の敵国条項削除要求、中国の反発も想定内だった… 次々に中国を挑発していく方針に転換か [668024367]
- 【高市悲報】足場会社社長(28)、従業員6人に襲撃され重傷wwwwwwwwww [834922174]
- こどもNISA、49%が反対 [667744927]
- 【高市超絶悲報】高市早苗広報、切り抜きやコラを駆使したプロパガンダを始める [165981677]
- 【高市悲報】JRが代行バスを断念した内房線区間、案の定バスが足りず崩壊www [469534301]
- 【速報】千葉県全域、いきなり大雨 [422186189]