识别通用保护故障 (x86) 上的故障地址 [英] Identifying faulting address on General Protection Fault (x86)

查看:39
本文介绍了识别通用保护故障 (x86) 上的故障地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为 x86 上的一般保护错误 (GP#13) 编写 ISR.我无法从 INTEL 文档中弄清楚如何找出导致异常的错误地址.我知道对于页面错误异常 (GP#14),cr2 寄存器保存错误地址.任何帮助表示赞赏.

解决方案

我在这里所做的所有参考都来自 在 评论,以防#GP 是由内存访问引起的,而您想要访问内存的地址,则需要对出错指令进行解码.

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.

解决方案

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

这篇关于识别通用保护故障 (x86) 上的故障地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