CPU triple faults after divide by zero with ISRs installed

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
0xBADC0DE
Posts: 18
Joined: Mon Sep 26, 2016 8:25 am

CPU triple faults after divide by zero with ISRs installed

Post by 0xBADC0DE »

I have been stuck with this problem for a few days now and have searched this forum and on Google, but still cannot figure out what is wrong.

I have been following the tutorials at http://www.brokenthorn.com/Resources/OSDevIndex.html and http://www.osdever.net/bkerndev/Docs/intro.htm. I have setup a GDT and IDT that seem to be working correctly. I have also setup all the ISRs and an exception handler function that saves the registers and prints a message to the screen about the interrupt.

The problem is that ISR0 is not being called (or any other ISR) when a DivideByZeroException occurs. Instead of the CPU handling this exception and jumping to and executing the ISR, printing a message that an exception has occured, the CPU just triple faults.

To test the interrupts, I have added the code

Code: Select all

asm("int ")
and also tried

Code: Select all

printf("%s\n", 4/0)
which, as described above, cause a triple fault.

http://pastebin.com/R2JRVCiT (gdt.asm)
http://pastebin.com/vDZUfRXK (gdt.c)

idt.asm:

Code: Select all

global _idt_install
extern idt_p

_idt_install:
    lidt [idt_p]
    ret
http://pastebin.com/R0kFA0tm (idt.c)
http://pastebin.com/hAzX2Y11 (isrs.asm)
http://pastebin.com/9z217v7q (isrs.c)

The fault_handler function and all the ISRs seem to be working correctly. If I put

Code: Select all

isr0()
in my kernel, I get the expected error message of 'Exception caught. system halted'. Because of this, I think that it is either my IDT is setup incorrectly and not pointing to the correct ISR to handle the exception or the CPU is not handling the interrupt. Or maybe it's something else?

Sorry that I posted a lot of code, I'm just not sure where the problem is. It's also my first post.
I'm using qemu to test my OS with GRUB legacy and am in protected mode.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: CPU triple faults after divide by zero with ISRs install

Post by neon »

Hello,

I advise running bochsdbg and setting a breakpoint before the code that raises the exception. You can use the info idt command to then verify the integrity of the descriptor table. We can probably assume the original exception was a general protection fault.

Since you are using GCC, take note that it is most recommended in these forums to use a GCC cross compiler. I took a quick look at the code - looks like your code and "data" GDT selectors are exactly the same.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: CPU triple faults after divide by zero with ISRs install

Post by Octocontrabass »

osdever wrote:

Code: Select all

asm("int ")
With no volatile qualifier and no side effects, there's a good chance this got optimized away. If it did make it into your kernel, you would get an assembler error because "int" requires one operand and you gave no operands. It should be "int $0" (assuming you're using GCC's default AT&T syntax).
osdever wrote:

Code: Select all

printf("%s\n", 4/0)
The compiler automatically reduces constant expressions before generating any code. If you look at your kernel in objdump or tell GCC to output assembly code, you'll see that there is no div instruction here. If you really want a division exception, use inline assembly or an external assembly function to run a "div edx" instruction.
osdever wrote:http://pastebin.com/R2JRVCiT (gdt.asm)
You need to set SS. (Your kernel's init code should have set SP earlier. If it hasn't, then you need to fix that too.)
osdever wrote:http://pastebin.com/vDZUfRXK (gdt.c)
Why do functions that return int not return anything? How does the gdt_set_descriptor() function's behavior change if you add a semicolon after the "return"?
osdever wrote:http://pastebin.com/R0kFA0tm (idt.c)
Do not use reserved names like "printf". Those belong to the C standard library, and must never be used for anything else. The compiler can and will optimize them on the assumption that a complete standard library exists, leading to all sorts of issues. If you must have a printf-like function in your kernel, use a different name.
osdever wrote:http://pastebin.com/hAzX2Y11 (isrs.asm)
I can guarantee that "push eax" will not pass the correct parameter to your fault_handler function. Perhaps you wanted "push esp" instead?
osdever wrote:http://pastebin.com/9z217v7q (isrs.c)
Just like above, you can't call it printf if it's not part of a C standard library.
osdever wrote:Sorry that I posted a lot of code, I'm just not sure where the problem is.
Your code has a lot of problems. Make sure you enable lots of compiler warnings (e.g. "-Wall -Wextra") and fix all of them.
0xBADC0DE
Posts: 18
Joined: Mon Sep 26, 2016 8:25 am

Re: CPU triple faults after divide by zero with ISRs install

Post by 0xBADC0DE »

I finally fixed it!. Thanks everyone for your help :)

The

Code: Select all

asm("int $0")
was a mistake in my post, but not my code.
After doing what Octocontrabass had said about fixing all of my errors, the triple fault stopped happening. I think it was the int functions returning nothing. After using qemu with the -s -S options and gdb, I was able to debug my code and figure out the problem.

After the triple fault problem was gone, I set a breakpoint at

Code: Select all

isrs_install()
and found that it wasn't executing the code block in

Code: Select all

if (r->int_no < 32)
{
    
}
Thanks again for your help
Post Reply