Return to BSD News archive
From: uhclem@nemesis.UUCP Date: 29 Aug 92 22:50 CDT Newsgroups: comp.unix.bsd Subject: Description of Trap Codes Message-ID: <-13547389@nemesis> Path: sserve!manuel!munnari.oz.au!uunet!cs.utexas.edu!convex!news.oc.com!utacfd.uta.edu!trsvax!trsvax!nemesis!uhclem Nf-ID: #N:nemesis:-13547389:000:7408 Nf-From: nemesis.UUCP!uhclem Aug 29 22:50:00 1992 Lines: 193 There have been several questions about the various Trap codes being encountered on the 386/486. Here is a list of the Trap codes, along with some common causes for each. Trap 0 Divide Error The DIV or IDIV instruction is executed with a zero denominator or the quotient is too large for the destination operand. Trap 1 Debug Exceptions Used in conjunction with DR6 and DR7, The following flags need to be tested to determine what caused the trap: BS=1 Single-step trap B0=1 AND (GE0=1 or LE0=1) Breakpoint, DR0, LEN0, R/W0 B1=1 AND (GE1=1 or LE1=1) Breakpoint, DR1, LEN1, R/W1 B2=1 AND (GE2=1 or LE2=1) Breakpoint, DR2, LEN2, R/W2 B3=1 AND (GE3=1 or LE3=1) Breakpoint, DR3, LEN3, R/W3 BD=1 Debug registers not available, in use by ICE-386 BT=1 Task Switch Trap 2 NMI Interrupt On PC/AT systems, the NMI input to the CPU is usually connected to the main memory parity circuit. By the time the error signal is generated, the data may have already been used in an instruction, so it isn't possible to reliably recover. Trap 3 Breakpoint The result of executing an INT 3 instruction. MS-DOS and Windows and some other non-386 systems use this for debugging. Code specific to the 386 and later processors should use the debugging features tied to Trap 1. Trap 4 INT0 Detected Overflow Occurs if an INT0 instruction is executed and the overflow flag (OF) is currently set. Trap 5 BOUND Range Exceeded Occurs if the BOUND instruction is executed and the array index points beyond the area of memory containing the array being tested. Trap 6 Invalid Opcode The value read at CS:IP is not a valid opcode. Trap 7 Coprocessor Not Available This occurs if the processor fetches an instruction that is for the coprocessor and no coprocessor is present. Trap 8 Double Exception (Fault) An exception occurred while trying to execute the handler for a prior exception. Example, an application causes a General Protection Fault (13) and the area of memory where the GPF handler should be is flagged not-present (paged-out?). The double-fault handler is invoked in these conditions. If a fault occurs while trying to run the double-fault handler, a triple-fault occurs and the CPU resets. The rules for deciding if a double-fault should occur or if the two faults can be handled serially are discussed in more detail in the Intel song book. Trap 9 Coprocessor Segment Overrun A page or segment violation occurred while transferring the middle part of a coprocessor operand to the NPX. Trap 10 Invalid Task State Segment During a task switch, the new TSS was invalid. Here is a table of conditions that Invalidate the TSS: TSS id + EXT The limit in the TSS descriptor is < 103 LTD id + EXT Invalid LDT selector or LDT not present SS id + EXT Stack segment selector is outside table limit SS id + EXT Stack segment is not a writable segment SS id + EXT Stack segment DPL does not match new CPL SS id + EXT Stack segment selector RPL <> CPL CS id + EXT Code segment is outside table limit CS id + EXT Code segment selector does not refer to code segment CS id + EXT DPL of non-conforming code segment <> new CPL CS id + EXT CPL of conforming code segment > new CPL DS/ES/FS/GS id + EXT DS, ES, FS or GS segment selector is outside table limits DS/ES/FS/FS id + EXT DS, ES, FS, or GS is not readable segment Trap 11 Segment Not Present Occurs when the "present" bit of a descriptor is zero. This can occur while loading any of these segment registers CS, DS, ES, FS, or GS. Loading SS causes a Stack fault. Also occurs when attempting to use a gate descriptor that is marked "not present", and if attempting to load the LDT with an LLDT instruction. Note that loading the LDT during a task switch causes an "invalid TSS" trap. Trap 12 Stack Fault A limit violation relating to an address referenced off the SS register. Includes POP, PUSH, ENTER and LEAVE opcodes, as well as references such as MOV AX,[BP+8] (which has an implied SS:). Also causes by loading SS with a descriptor that is marked "not present". Trap 13 General Protection Fault (GPF) Americas Favorite, in the Windows 3.0 world, it is known as the UAE error. The instruction tried to access data out of the bounds designated by the descriptors. The access that failed can be a read, write or instruction fetch. There are 15 classifications of GPFs: 1. Exceeding segment limit when using CS, DE, ES, FS or GS. 2. Exceeding segment limit when referencing a descriptor table. 3. Transferring control to a segment that is not executable. 4. Writing into a read-only data segment or into a code segment. 5. Reading from an execute-only segment. 6. Loading the SS register with a read-only descriptor (unless the selector comes from the TSS during a task switch, in which case a TSS exception occurs.) 7. Loading SS, DS, ES, FS or GS with the descriptor of a system segment. 8. Loading, DS, ES, FS or GS with the descriptor of an executable segment that is not also readable. 9. Loading SS with the descriptor of an executable segment. 10. Accessing memory via, DS, ES, FS or GS when the segment register contains a null selector. 11. Switching to a busy task. 12. Violating priviledge rules. 13. Loading CR0 with a PG=1 and PE=0. 14. Interrupt or exception via trap or interrupt gate from V86 mode to prviledge level other than zero. 15. Exceeding the instruction limit of 15 bytes (this can only occur if redundant prefixes are placed before an instruction). To determine which condition caused the trap, you need the instruction, the contents of all associated registers, particularly the segment registers involved, then the various LDT, GDT and page control tables. Lots of common coding errors cause the GPFs. Even a stack imbalance will usually show up as a GPF. Even MOV AX,7 MOV ES,AX or MOV AX,5 PUSH AX POP DS will get a GPF error. You can't use a segment register for "temporary storage" of any old value the way you could on the 8086. The values loaded into the segment registers are checked in protected mode. Trap 14 Page Fault The page directory or page table entry needed for the address translation has a zero in the present bit, or the current procedure does not have sufficient priviledge to access the indicated page. Trap 15 (reserved) Trap 16 Coprocessor Error The coprocessor asserted the ERROR# input pin on the 386 (internal on the 486) Trap 17 Alignment Check (486 and later) If enabled, this trap will occur if a data fetch does not occur on a word boundary. I don't know of any software that activates this feature yet. I have seen SCO UNIX get this error on early Cyrix processors, even though SCO had not enabled the feature. Trap 18-32 (reserved) All this information and more can be found in the variuous programmers references from Intel and other compatible chip vendors. Frank Durda IV <uhclem@nemesis.lonestar.org>|"The Knights who say "LETNi" ....utacfd!nemesis!uhclem (nearest internet) | demand... A SEGMENT REGISTER!!!" ....letni!rwsys!nemesis!uhclem |"A what?" ....decvax!microsoft!trsvax!nemesis!uhclem |"LETNi! LETNi! LETNi!" - 1983