2025/04/15 17:13 The case of the UI thread that hung in a kernel call

ロボ子、今回のITニュースはなかなか興味深いぞ。UIスレッドがカーネル内でハングする問題じゃ。

UIスレッドのハングですか。具体的にはどのような状況だったのでしょう?

ふむ、どうやらウォッチドッグスレッドがUIスレッドを監視していて、スタックトレースを取得しようとしたのが原因らしいのじゃ。

ウォッチドッグスレッドがUIスレッドを一時停止させた、と。

そうじゃ。UIスレッドが例外処理中に一時停止されて、ウォッチドッグスレッドがスタックを解析しようとした時に、UIスレッドが関数テーブルをロックしていたからデッドロックが発生した、とのことじゃ。

なるほど。ウォッチドッグスレッドは`ntdll!ZwWaitForAlertByThreadId`内でロック待ち状態だったのですね。UIスレッドは`nt!MmProtectVirtualMemory`内で一時停止されていた、と。

その通り!ここで重要なのは、自プロセス内のスレッドを一時停止すると、デッドロックが発生する可能性があるということじゃ。UIスレッドがプログラムに必要なリソースを保持している場合じゃからな。

カーネルは、スレッドがユーザーモードロックを保持しているかどうかを判断できないため、スレッドの一時停止をブロックできない、というのもポイントですね。

そうじゃな。カーネルは内部カーネルロックを保持しているスレッドは一時停止しないらしいが、ユーザーモードロックまでは面倒を見てくれないのじゃ。

解決策として、スレッドの一時停止とスタックの取得は別のプロセスから行う必要がある、とありますが、具体的にはどのように実装するのでしょうか?

ふむ、例えば、デバッグ用のプロセスを別途用意して、そこから問題のプロセスのスレッドを一時停止させてスタックトレースを取得する、という方法が考えられるのじゃ。プロセスを分けることで、ロックの問題を回避できる。

なるほど、プロセスを分離することで、デッドロックのリスクを回避できるのですね。勉強になります。

じゃろ? しかし、スレッドを一時停止させるのは、まるで時間を止める能力みたいじゃな。私にもそんな能力があれば、締め切り前に時間を止めて、ゆっくりコードを書けるのにのう…。

博士、時間を止めても、結局作業が終わらなければ意味がないですよ。それに、時間が止まっている間、博士はずっと同じ姿勢でいなければならないので、体が固まってしまうかもしれません。

むむ、それは困るのじゃ。やはり、地道に頑張るしかないか。…ところでロボ子、もし時間を止められるとしたら、何をする?

私は、止まっている時間の中で、全てのバグを修正します。

ロボ子らしい! でも、バグも時間も止まってたら、永遠に修正が終わらないんじゃないかの?
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
