0

いくつかの複雑な数値計算に既存のパッケージを使用しています。私がする必要があるのは、「損失」と呼ばれる関数をカスタマイズすることです。「損失」関数のデフォルトの動作は、予想される最終的な計算結果につながります。しかし、私のカスタマイズでは期待した結果が得られません。だから私はそれをデバッグしようとしています。

(1) 他の関数によって呼び出される関数 int loss(int c1, int c2) をカスタマイズしています。最初に、デフォルトの動作は c1==c2 を返すだけであることに注意してください。0:4; 私はそれを次のように変更したい:

double loss(int c1, int c2) {
    int v1 = map[c1];  // map is an int array
    int v2 = map[c2];

    return doSomething(v1, v2); 
}

プログラムは「損失」関数を使用して、いくつかの連続した複雑な数値計算を行いますが、最終的な計算結果は期待どおりではありません。したがって、「損失」機能をデバッグして、正しく機能することを確認したいと思います。

(2) 次のように簡単にします。

 double loss(int c1, int c2) {
     int v1 = map[c1];
     int v2 = map[c2];

   [1].  return v1==v2 ? 0: 4; // this should be equivalent to [4] in my application

         // double check that different position of the array have different values
   [2].  if( (c1==c2 && v1!=v2) || (c1!=c2 && v1==v2)) {
   [3].         exit(0);  // printf("%d %d %d %d", v1, v2, c1, c2);
         }


   [4].  return c1==c2 ? 0: 4;
 }

他のステートメントなしで [4] のみを使用する場合、それがデフォルトの動作であり、期待される計算結果につながることがテストされていることに注意してください。

  1. ここで最初に [1] を使用しますが、[2] を [4] にコメントします。これは、アプリケーションの [4] と同等です。つまり、配列「マップ」に重複する要素がないことを期待しています。[1]<=>[4]、私は [4] をテストしたので、最終的な計算は正しいので、これは正しい最終的な計算結果にはつながりません。これは奇妙です。

  2. [2] と [3] を追加して (もちろん [1] を削除して)、[1] と [4] が同等であることを再確認したいと思います。プログラムは最後まで実行されます。つまり、[3] は実行されないため、[1] と [4] が同等であることが保証されます。ただし、[2] と [3] を追加して c1 と c2 の値を変更していませんが、最終的な計算は期待どおりではありません。[3] で printf を使用すると、同様の問題が発生します。しかし、一部のステートメントでは問題が発生しません。たとえば、「if」本体では、「int a = c1 + c2;」を使用するだけで、結果は正しいです。

  3. さらに奇妙なことに、[3] をコメントして (つまり、if 本体は何もしない)、[2] と [4] の両方を使用すると、最終的な計算は期待どおりになります!

奇妙な問題を理解するのを手伝ってくれませんか?

ありがとう、ジェフ

4

2 に答える 2

0

コンパイラの出力を逆アセンブルするにはどうすればよいですか?

選択できる方法はいくつかあります。プログラムの名前はf1.

  • objdump -S f1 出力で を探し<loss>ます。
  • アセンブラのリストを作成します。たとえば、代わりに、通常のコンパイルと同じフラグを使用してgcc -g -Wa,-adhln=f1.lst -O -c f1.c いることを確認してください。-O
  • gdb f1
    (gdb) disass loss
    の場合、デバッグ情報を生成した場合は、関数 を介してgdb実行することもできます。
    (gdb) break loss
    (gdb) run

    (gdb) step
    -g
于 2014-06-04T12:10:05.267 に答える
0

私はあなたが全単射であると仮定していると思いますがmap実際には全射です。つまり、さまざまな値がありc1ます。これは、あなたが見ているものの最良の説明です:c2map[c1] == map[c2]

  • [1] を使用すると、つまりv1==v2「正しい最終計算結果」が得られないと述べていますが、[4] を使用すると、つまりc1==c2.
  • [2] は意図したとおりに正しいチェックを実行していますが、[3] の効果を適切に検出していない可能性があります。プログラムが最後近くで終了するのではなく、[3] が存在する状態で最後まで実行されますか? [3] が実行されているかどうかはどのようにわかりますか? [2][3][4] で実行しても、[4] だけで実行した場合とは結果が異なります。これは、[3] が実際に実行されていることを示唆しています。
  • [3] をコメントアウトして [2] を残すと、プログラムは if ブラケットに入り、[4] をアウトして実行し、[4] だけで同等の出力が得られることを確認します。これはすべて一貫しています。
于 2013-03-05T05:22:55.040 に答える