リベンジ(Debug onr FreeBSD)
とある夜、もうパソコンやるのやめよう、その前にメールが来てないか確認しようと思って メーラーを立ち上げると、今まで見た事が無いエラー。ネットにアクセス出来ないんだとさ。
ふと、目の前にあるADSLルーター(兼HUB)を見ると、WAN側のランプが異常な点滅を繰り返して いる。これって異常を教えてくれているんだよな。でも、おしいかなこのルーターは貰い物で 取り扱い説明書なんてないんだ。ネットで調べようとしても頼みのネットには繋がらんし。 もう寝るしか。
翌朝も異常な点滅は収まっていなかった。ええい、Power on Resetだ。でも効果無し。ADSLモデムは エラー表示もなく正常そう。こちらも念の為に、Power on Resetを実施。でも相変わらず ネットには接続出来ず。こうなったら、ルータをバイパスして、モデムに直結かな。確か ISPからDHCPでIPを貰い受けられたはず。昔遊びで使ってた馬鹿HUBを介してFreeBSD機を接続した。 (馬鹿HUBって、スイッチ機能が無い骨董品の意です)
# ifconfig ed1 delete # dhclient ed1
いつまで経っても、IPが届いたと連絡無し。こんな状態じゃpingも打てないじゃん。一応、電話が 通じているか声のpingはしましたけどね。久しぶりの実家の兄貴の声を聞いたよ。
はて、こうなるとモデムが壊れているか、モデムに対向する局内装置の不良かなあ。取りあえず ISPに電話だなあ。 なんて思っていたら、いつの間にか異常点滅も収まってネットにも 接続出来るようになってた。真夏(梅雨)の夜の怖い話(でもないか)でした。さて、その 真相やいかに?
VMWAREでシリアル接続して debug(再び)
前回の続きになるんだけど、FreeBSDでシリアル接続したマシンからリモートデバッグを 出来ないか、ねちねちと調べている。targetマシンを起動した時、シリアルポートを 見つけられないと言われて頓挫してたんだ。
ものは試しと本家の資料を見てたんだ。 English Handbook そしたら、翻訳されたハンドブックには無い一文を発見した。シリアルのフラグをセットせよ、 ですって。そんな訳で、おいらのシリアル(いつの間にかsioからuartへと進化してる)を 見ると
[sakae@cdr ~]$ man uart : In /boot/device.hints: hint.uart.0.disabled="1" hint.uart.0.baud="38400" hint.uart.0.port="0x3f8" hint.uart.0.flags="0x10" With flags encoded as: 0x00010 device is potential system console 0x00080 use this port for remote kernel debugging 0x00100 set RX FIFO trigger level to ``low'' (NS8250 only) 0x00200 set RX FIFO trigger level to ``medium low'' (NS8250 only) 0x00400 set RX FIFO trigger level to ``medium high'' (default, NS8250 only) 0x00800 set RX FIFO trigger level to ``high'' (NS8250 only)
へぇー、昔はこんな設定、configに書いておいてコンパイルしたような。。設定が外に出て自由度が増した のね。知らんかったよ。言われた通りにflagsを設定してから再起動。途中で6を押してから、boot -d したよ。
GDB: debug ports: uart GDB: current ports: uart KDB: debugger backends: gdb KDB: current backend: gdb KDB: enter: Boot flags requested debugger
おお、前回と違って、uartを認識してる。これは期待出来るぞ。remote側で皮を被ったgdbを 起動。
[sakae@fb8 /sys/i386/compile/SAKAE]# kgdb -r /dev/cuau0 kernel.debug GNU gdb 6.1.1 [FreeBSD] Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-marcel-freebsd"...Switching to remote protocol kdb_enter (why=0xc0cb3362 "bootflags", msg=0xc0cb3344 "Boot flags"...) at ../../../kern/subr_kdb.c:341 341 kdb_why = KDB_WHY_UNSET; (kgdb) b elf32_load_file Breakpoint 1 at 0xc08506c0: file ../../../kern/imgact_elf.c, line 555. (kgdb) c Continuing. [New Thread 100052] [Switching to Thread 100052] Breakpoint 1, elf32_load_file (p=0xc2e02d48, file=0xd009b114 "/libexec/l"..., addr=0xd1be6a98, entry=0xd1be6bd4, pagesize=4096) at ../../../kern/imgact_elf.c:555 555 struct vmspace *vmspace = p->p_vmspace; : (kgdb) i b Num Type Disp Enb Address What 1 breakpoint keep y 0xc08506c0 in elf32_load_file at ../../../kern/imgact_elf.c:555 breakpoint already hit 321 times (kgdb) bt #0 elf32_load_file (p=0xc34abd48, file=0xd01180f4 "/libexec/l"..., addr=0xd1c29a98, entry=0xd1c29bd4, pagesize=4096) at ../../../kern/imgact_elf.c:555 #1 0xc0851dfb in exec_elf32_imgact (imgp=0xd1c29bbc) at ../../../kern/imgact_elf.c:916 #2 0xc086b6a1 in kern_execve (td=0xc3101480, args=0xd1c29c54, mac_p=0x0) at ../../../kern/kern_exec.c:476 #3 0xc086cd3c in execve (td=0xc3101480, uap=0xd1c29cf8) at ../../../kern/kern_exec.c:207 #4 0xc0bd8fb5 in syscall (frame=0xd1c29d38) at ../../../i386/i386/trap.c:1073 #5 0xc0bbc2e0 in Xint0x80_syscall () at ../../../i386/i386/exception.s:261 #6 0x00000033 in ?? () Previous frame inner to this frame (corrupt stack?) :
ちゃんと動きましたねぇ。パチパチパチ。loginのpromptが出てくるまで、340回ぐらい load-file が呼ばれていたよ。すごいこった。
(kgdb) c Continuing. ^C^CInterrupted while waiting for the program. Give up (and stop debugging it)? (y or n) y (kgdb) q [root@fb8 /usr/src/sys/i386/compile/SAKAE]#
しかし、break pointをクリアしてしまうと、後は何をやってもgdbに制御が返ってこない。 強制的に止めてしまうと、もうkernelとは縁が切れてしまう。ちょっとこの点が残念であります。
残念と言えばもう一つあって、使っているうちにシリアルラインの接続が切れてしまう事が あるんだ。反応しなくなったなあと思っていると、target側が勝手にrebootしてしまい、 バックグラウンドで fsck が実行されたりする。 後、emacs上からは使えないというのが痛いなあ。
FreeBSDのブートプロセスをみる
ここまでやってきて、上京する機会があったんで、表題の本を仕入れてきた。この本は 懐かしいユニマガの連載をまとめたものだ。姉妹編で、Linuxの... ってのがあるけど いきがかり上って事で。
で、この本で言及してるのは、FreeBSD-5.1。どこかでソースが手に入らないかと思って 総本山へ行ったら、博物館があった。 全部揃っている 昔はCD1枚に全部収まっていたんだ。懐かしい。
今回はシステム以下のソースだけが欲しいんで、下記のようにした。1.4Mでsplitされてる のは、丁度1枚のFDDに収める為だ。今もこの分割は周到されてるのかな?
[sakae@cdr ~/tmp]$ wget ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/5.1-RELEASE/src/ssys.* [sakae@cdr ~/tmp]$ cksum ssys.a* 3805760201 1457152 ssys.aa 3416949032 1457152 ssys.ab 258509674 1457152 ssys.ac 1796530442 1457152 ssys.ad 2603359928 1457152 ssys.ae 995319421 1457152 ssys.af 785388220 1457152 ssys.ag 2986136453 1457152 ssys.ah 2748432807 1457152 ssys.ai 2923777202 1457152 ssys.aj 2836972634 517531 ssys.ak [sakae@cdr ~/tmp]$ cat ssys.a* | gzip -dc | tar xf - [sakae@cdr ~/tmp]$ cd sys [sakae@cdr ~/tmp/sys]$ ls Makefile ddb/ libkern/ netnatm/ powerpc/ alpha/ dev/ modules/ netncp/ security/ amd64/ fs/ net/ netsmb/ sparc64/ arm/ geom/ netatalk/ nfs/ sys/ boot/ gnu/ netatm/ nfsclient/ tools/ cam/ i386/ netgraph/ nfsserver/ ufs/ coda/ i4b/ netinet/ opencrypto/ vm/ compat/ ia64/ netinet6/ pc98/ conf/ isa/ netipsec/ pccard/ contrib/ isofs/ netipx/ pci/ crypto/ kern/ netkey/ posix4/
これでバッチリソースを読めるぞ。福読本は、悪魔本だな。
おまけ
カーネルのソースを見ていると、dconsなんてのがよく出てくる。dconsって一体何やねん? 調べてみた。
DESCRIPTION The dcons device is a simple console device which just reads from and writes to an allocated buffer for input and output respectively. It is of no use by itself and it is supposed that the buffer is accessed via a bus like firewire(4) or kvm(3) for interaction. : AUTHORS Hidetoshi Shimokawa <simokawa@FreeBSD.org>
下川さんが貢献してるんだ。MAC Loveな人なのかな? だって、firewireって、USBは好かん という某大将がさかんに押してたやつですよねぇ。今じゃすっかり廃れてしまっているけど 。
FIREWIRE(4) FreeBSD Kernel Interfaces Manual FIREWIRE(4) NAME firewire -- IEEE1394 High-performance Serial Bus
ひょっとして、VMWAREが間違ってサポートしてないか調べてみたけど、そんなアップルみたいな 事はしませんっていう事だ。ジョブスの口車に乗って投資した人がいたらかわいそうに。 そういえば、おいらのパソコンには、HDIM何とかという、直ぐに廃れそうな口が付いて いるけど、これって誰の差し金?
こんなくだらんI/Fを付けるなら、シリアルの口を用意してくれた方がよっぽど使い道が あるってもんです。
おまけのおまけで、どなたかが書いてたもの。FreeBSDの日本語manは、伝統的にeucJP。 これを、utf8の端末でスマートに読む方法。ports/misc/lvを入れといて
alias man='env PAGER="lv -Ou8" LC_ALL=ja_JP.eucJP jman'
端末は、TeraTermなりPuTTYなりを使います。どうしてもXの上を希望する場合は、ports/x11/mlterm を使えば無問題。