[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 でロックしようとして、スリープしてしまいます。
つまり、自分で二重にロックをかけ、デッドロックする場合があるようです。

テキストのようにシェアードされるページにブレークポイントをかけようと、
書き込みを行なう場合に起きるバグではないかと思います。