注意:这不是我遇到的问题,但它是我想要的东西 喜欢理解(仅仅因为我 想成为一个更好的人,并希望 人类的视野 理解)。
在Raymond Chen的book的奖励章节中,
Raymond举了一个声卡驱动程序中的错误示例:
原始函数,调用于 硬件中断时间,看起来像 这在DDK:
void FAR PASCAL midiCallback(NPPORTALLOC pPortAlloc, WORD msg, DWORD dwParam1, DWORD dwParm2) { if (pPostAlloc->dwCallback) DriverCallBack(pPortalloc->dwCallback, HIWORD(pPortalloc->dwFlags), pPortalloc->hMidi, msg, dwParam1, dwParam2); }
他们的功能版本看起来 像这样:
void FAR PASCAL midiCallback(NPPORTALLOC pPortAlloc, WORD msg, DWORD dwParam1, DWORD dwParm2) { char szBuf[80]; if (pPostAlloc->dwCallback) { wsprintf(szBuf, " Dc(hMidi=%X,wMsg=%X)", pPortalloc->hMidi, msg); #ifdef DEBUG OutputDebugString(szBuf); #endif DriverCallBack(pPortalloc->dwCallback, HIWORD(pPortalloc->dwFlags), pPortalloc->hMidi, msg, dwParam1, dwParam2); } }
零售代码中不仅有剩余的调试内容,而且还有 调用非中断安全功能 在硬件中断时间。如果
wsprintf
功能得到了 丢弃,系统将采取 一段不存在的故障 硬件中断,导致a 快死了。
现在,如果我正在查看该代码,我不会猜到调用库函数wsprintf会出现问题。如果我的驱动程序代码需要使用Win32 API会发生什么?
什么是段错误?我理解页面错误的概念:我需要的代码位于已经换成硬盘驱动器的页面上,并且需要在代码执行之前从硬盘驱动器返回可以继续当我们进入设备驱动程序的中断时,segment fault是什么?
页面错误是否等同于段错误的保护模式?如何避免段错误? Windows是否会换掉设备驱动程序代码?我如何阻止“ wsprintf被丢弃”?什么会导致wsprintf“被丢弃”?什么是“丢弃”?丢弃的优点是什么?什么时候 un 被丢弃了
为什么从驱动程序内部调用API调用不好,以及如何解决它?
答案 0 :(得分:3)
分段错误通常是指无效的内存访问。在大多数现代操作系统中,产生seg-fault的机制也用于提供请求分页机制。他们倾向于将内存页面“交换”到光盘并将其标记为无效,下一次指令访问该内存位时,内核会识别出它不是真正错误,将在内存中翻页。
Windows无法在某些上下文中处理页面错误,其中一个处于中断状态。这就是它的设计方式。例如,假设您在代码中出现页面错误,从磁盘驱动器读取内存页数据,怎么可能处理这种情况?因此,他们定义了允许页面操作模式和不允许页面操作模式的某些限制。如果在中断中导致页面错误,内核将强制执行BSOD。
如果您需要执行可能需要分页的操作,您应该在中断上下文中执行的操作是在中断处理程序中对所谓的延迟过程调用(DPC)进行排队。然后在DPC级别执行DPC(如果您阅读了DDK函数的一些描述,您会看到提到的内容)。 DPC级别可以页面,因此您可以使用您需要的任何功能。
至于驱动程序的东西,你可以将一些代码标记为不可分页,你可以分配非分页池,这是你可以访问的内存而不会导致页面错误。 wsprintf可以被分页,因为没有人使用它,内核回收内存。