Page 1 of 1

Problem with exceptions

Posted: Tue Jul 26, 2005 4:16 pm
by beyondsociety
I have exceptions 0 - 17 tied to one fault handler that will print out the number of exception triggered, and what it is. The problem is I am getting the same number printed out for all exceptions: 8 (Double fault).

Is this normal, or am I doing something wrong?

Code: Select all

idt_selector: 
0x8E00  // 1000111000000000 = present,ring0,int_gate

Bochs output: (Same for each exception)
32 bit interrupt gate target = 0x0008:0x00010380, DPL = 0

From Intel manuals
Normally, when the processor detects an exception while trying to invoke the handler for a prior exception, the two exceptions can be handled serially. If, however, the processor cannot handle them serially, it signals the double-fault exception instead. To determine when two faults are to be signalled as a double fault, the 80386 divides the exceptions into three classes: benign exceptions, contributory exceptions, and page faults.
Could this be the cause?

Re:Problem with exceptions

Posted: Tue Jul 26, 2005 5:28 pm
by oswizard
Can you post some code - your interrupt stubs should be fine. If you do not have different stubs, how are you getting the code? The processor does not tell you the exception number when it invokes the handler.

I don't think the double fault is the problem - it could be, though.

Mike

Re:Problem with exceptions

Posted: Tue Jul 26, 2005 6:22 pm
by AR
The double fault is most likely not actually a double fault, it's probably a hardware interrupt (IRQ0 - PIT), you will need to mask or remap the PIC before you'll be able to tell whether or not it's a CPU exception. Also your Int8 handler is invalid, since you are using the same handler for all exceptions I assume you aren't removing the Error Code from the stack which will cause another exception when you attempt to IRET from the handler.

Re:Problem with exceptions

Posted: Tue Jul 26, 2005 8:54 pm
by beyondsociety
Can you post some code - your interrupt stubs should be fine. If you do not have different stubs, how are you getting the code? The processor does not tell you the exception number when it invokes the handler.
I should of made myself more clear. I am using different stubs for each exception but having them called through one common fault_handler.

For example

Code: Select all

%macro STUB 1
   push byte 0  ; "Fake" error code
   push byte %1 ; Exception number

   push gs      ; Push segment registers
   push fs
   push es
   push ds
   pusha        ; Push EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX

   ; Put known-good values into segment registers
   mov ax, 0x10
   mov ds, eax
   mov es, eax
   mov fs, eax
   mov gs, eax

.1:     
   mov eax, _fault_handler ; Default "handler"
   call eax     ; Use EAX for absolute call vs. EIP-relative

   popa        ; Pop EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX
   pop ds      ; Pop segment registers
   pop es
   pop fs
   pop gs
   add esp, 8  ; Drop exception number and error code
   iret
%endmacro

; ISR00 (Divide Error)
divide_error:
   STUB 0x00
Also your Int8 handler is invalid, since you are using the same handler for all exceptions I assume you aren't removing the Error Code from the stack which will cause another exception when you attempt to IRET from the handler.
How would I do that?

Re:Problem with exceptions

Posted: Tue Jul 26, 2005 9:15 pm
by AR
You're clearing the stack properly (assuming you don't push the error code when the CPU has already put it on the stack). Have you masked the PIC?

If it is actually a double fault then that would imply that your handler and/or IDT is broken.

Re:Problem with exceptions

Posted: Tue Jul 26, 2005 10:15 pm
by beyondsociety
Have you masked the PIC?
Yes, I disable all exceptions/irqs.

Re:Problem with exceptions

Posted: Wed Jul 27, 2005 7:36 am
by oswizard
[I had a long message, but hit ESC... >:( ]

Can you post the code, or at least part of it, from your _fault_handler function?

Mike

Re:Problem with exceptions

Posted: Wed Jul 27, 2005 9:36 am
by beyondsociety
Code attached below.

Re:Problem with exceptions

Posted: Wed Jul 27, 2005 5:36 pm
by oswizard

Code: Select all

void fault_handler(regs_t regs)
{
        printk("\nException #%i (%s)", regs.num, exceptions[regs.num]);
        cli(); hlt();
}

Code: Select all

      push eax
.1:   mov eax, _fault_handler ; Default "handler"
   call eax                ; Use EAX for absolute call vs. EIP-relative
      pop eax
You call C functions by pushing their parameters on to the stack. Right now, the top thing on the stack is 0x10 - the data segment. So, I would think it should be printing 0x10 - coproc error. Instead, you need to do push esp right before the function - and get rid of the push/pop eax (but add 4 to esp after the function call to pop the parameters).

Change your regs_t struct to match the layout of the stack, and change fault_handler to take a regs_t* pointer. Then it should work, and you get access to all the other registers as a bonus. See a previous related thread (that I can't find right now) for more information.

Mike