実行時に現在のスタックサイズを測定する大まかな方法は、宣言することです
static void* mainsp;
次にmain
、例から始めます。
int main(int argc, char**argv) {
int here;
mainsp = (void*) &here;
次に、リーフルーチン内で、呼び出しスタックが十分に深い場合は、次のようなことを行います。
int local;
printf ("stack size = %ld\n",
(long) ((intptr_t) &local - (intptr_t) mainsp));
アプリケーションの完全なソースコードから静的に推定する必要なスタックサイズは、一般に決定不可能であり(再帰、関数ポインターを考えてください)、実際には非常に困難です(厳しく制限されたクラスのアプリケーションでも)。クーベルチュールを調べてください。そのような目的のために、プラグインを使用して最近のGCCコンパイラーをカスタマイズすることも検討できます(おそらく2021年半ばのBismon 。それについては私にメールしてください)が、それは簡単ではなく、過大評価になります。basile.starynkevitch@cea.fr
GCCでコンパイルする場合は、リターンアドレスブルティンを使用して、実行時にスタックフレームポインタをクエリできます。一部のアーキテクチャでは、一部の最適化フラグでは使用できません。最近のGCCにバイト-Wstack-usage=
サイズおよび/または-Wframe-larger-than=
バイトサイズの 警告オプションを使用することもできます。
ヒープとスタックのスペースがどのように分散されるかに関しては、これはシステムに依存します。/proc/self/maps
Linuxでファイルを解析するかもしれません。proc(5)を参照してください。setrlimit(2)を使用して、ユーザースペースのLinuxのスタックスペースを制限できます。
ただし、ライスの定理に注意してください。
マルチスレッドアプリケーションでは、事態はさらに困難になる可能性があります。いくつかのPthreadチュートリアルを読んでください。
単純なケースでは、GCCが末尾呼び出しの最適化を実行できる場合があることに注意してください。をコンパイルfoo.c
して、生成されたアセンブラコードgcc -Os -fverbose-asm -S foo.c
の内部を調べることができます。foo.s
移植性を気にしない場合は、GCCの拡張asm
機能の使用も検討してください。