Recovering from exceptions?
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
Recovering from exceptions?
My OS is working alright, I just have one problem, when an exception fires (ie. GPF) my OS basically crashes, nothing I can do about it... Problem is, I want to be able to say to the user "Hey you, a GPF just ocurred? What on earth were you doing?" and then give them an option to continue running the OS or just sit there staring at some trippy black and white text...
How exactly do I recover from an exception to be able to continue where the exception left off?
How exactly do I recover from an exception to be able to continue where the exception left off?
- mathematician
- Member
- Posts: 437
- Joined: Fri Dec 15, 2006 5:26 pm
- Location: Church Stretton Uk
Not much point in asking the user what he thinks he is up to, because a GPF would also certainly be the result of a bug in the program, and there is nothing he can do about that. Although a General Protection Exception comes complete with an error code, which in theory might allow the handler to sort out what's wrong an put it right, in practice probably all you can do is to display an error message, and close down the application.
The Intel manual gives a list of 31 possible causes of a GPF, and if you wanted to try and recover from an exception your handler would have to treat each one seperately.
The Intel manual gives a list of 31 possible causes of a GPF, and if you wanted to try and recover from an exception your handler would have to treat each one seperately.
- mathematician
- Member
- Posts: 437
- Joined: Fri Dec 15, 2006 5:26 pm
- Location: Church Stretton Uk
Not much point in asking the user what he thinks he is up to, because a GPF would also certainly be the result of a bug in the program, and there is nothing he can do about that. Although a General Protection Exception comes complete with an error code, which in theory might allow the handler to sort out what's wrong an put it right, in practice probably all you can do is to display an error message, and close down the application.
The Intel manual gives a list of 31 possible causes of a GPF, and if you wanted to try and recover from an exception your handler would have to treat each one seperately.
The Intel manual gives a list of 31 possible causes of a GPF, and if you wanted to try and recover from an exception your handler would have to treat each one seperately.
Does your exception handler work ? Then, of course you can do some text output and ask the user.
But if you want the interrupted program to continue at the instruction after the one which has thrown the exception, you have a problem. The return address you got is the address of the instruction which has thrown the error, not the address of the instruction after this one and it's impossible to find out the address of the next instruction, except you have a disassembler-module which is able to determine the length of an instruction.
But there is another way: You can pass the exception to the exception handler of the process which has thrown the exception. Lets say the process uses "try...catch", the exception handler can continue at the "catch" part.
But if you want the interrupted program to continue at the instruction after the one which has thrown the exception, you have a problem. The return address you got is the address of the instruction which has thrown the error, not the address of the instruction after this one and it's impossible to find out the address of the next instruction, except you have a disassembler-module which is able to determine the length of an instruction.
But there is another way: You can pass the exception to the exception handler of the process which has thrown the exception. Lets say the process uses "try...catch", the exception handler can continue at the "catch" part.
Hi,
How do you know later code doesn't rely on things that were meant to be done by the instruction you've skipped?
Do you test to see if the code that was running at the time actually caused the exception? For e.g. a messed up IDT descriptor for an IRQ can cause a general protection fault (where the code that was running before the CPU tried to start the IRQ handler has absolutely nothing to do with the problem).
In general when a critical error occurs (i.e. an exception that isn't intended, or some sort of condition detected by the kernel that isn't right) you want to put some debugging information somewhere (to help developers fix their problems) and terminate what-ever caused the problem.
The debugging information could mean displaying the values that were in registers *before* the instruction tried to execute (e.g. blue screen of death) or adding these details to the end of a system log, it could be a core dump, or it could be a nice little dialog box saying "This program crashed, do you want to automatically email diagnostic information to the developers of this program?".
You can even have different actions depending on what crashed - for example, a blue screen of death if the kernel crashed, a dialog box if an application crashed and some details added to a log if a device driver crashes.
Cheers,
Brendan
How do you know that the instruction is one byte long?pcmattman wrote:By one, to skip the code that brought the exception along.
How do you know later code doesn't rely on things that were meant to be done by the instruction you've skipped?
Do you test to see if the code that was running at the time actually caused the exception? For e.g. a messed up IDT descriptor for an IRQ can cause a general protection fault (where the code that was running before the CPU tried to start the IRQ handler has absolutely nothing to do with the problem).
In general when a critical error occurs (i.e. an exception that isn't intended, or some sort of condition detected by the kernel that isn't right) you want to put some debugging information somewhere (to help developers fix their problems) and terminate what-ever caused the problem.
The debugging information could mean displaying the values that were in registers *before* the instruction tried to execute (e.g. blue screen of death) or adding these details to the end of a system log, it could be a core dump, or it could be a nice little dialog box saying "This program crashed, do you want to automatically email diagnostic information to the developers of this program?".
You can even have different actions depending on what crashed - for example, a blue screen of death if the kernel crashed, a dialog box if an application crashed and some details added to a log if a device driver crashes.
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.
I didn't try it yet, but may be it will work. What if to place trap gate instead of int gate in the descriptor serving GPF, for example? AFAIR, trap gate differs from int gate only in value of EIP saved: in the case of trap gate EIP after instruction which arises exception is saved. But I don't know, allow CPU to do it or not. I think that differences between traps and ints are hardwired in CPU by numbers (exceptions N1 and N3 are traps, other are interrrupts), so it doesn't matter what stands in descriptor serving interrupt, but may be I am wrong .
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
exceptions are either traps or faults: traps store the eip of the next instruction, faults store the eip of the failing instruction.
Interrupt gates and trap gates work different: interrupt gates clear IF upon entry, while trap gates keep IF as-is.
conclusion: the IDT has no influence of wether the eip before or after the faulty instruction is stored.
Interrupt gates and trap gates work different: interrupt gates clear IF upon entry, while trap gates keep IF as-is.
conclusion: the IDT has no influence of wether the eip before or after the faulty instruction is stored.