Linuxカーネル内のスタックの適切な説明を探していますが、有用なものを見つけるのが驚くほど難しいと感じています。
スタックはほとんどのシステムで4kに制限され、他のシステムでは8kに制限されていることを知っています。各カーネルスレッド/下半分には独自のスタックがあると仮定しています。割り込みが発生した場合、現在のスレッドのスタックを使用することも聞いたことがありますが、これに関するドキュメントは見つかりません。私が探しているのは、適切なデバッグルーチンがある場合、スタックがどのように割り当てられるかです(特定の問題のためにスタックオーバーフローが疑われており、カーネルを警察にコンパイルすることが可能かどうかを知りたいスタックサイズなど)。
ドキュメントが不足している理由は、それがかなりアーキテクチャに依存する領域だからです。コードは本当に最高のドキュメントです。たとえば、THREAD_SIZE
マクロは(アーキテクチャに依存する)スレッドごとのカーネルスタックサイズを定義します。
スタックは alloc_thread_stack_node()
に割り当てられます。 struct task_struct
のスタックポインターは dup_task_struct()
で更新されます。これは、スレッドのクローン作成の一部として呼び出されます。
カーネルは スタックの最後にカナリア値STACK_END_MAGIC
を置く によって、カーネルスタックオーバーフローをチェックします。ページフォールトハンドラーで、カーネルスペースでフォールトが発生すると、このカナリアがチェックされます-たとえば、スタックがOopsメッセージの後にメッセージThread overran stack, or stack corrupted
を出力する x86フォールトハンドラー を参照してください。カナリアが破壊されました。
もちろん、これはallスタックオーバーランでは発生せず、スタックカナリアを破壊するもののみです。ただし、Oops出力から、スタックオーバーランが発生したかどうかを常に確認できる必要があります。これは、スタックポインターがtask->stack
を下回っている場合です。
ulimit
コマンドを使用して、プロセススタックサイズを決定できます。システムで8192 KiBを取得します。
$ ulimit -s
8192
プロセスの場合、ulimit
コマンド(_-s
_オプション)を使用してプロセスのスタックサイズを制御できます。スレッドの場合、デフォルトのスタックサイズは大きく異なりますが、pthread_attr_setstacksize()
を呼び出すことで制御できます(pthreadsを使用している場合)。
ユーザーランドスタックを使用した割り込みについては、ユーザーランドメモリへのアクセスはカーネル、特に割り込みルーチンからの面倒な作業であるため、多少疑問があります。しかし、私は確かに知りません。