Visual Studio 2010デバッガがF#シーケンスで例外を処理するためのデバッグシンボルをピックアップしないのはなぜですか?
-
28-10-2019 - |
質問
Visual Studio 2010では、次のF#シーケンスがリリースモードで期待どおりに機能します(無許可のAccesSectionsectionを無視します)が、デバッグモードでは正しく動作しません(「共通言語ランタイムの例外を設定していても、不正なaccessexceptionで破損します:thrown = false、false、user-ユーザー - unhandled = true ")。
open System
open System.IO
module private MyTestModule =
let rec private getAllFiles dir = seq {
if String.IsNullOrWhiteSpace dir |> not then
let getAuthorizedItems getItems dir =
try getItems dir
with :? UnauthorizedAccessException -> [||]
// Debugger stops here on UnauthorizedAccessException, but shouldn't...
yield! getAuthorizedItems Directory.GetFiles dir
for subDir in getAuthorizedItems Directory.GetDirectories dir do
yield! getAllFiles subDir }
// etc.
ただし、getauthorizeTems機能をシーケンス内にネストしない場合、代わりにモジュールレベルに配置する場合、デバッガーは正しく動作します。
ノート:
- 生成されたILコードを見ましたが、例外ハンドラーは両方の場合にある必要がある場合です(いかなる方法でも変更/最適化されていません)。
- デバッガーにシーケンスを正しく表示するためには、System.coreをプリロードする必要があることは知っていますが、それは私の問題とは関係ありません。
F#のデバッグ時間にシーケンスで例外を処理するための特別なルールはありますか?
編集
問題を報告した後、F#チームはすぐにそれを追跡し始めました。デバッグモードでは、生成されたコードの一部がユーザーコードであるにもかかわらず「外部コード」としてマークされているという事実に関連するマイナーなバグのようです。とりあえず、PADの答えで提案されている回避策を使用できます。別の回避策は、VSデバッグオプションで「コードのみを有効にする」をオフにします。
解決
VS2010 SP1がインストールされていないF#2.0/.NET 4.0を使用して、マシンのバグを再現できます。 @Svickがそれを再現できなかったため、このバグはVS2010 SP1で修正された可能性があります。 このバグは、VS2010 SP1アップデート後もまだ存在していることがわかりました。
シーケンス式内のネストされた関数における取り扱い例外のバグだと思います。ネストされた関数を変更して例外をキャッチしても、動作に影響しません。
let getAuthorizedItems getItems dir =
try getItems dir
with ex -> [||]
これは小さなバグです。あなたはそれを多くの方法でバイパスすることができます:
- リリースモード、FSI内で動作し、Visual Studioの外でデバッグモードでも動作します。
- ネストされた関数をとして宣言します
inline
デバッグモードで動作させます。 - 電源を)いれる、(電気・テレビなどを)つける
Optimize code
オプションは再び動作します。 - 内部にネストされた関数を使用していません
seq
また、役立ちます。
それが修正されていない場合は、バグレポートを提出することをお勧めします fsbugs で マイクロソフト ドット com.