Runtime: Debugger cannot break in custom AssemblyLoadContext

Created on 25 Oct 2018  路  18Comments  路  Source: dotnet/runtime

I'm working on transitioning from .NET Framework to .NET Core 2.1, and I've hit a snag when it comes to replacing AppDomains. I need to load script code on the fly, and usually this is done in a separate process. This turned out to be pretty clunky for debugging purposes, so I use a separate code path that loads the script into an AppDomain instead while I'm working on it. Setting breakpoints etc worked just fine the separate AppDomain, but the equivalent in .NET Core (using AssemblyLoadContexts) isn't working.

(Side note: I don't really care that I can't unload the scripts until .NET Core 3.0 comes out, as I said it's only for debugging.)

Here's a minimal example:

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Loader;

namespace TestLoadContext
{
    class Program
    {
        internal class MyAssemblyLoadContext : AssemblyLoadContext
        {
            internal MyAssemblyLoadContext() { }
            protected override Assembly Load(AssemblyName assemblyName) => null;
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Hello from main context!");

            var loadContext = new MyAssemblyLoadContext();
            var assembly = loadContext.LoadFromAssemblyPath(typeof(Program).Assembly.Location);
            var startMethod = assembly.GetType(typeof(Program).FullName).GetTypeInfo().GetMethod("Run");
            startMethod.Invoke(null, new object[0]);
            Debugger.Break();
        }

        public static void Run()
        {
            Console.WriteLine("Hello from custom context!");
            Debugger.Break(); // <--- DOES NOTHING
        }
    }
}

If I try to step into the Run method, I get a VS error: "Unable to step. Operation not supported. Unknown error: 0x80004005"

area-Diagnostics-coreclr

Most helpful comment

The loader context issue fix is in Visual Studio 2019 Preview 2 (https://blogs.msdn.microsoft.com/visualstudio/2019/01/24/visual-studio-2019-preview-2-is-now-available/). Can you give it a try and let us know if it resolves the issue?

Tested now with this repro and works like a charm. Great news. Thanks.

All 18 comments

cc: @tommcdon

This is a known problem (tracked by MS internal workitem https://devdiv.visualstudio.com/DevDiv/_workitems/edit/667860). It has been fixed by @r-ramesh a few days ago.

@r-ramesh Could you please check that your fix works for the repro above?

@r-ramesh Could you please check that your fix works for the repro above?

That's a month back now. Was it ever verified?

Can I help you guys testing this?

+1, would be neat to have it fixed. Thanks! 馃憤

Still no info available?

@tommcdon Could you please share when this fix is going to be available in Visual Studio?

No early Christmas gift here? 馃巺

Since there's still no answer, I decided to test this on latest bits (prerelease excluded). Slightly simplified it too, to illustrate it's not Debugger.Break() exclusively, but show in standard stepping in Visual Studio Code.

I just tested it in on 2.2 / SDK 2.2.1 and problem still remain.

For anyone that want to try it out:

  1. Build and run/debug below code in Visual Studio Code.
  2. Observe how first Run can be successfully stepped into.
  3. Observe how second Run can not.

Test.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>
</Project>

Program.cs

using System;
using System.Reflection;
using System.Runtime.Loader;

namespace TestLoadContext
{
    class Program
    {
        class MyAssemblyLoadContext : AssemblyLoadContext
        {
            protected override Assembly Load(AssemblyName assemblyName) => null;
        }

        static void Main(string[] args)
        {
            Run("Hello from main context");

            var loadContext = new MyAssemblyLoadContext();
            var assembly = loadContext.LoadFromAssemblyPath(typeof(Program).Assembly.Location);
            var runMethod = assembly
                .GetType(typeof(Program).FullName)
                .GetTypeInfo()
                .GetMethod("Run");

            runMethod.Invoke(null, new object[] { "Hello from custom context!" });
        }

        public static void Run(string message) => Console.WriteLine(message);
    }
}

Environment

.NET Core SDK (reflecting any global.json):
 Version:   2.2.101
 Commit:    236713b0b7

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17134
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.2.101\

Host (useful for support):
  Version: 2.2.0
  Commit:  1249f08fed

.NET Core SDKs installed:
  1.0.0-rc4-004771 [C:\Program Files\dotnet\sdk]
  1.0.0 [C:\Program Files\dotnet\sdk]
  1.0.3 [C:\Program Files\dotnet\sdk]
  1.1.0 [C:\Program Files\dotnet\sdk]
  2.0.0 [C:\Program Files\dotnet\sdk]
  2.1.202 [C:\Program Files\dotnet\sdk]
  2.1.400 [C:\Program Files\dotnet\sdk]
  2.2.101 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 1.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

And if it's of any help, one thing I noticed when I tried diagnose this earlier, is that by replacing call to LoadFromAssemblyPath with the below, debugging the second invocation works.

var assembly = loadContext.LoadFromAssemblyName(typeof(Program).Assembly.GetName());

Happy 2019! 馃槈

FWIW, and possibly helping anyone waiting for an answer on this, our team just discovered this is not a bug in JetBrains Rider, while it's still an issue in Visual Studio 2019 + .NET Core 3.0.

Verified this repro in Rider myself, and it works flawlessly.

I'm having this problem as well. Is there any news on when this will be fixed?

I'm having this problem as well. Is there any news on when this will be fixed?

If you didn't notice, it should have been fixed already in october:

This is a known problem (tracked by MS internal workitem https://devdiv.visualstudio.com/DevDiv/_workitems/edit/667860). It has been fixed by @r-ramesh a few days ago.

It's just not clear in what version.

Yes, I saw that, but I still have the issue in the latest VS2017 version and .NET Core 2.2, both of which were released long after that comment.

Yes, I saw that, but I still have the issue in the latest VS2017 version and .NET Core 2.2, both of which were released long after that comment.

Yeah, sad to hear that. We even tested in VS 2019 with .NET Core 3.0 (preview 1) and remained there. See below. The workaround to switch to Rider is not great of course.

FWIW, and possibly helping anyone waiting for an answer on this, our team just discovered this is not a bug in JetBrains Rider, while it's still an issue in Visual Studio 2019 + .NET Core 3.0.

Verified this repro in Rider myself, and it works flawlessly.

The loader context issue fix is in Visual Studio 2019 Preview 2 (https://blogs.msdn.microsoft.com/visualstudio/2019/01/24/visual-studio-2019-preview-2-is-now-available/). Can you give it a try and let us know if it resolves the issue?

The loader context issue fix is in Visual Studio 2019 Preview 2 (https://blogs.msdn.microsoft.com/visualstudio/2019/01/24/visual-studio-2019-preview-2-is-now-available/). Can you give it a try and let us know if it resolves the issue?

Tested now with this repro and works like a charm. Great news. Thanks.

Thanks @per-samuelsson! Closing this issue.

Was this page helpful?
0 / 5 - 0 ratings