1

私はよくCで数値ルーチンをデバッグします。これは、gdbを使用してプログラムを実行し、デバッグする関数にステップインすることを意味します。次に、gdbを使用して変数を出力することにより、数値を期待値と比較します。明らかに、この手順は長いルーチンでは面倒です。特に、ルーチンを変更して以前の結果と比較したい場合は、後続の実行間のさまざまな変数の値を覚えておく必要があります。場合によっては(特にルーチンが多かれ少なかれ線形である場合)、実行中に検出された数値で変数を自動的に置き換えるツールがあれば、非常に役立ちます。例:短い(些細な)ルーチン例

myfunc(double a, double b)
{
  double tmp_a, tmp_b, c;

  tmp_a = a*a;
  tmp_b = b*b;

  c = sqrt(tmp_a+tmp_b);

  return c;
}

に変換することができます

myfunc(double a<1.0>, double b<2.0>)
{
  double tmp_a, tmp_b, c;

  tmp_a = a<1.0>*a<1.0>;
  tmp_b = b<2.0>*b<2.0>;

  c = sqrt(tmp_a<1.0>+tmp_b<4.0>);

  return c<2.236067977499789696e+00>;
}

差分ツールを使用して、後続の実行の出力を簡単に比較できました。また、出力を数式処理システムに貼り付けることで、中間の数値結果を任意精度の結果と比較することもできます。大まかな考え方は、gdbドライバーが指定されたルーチンまでバイナリを実行し、ステップごとに実行し(ステップ内のすべての変数をその時点でそれぞれの値に置き換えるたびに)、最後に終了することです。既存のソフトウェアへのヒントや実装のアイデアは大歓迎です。たぶん、のような既存のgdbインターフェースを使用するperlに基づく解決策がありますDevel::GDB(これが十分に成長しているかどうかはわかりません)。


バージョン7以降、gdbはPythonスクリプトをサポートしているようです。シングルスレッドの実行可能ファイルをロードし、ブレークポイントを設定し、実行可能ファイルを実行し、ブレークポイントに到達すると変数値を出力する最小限の例は、私にとって非常に役立ちます。

4

2 に答える 2

0

別の方法で行うこともでき
ます。ログファイルを作成します(printfを使用して実行し、実行時に標準出力をリダイレクトすることができます)。diff対象の値と異なる実行からの2つのログを印刷できます。

于 2013-02-20T12:54:47.433 に答える
0

例で最適化を有効にし、引数がコード内の定数である場合、コンパイラはまさにそれを行い、すべてを単純化して事前に計算された 5 の平方根を返すと期待します。

「コードフロー解析」を行って境界条件を理解したり、「sqrtを負の値で呼ぶとエラーになる」とかいう製品が出回っています。Coverity は、C/C++ でこれを行うツールであり (ほとんど無料ではありません)、「あなたはここで何かばかげたことをしようとしています。これは正しいですか?」と吐き出します。コードのメッセージを入力します。

Valgrind も同様のことができます。

しかし、これらのツールはどちらも、一連のコード実行の変数の現在の値に注釈を付けることができません。それは可能ですが、コードを全速力で実行するのに比べてかなり時間がかかります。また、コードが数回の反復を実行する数百行を超えるものである場合、おそらく永遠に時間がかかり、生成されます。何がどこで起こったかの非常に大きなログファイル。それが実用的であるとはまったく確信していません。

于 2013-02-20T12:47:13.163 に答える