コンパイラとオペレーティング システムのアーキテクチャに依存することを読みました。GCC をコンパイラとして使用している Linux システムで、データ セグメントとスタックの最大サイズを調べるにはどうすればよいですか?
3 に答える
実験させてください: 次のようにファイル ``test.c'' を作成してください:
int main (void) { return 0; }
次に、最大スタックサイズを指定してコンパイルします(マップファイルでこの番号を簡単に検索し、それを参照してシンボル名を決定するだけです):
gcc test.c -o test.x -Wl,--stack=0x20000 -Wl,-Map=output.map
データ サイズの決定は簡単です。
size -A -d test.x
次のようなものが得られます。
section size addr
.text 1880 4299165696
.data 104 4299169792
...
また、「objdump -h test.x」も問題なく動作しますが、冗長な結果は得られません。
ここには (コードとデータだけでなく) より多くのセクションがありますが、ここにはスタック情報はありません。なんで?スタック サイズは ELF セクションではないため、プログラムがロードされて実行された後にのみ予約されます。次のように、ファイル内の (プラットフォームに依存する) シンボルから読み取る必要があります。
$ nm test.x | grep __size_of_stack_reserve__
0000000000020000 A __size_of_stack_reserve__
コンパイル時に述べたように、サイズが 0x20000 であることは驚くべきことではありません。
コンパイル中に生成された output.map ファイルを調べて、シンボル名を決定しました。こちらもまずは見ることから始めることをお勧めします。
次に、不明なファイル a.out がある場合は、シーケンスを繰り返します。
size -A -d a.out
nm a.out | grep __size_of_stack_reserve__
それにプラットフォーム依存のシンボルを代入して、上記の実験で決定しました。
セグメントは、実行可能ファイルに必要なものを整理する方法です。
通常、データ セグメントは、実行可能ファイルが使用するすべてのデータ用です (外部ソースからの入力なし)。一部のデータ セグメントには、文字列リテラルまたは数値定数が含まれる場合があります。
多くの実行可能ファイルは、関数のローカル変数、ステートメント ブロックのローカル変数、戻りアドレス、および関数パラメーターを格納するためにスタックを使用します。C または C++ 言語ではスタックは必要ありません。それはただの便利なデータ構造です。
スタック サイズは、スタックに割り当てられた容量、スタックに存在する要素の数、またはスタックが占有するメモリの量のいずれかです。
多くのプラットフォームには、スタックのデフォルト サイズがあります。プラットフォームはさまざまであるため、ツールのドキュメントを読んで、スタック サイズの設定方法とデフォルトの容量を確認する必要があります。