マルチスレッド アプリケーションのスタック オーバーフローのトラップは、ほとんどの場合、シングルスレッド アプリケーションのトラップと何ら変わりません。それが異なる可能性がある主な方法は、大きなマージンでオーバーフローしている場合です。メインスレッド用。これでも無効なスタック ポインターが残りますがSIGSEGV
、ほとんどの場合、小さなスレッド スタックでは、オーバーフローによってスタック ポインターが別のスレッドのスタックの途中に置かれる可能性があります。進捗。小さなスタックを使用している場合に確認する必要があるもう 1 つの問題は、ガード ページを無効にしていないことです。(ちなみに、この関数は非推奨です)を使用pthread_attr_setstack
しても、自分で設定していない限り、ガード ページは表示されません。使用するpthread_attr_setstacksize
(適切な最新のインターフェイス) はガード ページの割り当てに干渉するべきではありませんがpthread_attr_setguardsize
、オーバーフローが大幅に大きいと思われる場合は、(を使用して) ガード サイズを大きくすることをお勧めします。
そうは言っても、スタックオーバーフローを処理する一般的な手順は、ハンドラーをセットアップし、代替スタックで実行するようにSIGSEGV
設定することです。この最後のポイントは非常に重要です。シグナルが生成された時点ではスタック ポインターが無効であるため、シグナル ハンドラー自体を実行するための代替スタックが必要です。特定のシグナルが代替スタックで処理されるかどうかのフラグはシグナルごとの属性 ( によって設定) ですが、実際の代替スタックはスレッドごとの属性です。すべてのスレッドは、を使用して独自の代替スタックを設定する必要があります。代替スタックのスペースはまたはを介して割り当てることができますが、最も簡単な方法は、自動化することですsigaction
sigaltstack
malloc
mmap
char
スレッド開始関数で約 2 ~ 4k のサイズの配列を使用し、それを代替スタックに使用します。基本的に、これはスレッドのスタックの下部に小さな範囲を予約して、スタックの上部がオーバーフローした後にシグナル ハンドラー用の緊急スタック スペースとして使用することを意味します。