Page 1 of 1

General Protection Fault after Divide by Zero.

Posted: Thu May 05, 2005 12:02 am
by serverkitty
Hello, Rookie here again! ;)

I just finished re-setting up my exception handler, so I tried testing it by purposely dividing by 0. That works fine, but if I try to do anything else after that, I get a General Protection Fault. What could I be doing wrong, or will I have to post code?

Thanks~ Serverkitty

Re:General Protection Fault after Divide by Zero.

Posted: Thu May 05, 2005 7:48 am
by mystran
There are two possible causes. The first one (the probably one actually) is that there's a problem with your handler, so that it causes a GPF when it returns... or something like that.

Also, IIRC divide by zero is an abort, which means you shouldn't try to resume the code that caused it..

Re:General Protection Fault after Divide by Zero.

Posted: Thu May 05, 2005 8:43 pm
by serverkitty
Ok, I figured it out. It was in my handler.

Code: Select all

%macro ISTUB 1
   PUSH GS
   PUSH FS
   PUSH ES
   PUSH DS
   PUSHAD
      MOV AX, SYS_DATA_SEL
      MOV DS, EAX
      MOV ES, EAX
      MOV FS, EAX
      MOV GS, EAX
; Why does it work when I comment these?
      ;MOV EAX, %1  
      ;PUSH EAX   ; Pass the interrupt # to the Kernel Interrupt Handler
      CALL _InterruptHandler
;Do I have to pop them after the C function?
   POPAD
   POP DS
   POP ES
   POP FS
   POP GS
   ADD ESP, 8
   IRET
%endmacro

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 12:09 am
by AR
; Why does it work when I comment these?
;MOV EAX, %1
;PUSH EAX ; Pass the interrupt # to the Kernel Interrupt Handler
The reason it works without that is because you don't pop it afterwards. And yes that answers the other question, C/C++ functions do not pop their own parameters, in a standard C call the parameters are pushed and popped by the caller.

Also with these interrupt handlers, be aware that the parameters are not meant to be popped (The compiler usually puts ADD ESP, X to simply delete them) so be aware of that. I had an interesting experience with compiler optimizations where the compiler decided to completely override the parameters since they weren't used in the function which naturally made a big mess when I tried to pop the segment registers [GPF which is incidentally what is happening here, you were popping an invalid value for the segment registers].

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 7:02 pm
by serverkitty
Thank you AR and mystran, that was a great help. Now maybe I can get somewhere with assembler/C. ;)

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 8:38 pm
by serverkitty
OK, I'm still not having much luck here! :(

