0

それで、本当にブードゥーなバグ(もちろん、#include関連する場所にバグを追加することで解決されました)に対処した1週間後、デバッガーを常に信頼する必要はなく、何かが意味をなさない場合は良いことに気づきました。古いprintf()ものはあなたに役立つかもしれません。私が知っていたことから、コードがリリースモードでコンパイルされている場合、デバッガーは「嘘をつく」可能性があります。私は最近、クラスに がある場合#ifdef、次のようなことを学びました

struct MyStruct
{
    char a;
#ifdef USE_ME
    double c;
#else
    int c;
#endif
};

は、USE_ME構造体定義に表示されるヘッダーで定義されていませんが、デバッガーが混乱するよりも他の場所で定義されています。これは、デバッグモードであっても、型 c が何であるかがわからず、「嘘をつく」ためです。私の質問は次のとおりです。デバッガーがいつ嘘をつくかについて、他の状況を誰か教えてもらえますか?

4

3 に答える 3

4

デバッガーは通常、嘘をつきません (バグがある場合を除きます)。プログラムで何が起こっているかを正確に伝えます。あなたの問題は、あなたのプログラムで起こっていることが、あなたがプログラムで起こっていると思っていたものと異なっていること、またはソースコードに書いたものと異なっていることです。

コンパイラがコードを最適化するとき (たとえば、リリース ビルドをビルドするとき)、さまざまな方法でコードを変換します。つまり、操作が並べ替えられるか、完全に削除されます。

デバッグするとき、デバッガーは何が起こっているのかをソースコードに書かれていることと関連付けるために最善を尽くしますが、コンパイラーが同じ目標を達成するためにまったく異なる方法を選択した可能性があるため、完全に行うことはできません。そのため、変数がデバッガーでまったく表示されない (最適化されている) か、予期しない値が含まれているか、デバッガーが異なるソース コード行間でランダムにジャンプしているように見えることがよくあります。

したがって、デバッガーは嘘をつきません。予想とは違う真実を教えてくれるだけです。それは、プログラムで実際に起こっていることの真実を伝えます。ソース コードに書かれたことの「真実」ではありません。

于 2012-06-10T13:13:34.850 に答える
1

嘘の典型的な例は、メモリの破損 (スタックまたはヒープの破損)、および一般的なメモリ関連の問題 (たとえば、ぶら下がっている参照) で発生します。

これはundefined behaviorを呼び出した結果の 1 つです。この場合、デバッガーは無効なコンパイル済みコードから動作しているため、デバッガーの動作も未定義です。

デバッガーは、適切な形式のプログラムの論理的な問題を支援するのに優れており、不適切な形式のプログラムのエラー (null 参照解除など) を見つけるのに役立ちます。しかし、不正なプログラムのすべてのクラスを効率的にデバッグできるわけではありません。そしてもちろん、プログラムを観察するという事実そのものがその動作を変更するため、マルチスレッドプログラム (とりわけ) では事態はさらに複雑になります...

于 2012-06-10T13:22:15.003 に答える
0

デバッガーには、次の 2 つのシナリオがあります。

  1. 不足している/正しくないシンボル (自分のシンボルと OS のシンボルを含む) を使用してデバッグしています。
  2. あなたは悪いビルドを持っています。古い .OBJ が最初に再構築されずにリンクされた可能性があります。これは、大規模なプロジェクト/ソリューションで発生することがあります。特に、VS2010 での公式の方法ではなく、プロジェクトの依存関係を指定する「昔ながらの」方法を使用している場合です。
于 2012-06-10T13:19:52.597 に答える