Releaseバージョンアプリケーションのデバッグ


引用する
開発中によくあるエラーが発生した場合、Releaseバージョンが正常に動作せず、Debugバージョンが正しく動作しない可能性があります.この文書を読むことをお勧めします.想像通りではないので、ReleaseバージョンはアプリケーションがDebugバージョンのように動作することを保証します.
開発フェーズが完了した後、または開発期間中にReleaseバージョンのテストを行ったことがありませんが、テスト中に問題が発生した場合は、デバッグルール1を参照してください.
ルール1:開発ソフトウェアに対して常にDebugとReleaseバージョンの通常テストを行う.
Releaseバージョンをテストする間隔が長いほど、問題を排除する難易度が高くなり、少なくともReleaseバージョンを週に1回テストすることで、コンパクトな開発サイクルで潜在的な排出時間を節約できます.
Releaseバージョンに必要なコードを勝手に削除しないでください
この点は明らかに見えますが、開発者が何気なくよく犯すエラーです.なぜなら、コンパイラがReleaseバージョンをコンパイルするときにコードに存在するマクロを自発的に排除するからです.例えば、ASSERTやTRACEはReleaseバージョンで自動的に排除されます.このような問題は、これらのマクロで実行しているコードも削除されることです.これは非常に危険なことです.J例:
ASSERT(m_ImageList.Create(MAKEINTRESOURCE(IDB_IMAGES), 16, 1, RGB(255,255,255)));
このようなコードはDebugモードではエラーが発生せず、画像リストも自動的に作成されますが、Releaseバージョンでは?後続使用m_ImageListオブジェクトはプログラムのCrashにしかなりません!したがってASSERTマクロではできるだけ論理演算子を検証として使用する.
ルール2:あるコンパイルオプションでのみ実行される場所にコードを配置しないでください.DEBUGなどのコンパイルオプションマクロ内部のコードは、プログラム全体の使用に影響しない必要がある.
ルール3:ルール2を評価基準としてASSERTマクロを削除するのではなく、ASSERTマクロは有用なツールであるが、エラーが使いやすい.
DebugコンパイルモードをReleaseモードに近づける
Releaseバージョンの問題がコンパイラによって自動的に排除された場合、この方法で問題が再現される可能性があります.
いくつかの問題の発生は、異なるコンパイルオプション間の事前定義記号による可能性があります.そのため、コンパイルモードの事前定義記号を変更して、DebugモードをReleaseモードに近づけ、エラーが発生したかどうかを観察し、以下のように事前定義記号のコンパイル方法を変更することができます.
Alt-F 7は項目設定を開き、C++/Cページで「General」カテゴリを選択し、「_DEBUG」記号を「NDEBUG」に変更する.
C++/Cページで、「Preprocessor」カテゴリを選択し、「_DEBUG」を「Undefined Symbols」バーに追加します.
「Rebuild All」を使用してを再コンパイル
上記の設定で、Releaseコンパイルモードの問題をDebugモードで再現した場合は、次の手順に従ってコードを変更します.
ASSERTで重要な実行文をすべて除外するか、またはASSERTをVERIFYに変更します.
「#ifdef_DEBUG」内のすべてのコードをチェックし、Releaseモードで使用するコードを除外する.
TRACEが除外する重要な実行文をすべて検索します.TRACEはASSERTと同様にDebugモードでのみコンパイル.
Debugモードで問題が修正された場合は、Releaseモードを再コンパイルできます.以前に存在した問題を解決できる可能性があります.の
エラーの仮定によるコンパイルモードエラー
変数またはオブジェクトが指定された値(可能な0)に初期化されたと頻繁に仮定しますか?関連するすべてのリソースがアプリケーションに存在すると仮定しますか?これらもDebugとReleaseモードで異なる問題が発生する原因である.
ルール4:コードで変数を初期化しない限り、上記の仮定はできません.グローバル変数、自動変数、申請対象、new対象を含む.
このような状況はメモリの順序の問題でもよく発生します.元の構造体を使用するときは使いやすいように、2つの構造体オブジェクトを比較してmemcmpを使用し、Debugバージョンでは正常に動作していましたが、Releaseバージョンでは誤った解が計算され、確かに誤った仮定はできないようです.
ルール5:削除リソースのすべての参照が削除されることを確認します.例えばresource.hの定義
ソフトウェア開発では、異なるコンパイルバージョンによる変数とメモリの初期化が異なる.変数を0に初期化すると、Win 9 xシステムのReleaseモードで異常が発生します.したがって、すべての変数に対して、メモリの明示的なクリア0は比較的安全な方法である.
削除されたリソースを参照すると、Debugバージョンは正常に動作しますが、Releaseバージョンはcrashになる可能性があります.
コンパイラを信じますか?
コンパイラの警告レベルはコンパイルノイズとかなりの関係がある.
コンパイラの警告レベルを高めることで、プログラムが問題を隠す機会を増やすことができる.通常、警告レベルは「レベル3」または「レベル4」に設定.すべての警告をコンパイルして解決することは、Releaseバージョンのアプリケーションを公開するための良い提案です.これにより、アプリケーションに問題が発生する初期化の問題や潜在的なエラーが多数検出されます.
ルール6:プロジェクトを開始する前にコンパイル警告レベルを「レベル3」または「レベル4」に設定し、コードを登録する前にすべての警告が消滅することを確認します.
コンパイルモードでのデバッグ
かつて何度もVC開発者からReleaseモードの下でデバッグができないという話を聞いたことがあるが、幸いなことに、対応する設定を通じてReleaseモードでデバッグすることができるので、それは誤魔化したでたらめな言い方にすぎない.
ルール7:前のすべてのメソッドが無効な場合は、Releaseモードでデバッグする.
Releaseモードでは、デバッグを実行できます.最初のステップは、シンボルテーブルを開くことです.
Alt-F 7はプロジェクト設定を開き、C++/Cページで「General」クラスを選択し、Debug Info settingを「Program Database」に変更する.
[Link]ページで、[Generate Debug Info]を選択します.
"Rebuild All"
これらの設定では、Releaseモードでシンボルテーブルを保持できます.また、次の設定も考慮できます.
Releaseバージョンのアプリケーションをデバッグし、最適化オプションを閉じることができます.
Releaseモードでブレークポイントを設定ことができない場合、追加命令「_asm{int 3}」は、アプリケーションが改行停止(アプリケーションの発行時に除外することを決定する)することができる.
Releaseモードでのデバッグのいくつかの制限がある.
最大の問題は、ReleaseバージョンのMFCダイナミックリンクライブラリにデバッグ情報とシンボルテーブルが含まれていないため、MFC関数の内部を追跡できないことです.
また、呼び出したdllをデバッグするには、デバッグ情報とシンボルテーブルをすべて追加する必要があります.
コンパイラはエラーのコードを生成しましたか?
VC++コンパイラが「問題コード」を生成していることに気づくかもしれませんが、率直に言うと、人々はあまりにも早く愚痴をこぼしています.テストを行うには、Releaseモードの下で最適化オプションをオフにすることができます.
もしこの操作があなたの問題を解決したら、あなたの符号化習慣に問題があるかもしれません.信じるか信じないかはあなた次第で、あなたの符号化に曖昧な解があるか、正しいように見えるか、いくつかの条件でも正しい場合があります.たとえば、次のコードはDebugモードではすべて「正常」のようですが、Releaseモードではエラーが発生します.
#include <stdio.h>
 
