注:这不是我正在经历的问题,但我想要理解它(只是因为我想成为一个更好的人,并推动人类理解的地平线)。
在Raymond Chen's book的奖励章节中,
Raymond给出了声卡驱动程序中的一个bug的例子:
在硬件中断时调用的原始函数在
中如下所示:
void FAR PASCAL midiCallback(NPPORTALLOC pPortAlloc,WORD消息,双字dwParam1,双字dwParm2) { if (pPostAlloc>dwCallback) DriverCallBack(pPortalloc->dwCallback,HIWORD(pPortalloc->dwFlags),pPortalloc->hMidi,msg,dwParam1,dwParam2);}
他们的函数版本如下所示:
void FAR PASCAL midiCallback(NPPORTALLOC pPortAlloc,WORD消息,DWORD dwParam1,DWORD dwParm2) { char szBuf80;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
函数被丢弃,系统将在硬件中断中接受一个段不存在的故障,这将导致相当快的死亡。
现在,如果我看着这些代码,我不会想到对库函数的调用会是一个问题。如果我的驱动程序代码需要使用Win32应用程序接口,会发生什么?
什么是数据段故障?我理解页面错误的概念:我需要的代码位于已经换出到硬盘驱动器的页面上,并且需要从硬盘驱动器取回,然后代码才能继续执行。当我们在设备驱动程序的中断中时,什么是segment fault?
页面错误是否等同于segment-fault?的保护模式如何避免网段故障?Windows有没有换出设备驱动程序代码?我如何阻止"wsprintf被丢弃“?什么会导致wsprintf被“丢弃”?什么是“丢弃”?丢弃有什么好处?When it _un_discarded
为什么从驱动程序内部调用API调用是不好的,以及如何解决它?
发布于 2010-01-07 03:06:54
分段故障通常指的是无效的存储器访问。在大多数现代操作系统中,产生seg错误的机制也被用来提供请求分页机制。它们倾向于做的是将内存的页面“交换”到磁盘上,并将它们标记为无效,下一次指令访问该内存位时,内核会认识到这并不是一个真正的错误,并会在内存中分页。
Windows无法处理某些上下文中的页面错误,其中一个处于中断状态。这就是它的设计方式。例如,假设你在从磁盘驱动器读取内存页面数据的代码中遇到页面错误,它如何处理这种情况呢?因此,它们定义了允许分页和不允许分页操作模式的某些限制。如果您在中断中导致页面错误,内核将强制执行BSOD。
在中断上下文中,如果您需要做一些可能需要分页的事情,您应该做的是在中断处理程序中对所谓的延迟过程调用(DPC)进行排队。然后在DPC级别执行DPC (如果您阅读一些DDK函数的描述,就会看到上面提到的内容)。DPC级别可以分页,所以你可以使用任何你需要的函数。
至于驱动程序,您可以将一些代码标记为不可分页,并且可以分配非分页池,这是您可以访问的内存,而不会导致分页错误。wsprintf可能会被调出,因为没有人使用它,内核会回收内存。
https://stackoverflow.com/questions/2015389
复制相似问题