4

組み込みシステムで実行中の C プログラムの現在のスタックとヒープ サイズを確認するにはどうすればよいですか? また、組み込みシステムで許可される最大スタック サイズとヒープ サイズを確認するにはどうすればよいですか? ヒープサイズが見つからなくなるまで、サイズを増やして malloc() を線形に呼び出すことを考えましたが、スタックのサイズにもっと興味があります。

私は mbed NXP LPC1768 を使用しており、GitHub で開発された gcc4mbed というオフライン コンパイラを使用しています。

より良いアイデアはありますか?すべてのヘルプは大歓迎です!

4

2 に答える 2

10

このリンカー スクリプトを見ると、それぞれに割り当てたスペースの量が定義されます。

スタック サイズの使用法については、次のようにします。

メモリの初期化中の起動時 (C main() の前) に、すべてのスタック バイトを 0xAA や 0xCD などの既知の値に初期化します。プログラムを実行します。いつでも停止して、魔法の値がいくつ残っているかを確認できます。魔法の値が表示されない場合は、スタックがオーバーフローしており、奇妙なことが起こり始めている可能性があります。

実行時に、最後の 4 バイト程度をチェックすることもできます (最後の 2 ワードかもしれませんが、これはあなた次第です)。それらがあなたの魔法の値と一致しない場合は、強制的にリセットしてください。これは、システムがリセット時に正常に動作している場合にのみ機能し、システムがすばやく起動し、「リアルタイム」またはミッション クリティカルな処理を行っていない場合に最適です。

これは、この件に関するIAR の非常に役立つホワイトペーパーです。

于 2012-07-28T13:28:53.617 に答える
7

実行時に現在のスタックサイズを測定する大まかな方法​​は、宣言することです

 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/mapsLinuxでファイルを解析するかもしれません。proc(5)を参照してください。setrlimit(2)を使用して、ユーザースペースのLinuxのスタックスペースを制限できます。

ただし、ライスの定理に注意してください。

マルチスレッドアプリケーションでは、事態はさらに困難になる可能性があります。いくつかのPthreadチュートリアルを読んでください。

単純なケースでは、GCCが末尾呼び出しの最適化を実行できる場合があることに注意してください。をコンパイルfoo.cして、生成されたアセンブラコードgcc -Os -fverbose-asm -S foo.cの内部を調べることができます。foo.s

移植性を気にしない場合は、GCCの拡張asm機能の使用も検討してください。

于 2012-07-28T13:03:47.817 に答える