スタックがいっぱいで、まったく移植可能でないことを検出するのは非常に困難です。最大の問題の 1 つは、スタック フレームのサイズが可変であることです (特に、可変長配列を使用する場合、これは、人々が以前に で行っていたことを行うためのより標準的な方法ですalloca()
)。したがって、数値のような単純なプロキシを使用できませんスタック フレームの。
ほとんど移植可能な最も簡単な方法の 1 つは、スタック上の既知の深さに変数 (おそらく変数へchar
のポインターが a になるような型char*
) を配置し、そのポイントから変数 (同じの) までの距離を測定することです。 type) を単純なポインター演算によって現在のスタック フレームに格納します。割り当てようとしているスペースの見積もりを追加すると、スタックが爆発しようとしているかどうかを推測できます。これに関する問題は、スタックが成長している方向がわからないことです (いいえ、すべてが同じ方向に成長するわけではありません!)、スタック空間のサイズを計算すること自体がかなり面倒です (システム制限などを試してみてください。さらに、ハッキング率が非常に高いです。
32 ビット Windows でのみ使用されているのを私が見たもう 1 つのトリックは、alloca()
十分なスペースを確保し、十分なスペースがない場合に発生するシステム例外を処理することでした。
int have_enough_stack_space(void) {
int enough_space = 0;
__try { /* Yes, that's got a double-underscore. */
alloca(SOME_VALUE_THAT_MEANS_ENOUGH_SPACE);
enough_space = 1;
} __except (EXCEPTION_EXECUTE_HANDLER) {}
return enough_space;
}
このコードは非常に移植性が低く (たとえば、64 ビット Windows で動作するとは考えないでください)、古い gcc でビルドするには、代わりに面倒なインライン アセンブラが必要です。構造化された例外処理 (これが使用されます) は、Windows で最も厄介な黒魔術の 1 つです。(そして、コンストラクトreturn
の内部からではありません。)__try