ホーム 研究内容 FreeBSD HP電卓 今日のgoo Links

--ホーム--
研究内容
FreeBSD
HP電卓
--Links--
BSD
Security
Hardware
NetHack
HP電卓

死亡例その1 (わざと殺した)

とりあえず,雰囲気をつかんでみるということで,実際の例を見てみましょう. まずは,カーネルを無理矢理殺してみました.実験したのは5月4日の FreeBSD(98)-currentです.

まず,CTRL+GRPH+ESCでDDBに入ります.そして,

    db> call vfs_unmount()

としてすべてのファイルシステムをunmountしようとします.うまくいけば次 のリブートが速いですから.しかし,

  Fatal trap 12: pgae fault while in kernel mode
  fault virtual address   = 0x60
  fault code              = supervisor write, page not present
  instruction pointer     = 0x8:0xf01156db
  stack pointer           = 0x10:0xf01ebca0
  frame pointer           = 0x10:0xf01ebcb0
  code segment            = base 0x0, limit 0xffff, type 0x1b
                          = DPL 0, pres 1, def32 1, gran 1
  processor eflags        = interrupt enabled, resume, IOPL=0
  current process         = Idle
  interrupt mask          = net tty bio

  kernel: trap 12 trap, code = 0
  stopped at      _tsleep+0x83:   movl    %ecx,0x60(%ebx)

となってしまいます.なんで?というわけですが,どうしようもないのでcore を吐かせてみます.

  db> call panic

これでcoreを吐くいてからリブートします.それではkgdbを実行します.


        cd /sys/compile/HOGEHOGE
        kgdb


(kgdb) symbol-file kernel.debug
Reading symbol data from /tmp_mount/work/FreeBSD/sys/compile/
MARBLE/kernel.debug...done.

(kgdb) exec-file /var/crash/kernel.0
(kgdb) core-file /var/crash/vmcore.0
IdlePTD 23f000
panic: 
current pcb at 2065a0
Reading in symbols for ../../pc98/i386/machdep.c...done.

これで,シンボルなどの読み込みが終ります.とりあえず,

(kgdb) where
#0  boot (howto=256) (../../pc98/i386/machdep.c line 1016)
#1  0xf0119207 in panic (...)
#2  0xf0101c2a in db_command:db_fncall (...)
#3  0xf010195e in db_command:db_command (...)
#4  0xf0101add in db_command_loop (...)
#5  0xf0103e48 in db_trap (...)
#6  0xf01aebba in kdb_trap (...)
#7  0xf01b824f in trap:trap_fatal (...)
#8  0xf01b7d4c in trap:trap_pfault (...)
#9  0xf01b79df in trap (...)
#10 0xf01af431 in exception:calltrap (-221729216, 16, -267200475, 0)
#11 0xf012d863 in biowait (...)
#12 0xf012bf11 in bwrite (...)
#13 0xf019419a in ffs_vfsops:ffs_sbupdate (...)
#14 0xf0193a9d in ffs_unmount (...)
#15 0xf013278c in dounmount (...)
#16 0xf0130a11 in vfs_unmountall (...)
#17 0xf0101c2a in db_command:db_fncall (...)
#18 0xf010195e in db_command:db_command (...)
#19 0xf0101add in db_command_loop (...)
#20 0xf0103e48 in db_trap (...)
#21 0xf01aebba in kdb_trap (...)
#22 0xf01b7a8c in trap (...)
#23 0xf01af431 in exception:calltrap ()
#24 0xf01e2772 in syscons:scgetc (...)
#25 0xf01dd5cc in scintr (...)

として様子を見ます.trapで落ちているのでframe pointerが変わっています. それが#9です.まず,

(kgdb) up 9
Reading in symbols for ../../pc98/i386/trap.c...done.
#9  0xf01b79df in trap (frame={tf_es = 16, tf_ds = 16, tf_edi = -1073534926,
tf_esi = -267200475, tf_ebp = -266421072, tf_isp = -266421108, tf_ebx = 0,
tf_edx = 16, tf_ecx = -221729216, tf_eax = -1073534926, tf_trapno = 12,
tf_err = -1073545214, tf_eip = -267299109, tf_cs = -266862584,
tf_eflags = 66118, tf_esp = -221729216, tf_ss = -1073537006})
(../../pc98/i386/trap.c line 358)

358				(void) trap_pfault(&frame, FALSE);

とします.そして,

(kgdb) frame frame->tf_ebp frame->tf_eip
Reading in symbols for ../../kern/kern_synch.c...done.
#0  0xf01156db in tsleep (ident=(void *) 0xf2c8ae40, priority=16,
wmesg=(char *) 0xf012d825 "biowait", timo=0)
(../../kern/kern_synch.c line 322)

322		p->p_wchan = ident;

としてframe pointerをpanicしたところに持っていきます.ここは kern_synch.cの322行目のtsleep()の中です.ソースを見てみ ましょう.

(kgdb) list
317		}
318	#ifdef DIAGNOSTIC
319		if (ident == NULL || p->p_stat != SRUN || p->p_back)
320			panic("tsleep");
321	#endif
322		p->p_wchan = ident;
323		p->p_wmesg = wmesg;
324		p->p_slptime = 0;
325		p->p_priority = priority & PRIMASK;
326		qp = &slpque[LOOKUP(ident)];

さて,page faultをおこしたコードを逆アセンブルしてみます.

(kgdb) disassemble 0xf01156c0 0xf01156ff
Dump of assembler code from 0xf01156c0 to 0xf01156ff:
0xf01156c0 <tsleep+104>:        movl   0xf01f296c,%eax
0xf01156c5 <tsleep+109>:        testl  %edx,%eax
0xf01156c7 <tsleep+111>:        je     0xf0115860
0xf01156cd <tsleep+117>:        call   0xf01b0690
0xf01156d2 <tsleep+122>:        jmp    0xf0115860
0xf01156d7 <tsleep+127>:        nop    
0xf01156d8 <tsleep+128>:        movl   8(%ebp),%ecx
0xf01156db <tsleep+131>:        movl   %ecx,96(%ebx)
0xf01156de <tsleep+134>:        movl   %esi,100(%ebx)
0xf01156e1 <tsleep+137>:        movl   $0x0,108(%ebx)
0xf01156e8 <tsleep+144>:        movb   %dl,204(%ebx)
0xf01156ee <tsleep+150>:        movl   %ecx,%eax
0xf01156f0 <tsleep+152>:        sarl   $0x5,%eax
0xf01156f3 <tsleep+155>:        andl   $0x3f8,%eax
0xf01156f8 <tsleep+160>:        leal   -266310576(%eax),%edx
0xf01156fe <tsleep+166>:        cmpl   $0x0,-266310576(%eax)
End of assembler dump.

あれ?問題の部分は

0xf01156db <tsleep+131>:        movl   %ecx,96(%ebx)

ですが,panicメッセージでは

0xf01156db <tsleep+131>:        movl   %ecx,60(%ebx)

です.うーん,何か変.

あとはここからいろいろ考えていくわけですが,とりあえず雰囲気を掴むとい うことで,このへんでおしまいにします.

その後いろいろ調べたのですが,どうもCyrix 5x86のバグのようなのですが, 詳細はまだ調べていません.


リーガル Contact 名大岩鉱 名大地球 名大年測
© Copyright KATO Takenori, 1997, 1998, 199, 2000. All rights reserved.
© Original BSD Daemon Copyright 1988 by Marchall Kirk McKusik. All Rights Reserved.