How to handle certain interrupts?
How to handle certain interrupts?
Hey guys, I'm working on my interrupts still and I've got some questions.
When I try a divide by 0, it obviously raises an exception, which my interrupt handler successfully responds to.
However, it simply loops to the interrupt handler, over and over and over again. I'm guessing this means the program counter isn't continuing past the instruction.
So my question to you is, how should I handle exceptions like this? Should I advance the program counter or should I simply let the program look like this?
When I try a divide by 0, it obviously raises an exception, which my interrupt handler successfully responds to.
However, it simply loops to the interrupt handler, over and over and over again. I'm guessing this means the program counter isn't continuing past the instruction.
So my question to you is, how should I handle exceptions like this? Should I advance the program counter or should I simply let the program look like this?
Hexciting: An open source hex editor for the command line.
https://sourceforge.net/projects/hexciting/
https://sourceforge.net/projects/hexciting/
-
- Member
- Posts: 153
- Joined: Sun Jan 07, 2007 9:40 am
- Contact:
Re: How to handle certain interrupts?
Handle it any way you want. A #DIV0 is something the processor cant do. If the exception handler doesnt do anything with it then there will continuous exceptions. If you have some built in exception handling then you can advance to the exception handler (given care of course). You can terminate the thread/process with an error, etc. Its your OS, define the use case and implement.
- Troy Martin
- Member
- Posts: 1686
- Joined: Fri Apr 18, 2008 4:40 pm
- Location: Langley, Vancouver, BC, Canada
- Contact:
Re: How to handle certain interrupts?
You should have it ending with in iret or iretd instruction so it works correctly. At least I think it should, I just halt on #DIV0.
Re: How to handle certain interrupts?
If it loops forever inside of the int handler without ever returning it may be a possible stack problem (I had that happen before). Remember the processor pushes values on the stack when the handler is called so you need to pop them before iretd.
Also, insure you clear IF during the execution of the int handler to prevent any interruptions (pun intended )
Also, insure you clear IF during the execution of the int handler to prevent any interruptions (pun intended )
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: How to handle certain interrupts?
So how could I do this?
I'm used to MIPS programming where the exception stores the program counter before jumping to the exception handling. I'm under the impression that EIP is extended instruction pointer, rather than exception instruction pointer now.
My question then is, how can I store the program counter, and in certain cases (divide by zero), increment it to skip an instruction?
I'm used to MIPS programming where the exception stores the program counter before jumping to the exception handling. I'm under the impression that EIP is extended instruction pointer, rather than exception instruction pointer now.
My question then is, how can I store the program counter, and in certain cases (divide by zero), increment it to skip an instruction?
Hexciting: An open source hex editor for the command line.
https://sourceforge.net/projects/hexciting/
https://sourceforge.net/projects/hexciting/
Re: How to handle certain interrupts?
You dont need to store the program counter -- the processor pushes it on the stack in the following format when the int handler is called. In other words, this is the stack frame when the interrupt handler is called:
The return cs:eip will point to the faulting instruction that had the divide by 0.
What you want to do next is entirely up to you. You can try skipping the current instruction by incrementing eip (not recommended as it is hackish but may or may not work), or terminate the current process (Most systems seem to do this).
I dont know of a method to determine the instruction size given only a location in memory so I do not know of a method to determine the amount of bytes needed to increment eip to skip the next instruction. A project that I worked on incremented it by 2 when a problem happens; but it never really worked
Code: Select all
+---------------+ -- Bottom of stack
| EFLAGS |
+---------------+
| Return CS |
+---------------+
| Return EIP |
+---------------+ < esp points here
What you want to do next is entirely up to you. You can try skipping the current instruction by incrementing eip (not recommended as it is hackish but may or may not work), or terminate the current process (Most systems seem to do this).
I dont know of a method to determine the instruction size given only a location in memory so I do not know of a method to determine the amount of bytes needed to increment eip to skip the next instruction. A project that I worked on incremented it by 2 when a problem happens; but it never really worked
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
-
- Member
- Posts: 153
- Joined: Sun Jan 07, 2007 9:40 am
- Contact:
Re: How to handle certain interrupts?
EIP is on the stack already, it points to the failed instruction.samoz wrote:My question then is, how can I store the program counter
Think about it. A DIV instruction is normally for a purpose and the result will normally be used for something. If you skip the instruction and continue processing there will likely be unexpected results. It's best to forward to an exception handler or terminate the process/thread.samoz wrote:...and in certain cases (divide by zero), increment it to skip an instruction?
Re: How to handle certain interrupts?
I had the same problem and infact it turned out NOT to be the stack. mask your IRQs some of them cause infinite loops because they are handled. If that does not help then check your asm code and make sure you pop everything you push.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
Currently - Busy with FAT12 driver and VFS
Re: How to handle certain interrupts?
Hi,
Have a look at this link to Sandpile.org. This outlines whether each CPU exception is a trap or fault.
I would strongly suggest (like some of the other posters) that you halt / terminate the current process on a #DE. Returning control to the process having updated EIP would leave the program in a very unstable indeterminate state.
Cheers,
Adam
Have a look at this link to Sandpile.org. This outlines whether each CPU exception is a trap or fault.
I would strongly suggest (like some of the other posters) that you halt / terminate the current process on a #DE. Returning control to the process having updated EIP would leave the program in a very unstable indeterminate state.
Cheers,
Adam
Re: How to handle certain interrupts?
Killing a process sounds like a valid idea for some of these.
Currently though, I'm still writing kernel code, no actual processes or even user space yet. I suppose I'll need to re-address my interrupts once my OS becomes a little more developed...
Currently though, I'm still writing kernel code, no actual processes or even user space yet. I suppose I'll need to re-address my interrupts once my OS becomes a little more developed...
Hexciting: An open source hex editor for the command line.
https://sourceforge.net/projects/hexciting/
https://sourceforge.net/projects/hexciting/
Re: How to handle certain interrupts?
If you get any form of an exception within kernel code, then it is a bug in the kernel that should be fixed. Dont try to bypass the bug in the exception handler as it can cause more harm then good.
If the current process is the kernel itself, or a system device driver, it should be properly handled as well. ie; perhaps restarting the driver, or falling back to a more compatable driver and displaying a warning, or displaying an error and rebooting the system. There are more options depending on what the problem is...
If the current process is the kernel itself, or a system device driver, it should be properly handled as well. ie; perhaps restarting the driver, or falling back to a more compatable driver and displaying a warning, or displaying an error and rebooting the system. There are more options depending on what the problem is...
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: How to handle certain interrupts?
An exception to this rule may be the page fault exception, if your brave (and smart) enough to page your kernel out. (Brave because tracking all the dependencies of your paging code may proove to be rather tricky, and if you get it wrong you end up recursively faulting)
Re: How to handle certain interrupts?
Certain exceptions have the IP at the start of the exception, so the OS (or application) can correct the situation. Iirc, div/0 is one of these. This means that if you do not fix what caused the div/0, it will happen over and over again.samoz wrote:When I try a divide by 0, it obviously raises an exception, which my interrupt handler successfully responds to. However, it simply loops to the interrupt handler, over and over and over again. I'm guessing this means the program counter isn't continuing past the instruction. So my question to you is, how should I handle exceptions like this? Should I advance the program counter or should I simply let the program look like this?
JAL