Mac OS Xのカーネル Xnuのメモ書き

例外処理



例外のエントリポイント

osfmk/i386/locore.s::alltraps
IDTに設定されているエントリポイント
user_trap()もしくはkernel_trap()を呼ぶ

例外処理

user_trap()
User Modeで例外が発生した場合の例外ハンドラ。

ページフォルトやFPUなどの一部の例外を除いて、i386_exception()を呼び出して例外の発生したプロセスを終了させる。

ページフォルトはvm_fault()で処理をする。ページフォルトには不正なアドレスにアクセスした場合などプロセスを停止させるべきケースと、物理ページの遅延割り当て(デマンドページング)など、例外をハンドリング後プロセスの実行を継続すべきケースがある。これにはvm_fault()終了後、呼び出されるuser_page_fault_continue()で処理を別けている。vm_fault()がエラーリターンしていた場合は、i386_exception()を呼び出しプロセスを終了させる。vm_fault()が例外のハンドリングに成功して正常終了した場合はthread_exception_return()を呼び出して例外処理を終了する。


kernel_trap()
Kernel Modeで例外が発生した場合の例外ハンドラ。

ページフォルトやFPUなどの一部の例外を除いて、システムを停止させる。

本ルーチンがTRUEを返すと呼び出し元ルーチンでreturn_from_kernel()を呼び例外処理を終了する。FALSEを返すとpanic_trap()を呼び出してシステムを停止させる。

ページフォルトはuser_trap()と同様vm_fault()で処理をする。不正アドレスへのアクセスなどでvm_fault()がエラーリターンした場合は、システムを停止させる。

例外処理の終了

thread_exception_return()
スタックを切り替えてreturn_from_trap()を呼び出す。

return_from_trap()
未処理のASTがないかチェックし、あった場合はi386_astintr()で処理をする。なければ、return_to_user()でユーザー空間に戻る。

return_from_kernel()
カーネルモードから戻る。

例外ベクタテーブルの設定

ディスクリプタテーブルの作成
osfmk/i386/idt.s
        .data
Entry(idt)
.text

EXCEPTION(0x00,t_zero_div)
<== IDTのエントリを作成してalltrapsへの
ジャンプルーチンを作る EXCEP_SPC(0x01,t_debug)
INTERRUPT(0x02) /* NMI */
EXCEP_USR(0x03,t_int3)
EXCEP_USR(0x04,t_into)
EXCEP_USR(0x05,t_bounds)
EXCEPTION(0x06,t_invop)
:
:

IDTRの設定はstart.s::spag_startで行なう。

例外発生時の処理の流れ




最終更新 2006/06/08 09:23:09 - kztomita
(2006/03/27 13:05:13 作成)
添付ファイル
exception.png - kztomita


最近更新したページ