首页 > *nix技术, X86芯片, 内核技术, 硬件设备, 跟踪调试 > Double Fault & Triple Fault

Double Fault & Triple Fault

2012年4月7日 发表评论 阅读评论 11,718 次浏览

之前我曾提到过intel x86 cpu的14号中断用于处理缺页异常,这也是被人熟知的一个中断号,事实上intel架构总共可用的中断号有256个(从0到255),其中前32个(从0到31)中断号保留给Intel架构内部使用,也就是说这些中断都有其特定的含义而不可被用户更改,而剩余的224(从32到255)个中断则可由用户自定义和实现其具体功能。本文重点关注前32个中断,更具体点说是其中的一个中断Double Fault,以及隐包含的另外一个中断Triple Fault。

前32个中断,每个中断的含义都可以在intel手册“Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 3A System Programming Guide.pdf”上找到对应的描述(Table 6-1. Protected-Mode Exceptions and Interrupts ),这里不再过多解释其它中断,重点看一下8号Double Fault中断。
Double Fault从字面上来讲,就是前后的动作连续触发两个中断的异常,比如一个缺页异常没有对应的异常中断处理函数(用c代码表示即为NULL,空指针),这就将会引发一个典型的Double Fault,在这种情况下,如果发生缺页异常则将触发一个中断,此时cpu要去调用缺页异常中断处理函数进行处理,但却发现没有这个处理函数,因而这又是一个异常而再次触发中断,此时触发的就是Double Fault异常中断。但是,值得注意的是并不是连续发生两个中断就是Double Fault,因为部分情况下,连续发生的两个中断可以依次被cpu处理。为了辨别什么情况下才会触发Double Fault,Intel cpu把32个中断分为3类:
Table 6-4. Interrupt and Exception Classes

Class Vector Number Description
Benign
Exceptions
and
Interrupts








16 
17 
18 
19 
All 
All 
Debug
NMI Interrupt
Breakpoint
Overflow
BOUND Range Exceeded
Invalid Opcode
Device Not Available
Coprocessor Segment Overrun
Floating-Point Error
Alignment Check
Machine Check
SIMD floating-point
INT n
INTR
Contributory
Exceptions

10 
11 
12 
13 
Divide Error
Invalid TSS
Segment Not Present
Stack Fault
General Protection
Page Faults 14  Page Fault

而下表显示了会导致发生Double Fault的情况,即如果先发生某类型的异常,接着再发生某类型的异常,此时是否会导致发生Double Fault异常:
Table 6-5. Conditions for Generating a Double Fault

First Exception Second Exception
Benign Contributory Page Fault
Benign x x x
Contributory x Double Fault x
Page Fault x Double Fault Double Fault

看看前面举的示例,先发生Page Fault,接着发生Contributory Exception(执行NULL空函数为Segment Not Present,11号中断),对应下表的确将引发Double Fault。事实上,这个示例有点特殊,其实不管前一个异常是Benign也好,Contributory也好,Page Fault也好,只要对应的中断函数为空,此时都会触发Double Fault,对应intel手册里的话为:“Any further faults generated while the processor is attempting to transfer control to the appropriate fault handler could still lead to a double-fault sequence.”
Double Fault不可恢复,所以在该中断的处理函数里能做的也只能是收集相关信息(以便进行Double Fault问题原因排查),主动关闭相关程序和服务(如果可以的话),让机器‘死’得优雅一点。
如果Double Fault异常中断的函数也为空,那么此时将发生Triple Fault异常,该异常并不是一个真正的异常,它没有对应中断号,也表示如果发生了Triple Fault异常这种情况,cpu都不管了,除了重启机器别无他法(一般外部硬件,比如主板会向cpu发出重启信号)。
触发Triple Fault的情况大部分是因为LDT或者GDT或IDT错误导致(被无意中踩坏?)或者内核栈溢出(或下溢),比如内核栈溢出,栈顶指针刚好达到一个无效内存页(即访问页不在内存中)而触发Page Fault中断,进而调用Page Fault异常中断函数进行处理,函数调用需要进行异常信息压栈(以传递给中断函数),但栈内存页不存在内存中,这又触发Page Fault异常,如此反复进而触发Double Fault、Triple Fault。
遇到Triple Fault怎么弄?额,我不知道,不过Linus给出了明确的答复,但那是03年的事情:
http://yarchive.net/comp/linux/triple_faults.html

Newsgroups: fa.linux.kernel
From: Linus Torvalds <torvalds@osdl.org>
Subject: Re: 2.6.0-test9-mm3
Original-Message-ID: <Pine.LNX.4.44.0311141344290.5877-100000@home.osdl.org>
Date: Fri, 14 Nov 2003 21:48:59 GMT
Message-ID: <fa.jjta19r.1gl80h1@ifi.uio.no>

On Fri, 14 Nov 2003, Martin J. Bligh wrote:
>
> Linus had some debug thing for triple faults, a few months ago, IIRC ...
> probably in the archives somewhere ...

Triple faults you can't debug, they raise a line outside the CPU, and
normal PC hardware will cause that to just trigger a reboot.

But double faults do get caught, and that debugging stuff actually is in
the standard kernel. It won't give _nearly_ as good a debug report as a
"normal" oops, since I didn't want the double-fault handler to touch
anything even remotely unsafe, but it often gives a good hint about what
might be wrong. Certainly better than triple-faulting did (which we still
do for _catastrophic_ corruption, eg totally munged kernel page tables etc
- it's just very hard to avoid once you get corrupted enough).

		Linus

转载请保留地址:http://www.lenky.info/archives/2012/04/1479http://lenky.info/?p=1479


备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。

法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以Email或书面等方式告知,本站将及时删除相关内容或链接。

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.