1

PROT_NONEをmprotect持つセグメントであり、SIGSEGVによって処理される書き込みが原因で発生したsigaction場合、sa_sigactionを使用して障害が発生したアドレスを見つけることができsiginfo_tますsi_addr。しかし、書き込まれようとしたデータとデータの長さを見つける方法はありますか?

プロジェクトでコピーオンライトメカニズムを試しているため、これを実行しようとしています。

4

3 に答える 3

2

プロセスが書き込もうとしたデータが見つからないか、そのサイズを尋ねる意味がありません。データを取得できた場合は、カーネルがすでにデータをどこかにコピーしたことを意味します。

SIGSEGVページ全体で を取得します。つまり、プロセスが書き込んでいるデータに関係なく、最初にバイトを書き込もうとしたときに、ページごとに 1 つのエラーが発生します。したがって、必要なことは次のとおりです。

  • ページの状態を追跡する
  • 必要に応じて権限を増やします
于 2012-02-14T08:50:07.813 に答える
2

カーネルは知らないので、あなたに教えることはできません。しかし、必要に応じて調べることができます。スタックでエラーが発生したコード アドレスがあるので、そこでコードを逆アセンブルして、それを把握することができます。他に知る方法はありません (理由が明らかでない場合は、考えてみてください)。命令が保護されたページに触れたためにエラーが発生しました。これは、アセンブリ コードを分析しない限りわかりません。

エラーが発生したページだけを知っていても、どのオブジェクトを扱っているかがわからない場合は、そうするようにデザインを変更することを再検討することを強くお勧めします。(posix_memalign、もしかして?)

更新: すべてのコンテキスト スイッチで呼び出されるフックが必要であることを忘れないでください。各フックでページをコピーする必要がある場合があります。例えば:

  1. コンテキスト A は、CoW セマンティクスを使用してページ Q にアクセスしています。コンテキスト A は、ページへの読み取り専用アクセスを取得します。

  2. コンテキスト B は、CoW セマンティクスを使用してページ Q にアクセスしています。コンテキスト B は、ページへの読み取り専用アクセスを取得します。

  3. コンテキスト A がページを変更し、コンテキスト B のコピーを作成します。コンテキスト A はページへの書き込みアクセス権を持ち、ページを変更します。

  4. コンテキスト A からコンテキスト B に切り替えます。この時点で、コンテキスト B 用に作成したページのコピーに切り替える必要があります。

これを回避するもう 1 つの方法は、コンテキストにページのマップとロックへの特定の呼び出しを行わせることです。コンテキストがコンテキストスイッチ全体でマッピングを保持できるようにすると、これは機能しません。少なくとも、多くの追加作業がなければ機能しません。

于 2012-02-14T08:52:07.087 に答える