2016-01-13 15 views
5

Ravenscarサブセットを使用してAdaプログラムを作成しています(実行時に実行中のタスクの数がわかります)。コードは-fstack-checkスイッチを有効にしてgccによってコンパイルされます。私のタスクがスタックを超えた場合、プログラムは実行時にSTORAGE_ERRORを発生させるはずです。Ravenscarプログラムのスタック使用量を判断するためのベストプラクティス

pragma Storage_Size (Some_Value); 

今私はSome_Valueを決定しなければならないものオプション思っていた:

エイダは、それら(タスク固有)はそうのような各タスクの指定時にスタックの上限を設定することを可能にします。これまでに聞いたことがあります:

  1. STORAGE_ERRORがもう発生しなくなるまで、野生の推測を行います。これは、OPが示唆しているものと多かれ少なかれhereです。
  2. -fstack-usageの出力をそこに送ります。
  3. hereのようにいくつかのgnat固有の拡張を使用します(これは技術的に項目#2とどのように違いますか?)。
  4. gnatstackのようなスタックアナライザを取得し、それをあなたに任せましょう。

私はこれを正しく理解していれば、上記のすべての技術は、(すなわち、彼らが動作するために実行するプログラムを必要とする)ダイナミックです。静的アプローチも考えられますか?例えば。 Adaの高度な整合性オプション(例えば、No_Recursionなど)のいくつかをさらに制限することによって、他に何か?

おそらく、この問題に対処したり、私の(確かに不完全な)リストを拡張/コメントするためのベストプラクティスを挙げることができます。

ボーナス質問:上記のプラグマが指定されていない場合のタスクスタックのデフォルトサイズはいくらですか? GCCのdocsは、具体的な数値を指定せずにこの値が実行時によって異なります。

+1

良い背景調査で良い質問! –

+0

デフォルトのスタックサイズは 'System.Parameters.Default_Stack_Size'(ファイル' s-parame.adb')で与えられます。 –

+0

@Simon:そのスタックサイズは環境タスク、宣言されたタスク、またはすべてのタスクに関係しますか?環境タスクに影響を与えない「スタックサイズの設定」オプションが出てきました。特定のコンパイラリリースでは明らかに設定できませんでした。これもulimit設定に反しています。私はプログラム全体を新しいタスクに動かすことでその周りに取り組みました... –

答えて

1

通常、個々のタイプに必要なスタック領域は、'Storage_Size属性(ビット数)で確認できます。

これを集計したら(単語/ダブルワード全体に丸めなければならない場合があります)、各宣言領域でどれだけのスタックスペースが使用されているかを加算し、最大値スタックの使用。

+0

これを手動で行うことをお勧めしますか?それは退屈な努力のように思えます...これはおそらくツールのサポートですか? – morido

+1

私はそれを手作業で行うことを文字通り示唆していました。私は、あなたが再帰を使わないように自分自身を制限しない限り、あなたが静的分析を通してそれを行うことができるのではないかと疑います。再帰を使用しない場合は、小さなASISベースのツールを使用して作業を実行する必要があります。 –

関連する問題