问题
I am trying to write a ISR for the General Protection Fault (GP#13) on x86. I am unable to figure out from the INTEL docs as to how I can find out the faulting address causing the exception. I know that for Page fault exceptions (GP#14) the cr2 register holds the faulting address. Any help is appreciated.
回答1:
All references I make here are from AMD64 Architecture Programmer's Manual Volume 2: System Programming, which also describes the legacy protected-mode (i.e., x86) behavior.
Figure 8-8 on page 240 shows the stack layout after an interrupt to the same privilege level (that is, the stack layout when an ISR is entered):
In Section 8.2.14, you can see that #GP
provides an error code and the following is also of interest:
Program Restart.
#GP
is a fault-type exception. In most cases, the saved instruction pointer points to the instruction that caused the#GP
. See “Exceptions During a Task Switch” on page 230 for a description of the consequences when this exception occurs during a task switch.
The referenced section mentions the following:
An exception can occur during a task switch while loading a segment selector. Page faults can also occur when accessing a TSS. In these cases, the hardware task-switch mechanism completes loading the new task state from the TSS, and then triggers the appropriate exception mechanism. No other checks are performed. When this happens, the saved instruction pointer points to the first instruction in the new task.
So, unless you are using hardware task switching, the saved instruction pointer always point to the faulting instruction.
To get the address of the faulting instruction, simple get the saved EIP
and CS
values from the stack in your ISR. (If you're using a flat memory model and all your segments cover the whole 4GB, the saved CS
is of no interest, of course).
movl 4(%esp), %eax
movw 8(%esp), %ebx
Now, EAX
contains the saved EIP
and EBX
the saved CS
.
Edit: Of course, as pointed out by Alex in the comments, in case the #GP
was caused by a memory access and you want the address of the accessed memory, you will need to decode the faulting instruction.
来源:https://stackoverflow.com/questions/10360888/identifying-faulting-address-on-general-protection-fault-x86