I popped that like you said and I'm still getting the GPF. so I tried adding 9 to ESP to delete it and it is still generating a GPF. I'm so lost! :-[

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 9:31 pm
by AR

Code: Select all

%macro ISTUB 1
   PUSH GS
   PUSH FS
   PUSH ES
   PUSH DS
   PUSHAD
      MOV EAX, SYS_DATA_SEL
      MOV DS, EAX
      MOV ES, EAX
      MOV FS, EAX
      MOV GS, EAX

      PUSH %1   ; Pass the interrupt # to the Kernel Interrupt Handler
      CALL _InterruptHandler
      ADD ESP, 4 ;Delete PUSH %1 value

   POPAD
   POP DS
   POP ES
   POP FS
   POP GS
   ADD ESP, 8
   IRET
%endmacro
How you use this code would be useful, I am a bit confused by the last part ( ADD ESP, 8 ) being in a macro. Are you adding this code as is to the IDT or is there a stub that jumps to it?

In Bochs I recommend inserting "hlt; nop" pairs to let you step through it and print the stack as it goes to see where it messes up.

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 9:58 pm
by serverkitty
I haven't actually tried using Bochs yet, I've been using GRUB to boot up and I really don't feel like waiting for Bochs it to boot from floppy etc... right now I have a test rig with GRUB installed on the hard drive, so all I have to do is insert the floppy and turn the computer on.

This is the code I have so far for the ISR:
It finally does not reboot the computer, but I still get a full screen of GPFs, then after about a minute, the screen turns white! :S

Code: Select all

extern _InterruptHandler

%macro ISTUB 1
   PUSH GS
   PUSH FS
   PUSH ES
   PUSH DS
   PUSHAD
      MOV AX, SYS_DATA_SEL
      MOV DS, EAX
      MOV ES, EAX
      MOV FS, EAX
      MOV GS, EAX

      PUSH %1   ; Pass the interrupt # to the Kernel Interrupt Handler
      CALL _InterruptHandler
      ADD ESP, 4   ; Delete PUSH %1 value
   POPAD
   POP DS
   POP ES
   POP FS
   POP GS
   ADD ESP, 8
   IRET
%endmacro

isr0: ISTUB 0      ;Divide by 0
isr1: ISTUB 1      ;Debug Exception
isr2: ISTUB 2      ;Non-maskable hardware interrupt
isr3: ISTUB 3      ;Debugger Breakpoint
isr4: ISTUB 4      ;INTO instruction detected overflow
isr5: ISTUB 5      ;BOUND instruction detected overrange
isr6: ISTUB 6      ;Invalid instruction opcode
isr7: ISTUB 7      ;No coprocessor
isr8: ISTUB 8      ;Double fault
isr9: ISTUB 9      ;Coprocessor Segment Overrun
isr10: ISTUB 0x0A   ;Invalid task state segment
isr11: ISTUB 0x0B   ;Segment not present
isr12: ISTUB 0x0C   ;Stack fault
isr13: ISTUB 0x0D   ;General protection fault
isr14: ISTUB 0x0E   ;Page Fault
isr15: ISTUB 0x0F   ;Reserved
isr16: ISTUB 0x10   ;Coprocessor Error
isr17: ISTUB 0x11   ;Alignment Check
isr18: ISTUB 0x12   ;Machine Check
isr19: ISTUB 0x13   ;Reserved
isr20: ISTUB 0x14   ;   ''
isr21: ISTUB 0x15   ;   ''
isr22: ISTUB 0x16   ;   ''
isr23: ISTUB 0x17   ;   ''
isr24: ISTUB 0x18   ;   ''
isr25: ISTUB 0x19   ;   ''
isr26: ISTUB 0x1A   ;   ''
isr27: ISTUB 0x1B   ;   ''
isr28: ISTUB 0x1C   ;   ''
isr29: ISTUB 0x1D   ;   ''
isr30: ISTUB 0x1E   ; Kernel Call

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 10:04 pm
by AR
That's why people don't use real floppies and use floppy disk images instead.

Ok, I see now, you've made a mess of your stack, remove the ADD ESP, 8 and it may work, some exception handlers have error codes (like page fault, GPF, TSS, etc) which do require an ADD ESP, 4 at the end however.

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 10:11 pm
by Chris Giese
Divide error doesn't push an error code on the stack, so you don't need the "ADD ESP, 8"

Anyway, for exceptions that DO push an error code, you want to use "ADD ESP, 4"

The next problem you encounter may be an infinite loop of exceptions. Divide error is a fault, so the IRET returns to the instruction that caused it -- which immediately causes another divide error. (Hmmm, try it and see...could be amusing :)

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 10:54 pm
by serverkitty
Hahahah, that was cool, it doesn't crash but there is an infinite loop of Divide by 0's! ;) Along with some video buffer corruption. O_o

Thanks guys! Chris, your website is awesome, it has helped me so much.

Now I have to figure out how to stop the divide by 0.
~Serverkitty

Re:General Protection Fault after Divide by Zero.

Posted: Fri May 06, 2005 11:02 pm
by serverkitty
Darn it, just when I thought everything was fixed and good, I opened up the source code, replaced the divide by 0 with an INT 0x1E to test my system call and it still says that it is a divide by 0. This interrupt stuff is really confusing! :S
How does the interrupt handler get a zero from 0x1E?

Re:General Protection Fault after Divide by Zero.

Posted: Sat May 07, 2005 3:20 am
by Pype.Clicker
might you have something broken in your compilation code ?

moreover, as you have previously removed the part that passes the interrupt code to the C code, i'm not surprised that all interrupts appears as a single one ;)

Re:General Protection Fault after Divide by Zero.

Posted: Sat May 07, 2005 10:20 pm
by serverkitty
I'm still having terrible problems with this and I'm beginning to tear my hair out of my scalp! >:(

So I'm deciding just to post the code of the whole thing so you guys can look it over. I must have made a mistake somewhere...

I will be so greatful if someone could take the time to look it over.

Thanks~ Serverkitty

Re:General Protection Fault after Divide by Zero.

Posted: Sun May 08, 2005 11:25 pm
by B.E
try and uncomment your switch statment and place the

Code: Select all

default:
??????setAttribute(0x0C);
??????print("FATAL ERROR: Unknown Exception! System halted.\n");
??????asm("hlt");
??????break;
down the bottom of the switch statment (as that is the normal place you will find this stament)

and with isr.inc uncomment PUSH DWOD %1