int* func1()
{
int retval = 5;
return &retval;
}
 
int main(int argc, char* argv[])
{
printf("%d
"
, *func1());
return 0;
}

多くのプログラマー、特に初心者はこのような状況に遭遇しやすいと信じています.
ルール8:Releaseモードの最適化オプションをオフにすると、アプリケーションが正常に動作し、最適化オプションをオンにすると問題が発生します.原因は、符号化習慣が悪いためです.これは、コードをよくチェックし、誤った仮定を整理し、ポインタを空にする必要があることを意味します.これは、Debugモードと最適化オプションをオフにするReleaseモードでアプリケーションが正常に動作しているのは、システムに隠された運のためであり、危険なコードの修正に着手する必要があります.そうしないと、後で大きな損失をもたらす可能性があります.
ルール9:コードを完全にチェックし、問題が見つからない場合は、最適化オプションを1つずつ開くと、エラーの原因が範囲内に制限されます.
BTW-以上の問題コードはC++コンパイラによって自動的に検出する.ルール6に従っている場合は、前のセクションでこれらの問題を解決したかもしれません.
私の开発経験によると、コンパイラは间违ったコードを発生することはめったにありません(もちろんインタフェースプログラムの境界位置合わせの问题に注意してください).通常、テンプレートクラスを使用する时、VC 6コンパイラはASSERTエラーを断言することができます.この场合、パッチを更新するだけで解决できます.
最後の思考
日常の符号化において、少し厳格な検出を加えるだけで、新しいDebug-v-Releaseモードの問題の発生を効果的に回避することができ、以下は私のいくつかの経験である.
1.修正が必要なコードを取り出す.
2.コードを修正し、すべての警告を排除し、DebugとReleaseバージョンをコンパイルする.
3.新しいコードを詳細にテストする、すなわち、新しいコードセグメントを単一ステップでデバッグした後、作業コードに入り、コードに間違いがないことを確保する.
4.すべての問題を修正する.
5.エラーがないことを確認してから、新しいコードを入庫する(check in).
6.入庫登録コードを新たにコンパイルし、新たな登録コードが他のコードと融合することを確保する.
7.コードを再詳細にテストする.
8.新しい問題の修正(入庫コードの登録に問題があるかもしれません)
以上の手順に従って、設計開発の過程で多くの問題を解決することができ、最後にアプリケーションをリリースするときに新しい位置決めが難しい問題を回避することができます.
後記
本文は私の开発の过程の中でReleaseバージョンのアプリケーションの発表に出会って、间违いが発生する时苦労して得たいくつかの経験を求めて、原文はcodeprojectから来て、本人の润色を経て、国内の开発者に适する文章に书いて、みんなに役に立つことを望んで、ありがとうございます!