1

注:これは私が経験している問題ではありませんが、理解したいことです(私がより良い人間になり、人間の理解の地平をさらに広げたいという理由だけで)。

レイモンド・チェンのボーナスの章で、

代替テキスト

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、システムはハードウェア割り込み内でセグメントが存在しない障害を起こし、かなり迅速に停止します。

そのコードを見ていると、ライブラリ関数wsprintfの呼び出しが問題になるとは思いもしませんでした。ドライバーコードでWin32APIを使用する必要がある場合はどうなりますか?

セグメンテーション違反とは何ですか?ページフォールトの概念を理解しています。必要なコードは、ハードドライブにスワップアウトされたページにあり、コードの実行を続行する前にハードドライブから戻る必要があります。デバイスドライバーの割り込み内にいるときのセグメンテーション違反とは何ですか?

ページフォールトは、セグメントフォールトと同等の保護モードですか?セグメンテーション違反を回避するにはどうすればよいですか?Windowsがデバイスドライバーコードを交換することはありますか?「wsprintfが破棄されるのを防ぐにはどうすればよいですか?」wsprintfが「破棄」される原因は何ですか?「廃棄」とは何ですか?廃棄することの美徳は何ですか?何かが捨てられていないとき

ドライバーの内部からAPI呼び出しを呼び出すのはなぜ悪いのですか、そしてそれをどのように回避するのでしょうか?

4

1 に答える 1

3

セグメンテーション違反は通常、無効なメモリアクセスを指します。最新のオペレーティングシステムのほとんどでは、セグメンテーション違反を生成するメカニズムを使用して、デマンドページングメカニズムを提供しています。彼らがしがちなのは、メモリのページをディスクに「スワップ」して無効としてマークすることです。次に命令がメモリのそのビットにアクセスすると、カーネルはそれが実際にはエラーではないと認識し、メモリにページインします。

Windowsは、特定のコンテキストでページフォールトを処理できず、そのうちの1つが割り込みになっています。それはまさにそれが設計されている方法です。たとえば、ディスクドライブからメモリページデータを読み取るコードでページフォールトが発生したとしたら、そのような事態をどのように処理できるでしょうか。したがって、ページングを許可する操作モードと許可しない操作モードに関する特定の制限を定義します。割り込みでページフォールトが発生すると、カーネルはBSODを強制します。

ページングが必要になる可能性のある処理を実行する必要がある場合に、割り込みコンテキストで実行することになっているのは、割り込みハンドラーで遅延プロシージャ呼び出し( DPC )と呼ばれるものをキューに入れることです。次に、DPCがDPCレベルで実行されます(DDK関数の説明の一部を読むと、言及されていることがわかります)。DPCレベルはページングできるため、必要な機能を使用できます。

ドライバーに関しては、コードの一部をページング不可としてマークしたり、ページフォールトを発生させずにアクセスできるメモリである非ページングプールを割り当てたりすることができます。wsprintfは、誰も使用しておらず、カーネルがメモリを再利用しているため、ページアウトされる可能性があります。

于 2010-01-06T19:06:53.620 に答える