だから私はリリースモードのデバッグシンボルを有効にするアドバイスに従いました、そしてデバッグシンボルを有効にし、最適化を無効にし、シンボルがリリースモードに準拠している場合にブレークポイントが機能することを見つけた後、私は疑問に思います...
- デバッグモードの目的は、バグを見つけるのに役立つことではありませんか?
- バグがあなたをすり抜けてしまうのなら、なぜデバッグモードを気にするのですか?
何かアドバイス?
だから私はリリースモードのデバッグシンボルを有効にするアドバイスに従いました、そしてデバッグシンボルを有効にし、最適化を無効にし、シンボルがリリースモードに準拠している場合にブレークポイントが機能することを見つけた後、私は疑問に思います...
何かアドバイス?
実際には、リリースモードやデバッグモードなどはありません。さまざまなオプションが有効になっているさまざまな構成があります。リリース'モード'とデバッグ'モード'は単なる一般的な構成です。
これまでに行ったことは、リリース構成を変更して、デバッグ構成で通常有効になっているいくつかのオプションを有効にすることです。
これらのオプションを有効にすると、有効にするバイナリに応じてバイナリが大きくなり、遅くなります。
これらのオプションを有効にすればするほど、バグを見つけやすくなります。あなたの質問は本当に「なぜリリースモードを気にするのか」ということだと思います。その答えは、それがより小さく、より速いということです。
デバッグモードでは、「バグがすり抜ける」ことはありません。多数のバグをキャッチするためにチェックを挿入しますが、これらのチェックの存在は他の特定のバグを隠す可能性もあります。すべてのエラーチェックコードは多くのエラーをキャッチしますが、パディングとしても機能し、微妙な境界エラーを隠す可能性があります。
そのため、それ自体が両方を実行する十分な理由になるはずです。MSVCは、デバッグモードで多くの追加のエラーチェックを実行します。
さらに、デバッグビルドではそうであるが、デフォルトではリリースビルドではそうではないなど、多くのデバッグツールは定義されていないことにassert
依存しています。NDEBUG
最適化がオフになり、デバッグが容易になります(そうしないと、コードが奇妙な方法で並べ替えられる可能性があります)。また、assert()などの条件付きコードを含めることができます。
アプリケーションがリリースモードで非常にデバッグ可能であることを除けば、 MSVCランタイムライブラリはそれほど優れていません。他のライブラリも同様です。
たとえば、デバッグヒープは、割り当てられたメモリの周囲に無人のランドマーカーを追加して、バッファオーバーランをトラップします。MSVCで使用される標準ライブラリは、イテレータの有効性を主張します。そして、はるかに。
オプティマイザーによるバグは前代未聞ではありません。ただし、通常は、より深い問題を示唆しています。たとえば、volatile
必要なときに使用しないと、オプティマイザーのバグが発生します(比較を最適化し、代わりにキャッシュされた結果を使用します)。
結局のところ、初期のリリースにデバッグシンボルを含めると、展開後にバグを追跡するのに役立ちます。
今、あなたの質問に直接答えるために:
assert()
デバッグモードには、リリースモードで削除されるsなどの他のものがあります。volatile
バグなど)はデバッグモードでのみ非表示になります。それらはまだ存在しており、トリガーするのが難しいだけです。アプリケーションに完全なシンボルを含めると、ビルドマシンに関する重要な情報が含まれます(パスなどが埋め込まれます)。
アドバイスは、最適化がオンになっているリリースビルド(ファイル、行、ローカル変数のシンボルは含めない)に「PDBのみ」のシンボルを含めることです。また、デバッグビルドには最適化と完全なシンボルがありません。
そして(他の回答で述べられているように)共通部分式除去と命令の並べ替えはデバッグを面白くすることができます(次に移動してn、n + 2、n + 1 ...行に移動します)。
最適化はデバッグにとって悪夢です。これを使ってアプリケーションを作成したら、forループ
for (int i = 0; i < 10; i++)
{
//use i with something
}
デバッグでは常に0でした。しかし、それをコンソールに出力すると、それが増加したことが示されました