Why does the Visual Studio 2010 debugger not pick up debug symbols for handling exception in F# sequence?

StackOverflow https://stackoverflow.com/questions/9359423

  •  28-10-2019
  •  | 
  •  

Question

In Visual Studio 2010, the following F# sequence works as expected in Release mode (ignores UnauthorizedAccessException), but does not work correctly in Debug mode (breaks on UnauthorizedAccessException, even if I have set "Common Language Runtime Exceptions: Thrown = 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.

However, if I do not nest the getAuthorizedItems function inside the sequence, but place it at module level instead, the debugger works correctly.

Note:

  1. I have looked at the generated IL code, and the exception handler is where it should be in both cases (is not modified/optimized in any way);
  2. I know that System.Core must be preloaded in order for sequences to be displayed correctly in the debugger, but that is not related to my issue.

Are there any special rules for handling exceptions in sequences at debug time in F#?

Edit

After my reporting the issue, the F# team very quickly started to track it. It seems to be a minor bug related to the fact that, in Debug mode, some of the generated code is marked as ‘External Code’, even though it is user code. For the time being, one can use the workarounds suggested in pad's answer. Another workaround ist to turn off "Enable Just My Code" in the VS debugging options.

Was it helpful?

Solution

I'm able to reproduce the bug on my machine using F# 2.0/.NET 4.0 without VS2010 SP1 installed. It could be the case that this bug has been fixed in VS2010 SP1 as @svick couldn't reproduce it. It turns out this bug is still present after VS2010 SP1 update.

I think it's a bug of handling exception in nested functions inside sequence expression, changing the nested function to catch any exception doesn't affect the behaviour:

let getAuthorizedItems getItems dir =
    try getItems dir
    with ex -> [||]

This is a minor bug; you can bypass it in many ways:

  • It works in Release mode, inside fsi and even runs in Debug mode outside Visual Studio.
  • Declaring the nested function as inline makes it work in Debug mode.
  • Turning on Optimize code option makes it work again.
  • Not using nested functions inside seq also helps.

If it hasn't been fixed, I suggest you file a bug report at fsbugs at microsoft dot com.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top