デバッガー (または CLR 例外ハンドラー) は、pdb を使用してリリース モードで例外が発生した行を表示できますか?
リリース モードのコードは最適化されており、「元の」コードの順序とロジックに常に従うとは限りません。
また、リリース モードであっても、デバッガーがコードを 1 ステップずつナビゲートできることも驚くべきことです。最適化により、ナビゲーションが非常に不快になります。
その2点を明確にしていただけますか?
これが CLR でどのように行われるかについてはあまり詳しくありませんが、おそらくネイティブ コードで行われる方法と非常によく似ています。コンパイラがマシン命令を生成するとき、基本的に「現在のアドレス X の命令は foo.cpp の 25 行目から来た」というエントリを pdb に追加します。
デバッガーは、現在実行中のプログラム アドレスを認識します。そのため、pdb でアドレス X を検索し、それが foo.cpp の 25 行目にあることを確認します。これを使用して、ソース コードを「ステップ実行」できます。
このプロセスは、デバッグ モードまたはリリース モードに関係なく同じです (pdb がリリース モードで生成される場合)。ただし、多くの場合、最適化のためにリリース モードでは、デバッガーがコードを "直線的に" ステップ実行しません。予期せず別の行にジャンプする可能性があります。これは、オプティマイザーが命令の順序を変更したためですが、アドレスからソース行へのマッピングは変更されないため、デバッガーは引き続きそれに従うことができます。
[@わからない] ほぼ正しい。コンパイラは、現在のマシン コード命令に厳密に一致する適切な行番号を特定するために最善を尽くします。
PDB とデバッガーは最適化について何も知りません。PDB ファイルは基本的に、マシン コード内のアドレス位置をソース コードの行番号にマップします。最適化されたコードでは、アセンブリ命令をソース コードの特定の行に正確に一致させることが常に可能であるとは限らないため、コンパイラは手元にある最も近いものを PDB に書き込みます。これは、「前のソース コード行」または「囲んでいるコンテキスト (ループなど) のソース コード行」またはその他の何かである可能性があります。
とにかく、デバッガーは基本的に、現在の IP (命令ポインター) に最も近い (「前または等しい」などの) PDB マップ内のエントリを見つけ、その行を強調表示します。
一致があまり良くない場合があり、ハイライトされた領域があちこちに飛び散っているのが見えるのはそのときです。
次の SO の質問を参照してください。
デバッガーは、問題が発生した場所を最大限に推測します。100% 正確であるとは限りません。完全に最適化されたコードでは、多くの場合不正確になります。数行のずれから完全に間違ったコール スタックまで、さまざまな不正確さが見つかりました。
最適化されたコードでデバッガーがどれだけ正確であるかは、コード自体と、どのような最適化を行っているかによって異なります。