5

いくつかのヘッダーを含む 4 ~ 5 個の .c ファイル (それぞれ約 2000 ~ 5000 行) を使用しています。現在、実行中にプログラムをデバッグするのに役立つデバッグ プリントはありません。

私の質問は次のとおりです:- .c ファイルを解析し、.c ファイルの現在のスコープ内のすべての変数に対して新しい印刷ステートメントのセットを追加する方法 (または既存のツール) はありますか? VC++ と同じように、ローカルやグローバルなどを表示できます。各ステップでそれらを出力する必要があります。また、ポインターは逆参照する必要があります。

たとえば。.c ファイルのある時点で、10 個のグローバル変数と 3 個のローカル変数があるとしましょう。その時点でこれらの 13 個の変数を出力するには、スマート printfs を生成する必要があります。プログラムの後半で20個の変数がある場合、20個の変数などを出力できるはずです。含まれているヘッダーファイルには、これらの
変数のそれぞれに関連するすべての宣言が含まれています(構造/ポインター/配列またはいくつかの組み合わせなどである可能性があります. ) 私は perl スクリプトでこれを達成しようとしていました。

私がしたことは、前処理されたファイル (.i ファイル) を生成し、それを perl で解析してから、各変数に固有の個々の印刷関数を生成しようとしたことですが、半日の努力の後、時間がかかりすぎることに気付きました。すでにそれを行うツールはありますか? これではない場合は、それに近いもので十分です(perl処理などを適用できます)私の目標は、プログラムの実行後、プログラム実行中の各ステップで、変数(有効なそのスコープで) デバッガーを呼び出す必要はありません。

.c ファイルを処理して、もう一度書き直すことは許可されています。私の質問が明確であることを願っています。返信ありがとうございます。

4

1 に答える 1

3

C プログラムが Frama-C の値分析によって解釈できると仮定すると、これは与えられたものではありませんが、それを使用して、プログラムの各ポイントまたは関心のあるポイントですべての生きている変数の値のログを取得できます。

次のプログラムを検討してください。

int x = 1;

main(){
  int l;

  x=2;
  Frama_C_dump_each();
  l=3;
  Frama_C_dump_each();
  {
    int blocklocal = l + 1;
    Frama_C_dump_each();
    x = blocklocal + 1;
    Frama_C_dump_each();
  }
  Frama_C_dump_each();
  return 0;
}

frama-c -val -slevel 1000000000 -no-results t.cこのプログラムを実行すると、次のログが生成されます。

[value] Values of globals at initialization
        x ∈ {1}
[value] DUMPING STATE of file t.c line 7
        x ∈ {2}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 9
        x ∈ {2}
        l ∈ {3}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 12
        x ∈ {2}
        l ∈ {3}
        blocklocal ∈ {4}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 14
        x ∈ {5}
        l ∈ {3}
        blocklocal ∈ {4}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 16
        x ∈ {5}
        l ∈ {3}
        =END OF DUMP==

ステートメントは私が手動で挿入しましたFrama_C_dump_each()が、各ステートメントで状態を自動的にダンプするようにインタープリターを微調整することもできます。

このアプローチを機能させるには、標準ライブラリ関数 ( strlen()memcpy()、…) を含むプログラムのソース コード全体が必要であり、main()関数の先頭で入力の値をハードコーディングする必要があります。それ以外の場合は、C インタープリターとして動作するのではなく、実際の静的アナライザーとして動作します。

GUIを使用してプログラム内の変数の値を観察することもできますが、それが線形でない場合、関数呼び出しまたはループのために何度もアクセスされるステートメントは、実行中に取得できるすべての値を表示します。

于 2012-12-30T11:26:49.487 に答える