--ホーム--
|
死亡例その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のバグのようなのですが, 詳細はまだ調べていません. |