Identifying faulting address on General Protection Fault (x86)

人盡茶涼 提交于 2021-02-07 13:13:00

问题


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):

Stack After Interrupt to Same Privilege Level

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, EAXcontains 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!