IDT Errors? Exception 6 (Invalid Opcode)

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
underscoretanner
Posts: 2
Joined: Sat Jun 24, 2017 8:46 pm

IDT Errors? Exception 6 (Invalid Opcode)

Post by underscoretanner »

Hello, first off if you've clicked this and are here to help I would like to express a thank you. I'm having a problem with my IDT implementation (which I hear is common) that I haven't been able to fix after rewrites, looking at functioning IDT code, and browsing this forum with the obvious search parameters. As the title suggests my IDT malfunctions producing an invalid opcode exception when it should actually be reporting a division by zero exception. Because my assembly file is so long I'll post a pastebin of it and other code related to it. If it helps I've been making my way through Bran's kernel tutorials so it looks basically like that (with some additional discrepancy, apparently).

IDT: https://pastebin.com/ifSit15p
Kernel main (with testing code): https://pastebin.com/CgfVEhYg
Boot (assembly): https://pastebin.com/0cFgZvYf

If there's anything I can do to make this problem more amenable to helping (like posting my GDT, could that be related?), I'd be happy to post that but this seems like the relevant sources to me. Also, I'm new to OS development (~ 1 week, but I have been programming for years!), so please forgive my ignorance! Thank you :)
LtG
Member
Member
Posts: 384
Joined: Thu Aug 13, 2015 4:57 pm

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by LtG »

What are you using for testing? Qemu?

I'd suggest debugging, for example gdb and seeing the actual instruction that causes exception as well as checking the relevant registers at that point. Sooner or later you will have to start debugging anyway, so this is as good a time as any to start.

This may be of use: http://wiki.osdev.org/Kernel_Debugging# ... _with_QEMU
Octocontrabass
Member
Member
Posts: 5586
Joined: Mon Mar 25, 2013 7:01 pm

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by Octocontrabass »

underscoretanner wrote:As the title suggests my IDT malfunctions producing an invalid opcode exception when it should actually be reporting a division by zero exception.
I don't see anything in your code that should produce #DE. If you're talking about this line:

Code: Select all

putc('A' / 0);
That is a constant expression, and the compiler will attempt to fold it to a constant value. Since the division is happening at compile time instead of at run time, there will be no #DE here. (Of course, since division by zero is undefined behavior in C, the compiler may do all sorts of wacky things, including assuming this line of code must be unreachable and removing all code paths that lead to it.)

With that said, you probably still shouldn't be getting #UD from this. Now would be a great time to look into using a debugger, although it might be possible to locate the cause just by analyzing a disassembly of your kernel.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by Brendan »

Hi,
Octocontrabass wrote:
underscoretanner wrote:As the title suggests my IDT malfunctions producing an invalid opcode exception when it should actually be reporting a division by zero exception.
I don't see anything in your code that should produce #DE. If you're talking about this line:

Code: Select all

putc('A' / 0);
That is a constant expression, and the compiler will attempt to fold it to a constant value. Since the division is happening at compile time instead of at run time, there will be no #DE here. (Of course, since division by zero is undefined behavior in C, the compiler may do all sorts of wacky things, including assuming this line of code must be unreachable and removing all code paths that lead to it.)

With that said, you probably still shouldn't be getting #UD from this. Now would be a great time to look into using a debugger, although it might be possible to locate the cause just by analyzing a disassembly of your kernel.
Unfortunately, in some cases GCC responds to undefined behaviour by inserting a "UD2" instruction, because someone decided that generating a compile time error would have made it too easy for people to figure out where a problem is. Note: The "UD2" instruction is designed specifically to cause an undefined opcode exception.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
LtG
Member
Member
Posts: 384
Joined: Thu Aug 13, 2015 4:57 pm

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by LtG »

Brendan wrote:Hi,
Unfortunately, in some cases GCC responds to undefined behaviour by inserting a "UD2" instruction, because someone decided that generating a compile time error would have made it too easy for people to figure out where a problem is. Note: The "UD2" instruction is designed specifically to cause an undefined opcode exception.
Do you have any background on that? If it's known at compile time that it's UB then why insert runtime #UD2 instead of doing the sane thing and giving a compile time error?

I'm hoping there's a better reason than stupidity, but there have been some pretty stupid decisions with GCC development in the past..
LtG
Member
Member
Posts: 384
Joined: Thu Aug 13, 2015 4:57 pm

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by LtG »

LtG wrote:
Brendan wrote:Hi,
Do you have any background on that? If it's known at compile time that it's UB then why insert runtime #UD2 instead of doing the sane thing and giving a compile time error?

I'm hoping there's a better reason than stupidity, but there have been some pretty stupid decisions with GCC development in the past..
I think this explains it a bit:
http://blog.llvm.org/2011/05/what-every ... -know.html

So my guess is that the compilers only do it for the dynamic (runtime) cases, because it's the only reasonable thing to do if it's not known at compile time. Maybe some cases that could be proven to be compile time just aren't analyzed deeply enough and they "fall thru" to dynamic and thus runtime #UD2. If that's the case then I do think it's reasonable for sake of higher performance...
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by iansjack »

Brendan wrote: Unfortunately, in some cases GCC responds to undefined behaviour by inserting a "UD2" instruction, because someone decided that generating a compile time error would have made it too easy for people to figure out where a problem is. Note: The "UD2" instruction is designed specifically to cause an undefined opcode exception.
The OP ought to be able to check that possibility very easily by inspecting the generated code.
underscoretanner
Posts: 2
Joined: Sat Jun 24, 2017 8:46 pm

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by underscoretanner »

It seems that Brendan is exactly correct. I have since been able to produce a division by zero exception by disabling optimizations, which makes sense. So it seems to me that this is more of a quirk of GCC rather than something indicative of a problem, however, I was troubled that Bran's guide seems to recommend this as a test for the IDT when it seems not to work with his recommended O2 optimizations. Also, regarding debugging, I should definitely get the hang of that in the OS world. Thank you all for your links and insight! Glad to join the forum :)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: IDT Errors? Exception 6 (Invalid Opcode)

Post by Brendan »

Hi,
underscoretanner wrote:It seems that Brendan is exactly correct. I have since been able to produce a division by zero exception by disabling optimizations, which makes sense. So it seems to me that this is more of a quirk of GCC rather than something indicative of a problem, however, I was troubled that Bran's guide seems to recommend this as a test for the IDT when it seems not to work with his recommended O2 optimizations. Also, regarding debugging, I should definitely get the hang of that in the OS world. Thank you all for your links and insight! Glad to join the forum :)
I wouldn't be too surprised if the code in Bran's Kernel Development tutorial "worked" when it was originally written/published (over a decade ago). Unfortunately it doesn't seem to be updated by it's original author (and isn't on in a Wiki where other people can change it), so there's no warnings or corrections for newer versions of GCC (or anything else).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply