[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
deadlock on ptrace
斉藤@densanと言います。こんにちは。1.5.2で質問があります。
以下の症状は、皆さんのところでは、起こっていないでしょうか。
何かアドバイスいただけると幸いです。
gdbでプログラムをデバッグしている時の話ですが、
runを何回か繰り返しているとシステムが止まってしまいます。
止まる時ですが、あるshellでコマンドを実行しようとすると、
fork1() -> uvm_km_valloc() -> uvm_map() -> vm_map_lock() -> lockmgr() -> ltsleep()
と推移し、スリープしたきりとなります。
起動済みのprocessは動いているのですが、forkできなくなるので、
リセットしかありません。今のところ、
gdbで一回目のrunで止まったことはありませんし、
その他のforkで止まったこともありません。
shellは fork1()以降の処理で、
&kernel_map->lock に対し LK_EXCLUSIVE でロックしようとしますが、
&kernel_map->lock は、すでに LK_SHARED でロックされており、
LK_SHARED ロックの解除を待とうとします。
しかし、LK_SHARED ロックをかけたプロセスが、すでにスリープしているので、
デッドロック状態になっています。
gdbでrunをし、症状が出た時のプログラムの流れです。
trap() -> uvm_fault() -> pmap_page_protect() -> pmap_remove_pv() ->
pmap_free_pv() -> uvm_km_free() -> uvm_unmap() -> vm_map_lock() ->
lockmgr() -> ltsleep()
ページフォールトが発生し、
uvm_fault() の中で最初に呼び出される、uvmfault_lookup()が
&kernel_map->lock に対し、LK_SHAREDでロックしたまま、
上記のようにプログラムが推移することがあり、
LK_EXCLUSIVE でロックしようとして、スリープしてしまいます。
つまり、自分で二重にロックをかけ、デッドロックする場合があるようです。
テキストのようにシェアードされるページにブレークポイントをかけようと、
書き込みを行なう場合に起きるバグではないかと思います。