OYIon / LiveSharp

Public repository for the LiveSharp project
96 stars 4 forks source link

LiveSharp.Runtime.IL.DocumentMetadata.DeserializeTypes fails - Breaks Debugging #83

Closed warappa closed 1 year ago

warappa commented 4 years ago

Using LiveSharp 1.5.53

In the repo-project of #79 I was experimenting with editing the controller-action of WeatherForecastController.cs (not the same project as in #82).

By changing

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    var rng = new Random();
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = rng.Next(-20, 55),
        Summary = Summaries[rng.Next(Summaries.Length)]
    })
    .ToArray();
}

to

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    var rng = new Random();
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = rng.Next(-20, 55),
        Summary = "SOME PREFIX" + Summaries[rng.Next(Summaries.Length)] // <-- this change
    })
    .ToArray();
}

the code is indeed updated and the next invokation returns the data with the prefix. So far, so good.

But debugging breaks (breakpoints not hit anymore there) and in the output window I get an InvalidOperationException in LiveSharp.Runtime.IL.DocumentMetadata.DeserializeTypes:

error: System.InvalidOperationException: Microsoft.AspNetCore.Routing.IEndpointRouteBuilder, Microsoft.AspNetCore.Routing, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60 not found
  at LiveSharp.Runtime.IL.DocumentMetadata.DeserializeTypes (System.Xml.Linq.XElement[] types) <0x37012c0 + 0x0018e> in <filename unknown>:0 
  at LiveSharp.Runtime.IL.DocumentMetadata..ctor (System.Xml.Linq.XElement documentElement, LiveSharp.Runtime.Virtual.VirtualAssembly virtualAssembly, LiveSharp.ILogger logger, System.Func`2[T,TResult] methodFilter) <0x3486c30 + 0x0012c> in <filename unknown>:0 
  at LiveSharp.Runtime.LiveSharpRuntime.UpdateDocument (System.Xml.Linq.XElement element, System.Func`2[T,TResult] methodFilter) <0x3485dc0 + 0x00016> in <filename unknown>:0 
  at LiveSharp.Runtime.LiveSharpRuntime.LiveSharpMessageReceived (System.String messageContent, System.Byte contentType, System.Int32 groupId) <0x3448620 + 0x0003e> in <filename unknown>:0 

In my Blazor WASM project it tries to deserialize types from the server host project. As the Blazor WASM project has no reference to this DLLs, it cannot find those types. Therefore it throws an InvalidOperationException.

Suggestion

Handle not found types more gracefully (ignore them or just warn about it). Don't throw an InvalidOperationException but keep deserializing the rest of the types.

EDIT

Removing LiveSharp from Blazor WASM project but keeping it in server host project, no exception is thrown and the breakpoint keeps getting hit aka. debugging continues to work!

warappa commented 4 years ago

That's maybe interesting:

Although I only update this one controller action (as above), I get almost all the methods/properties/fields of the assembly listed as "updated" - is this expected 🤔?

received C# update
Received update for method Program.Main
Received update for method Program.CreateHostBuilder
Received update for method Program..ctor
Received update for method Program+<>c..cctor
Received update for method Program+<>c..ctor
Received update for method Program+<>c.<CreateHostBuilder>b__1_0
Received update for method Startup..ctor
Received update for method Startup.get_Configuration
Received update for method Startup.ConfigureServices
Received update for method Startup.Configure
Received update for method Startup+<>c..cctor
Received update for method Startup+<>c..ctor
Received update for method Startup+<>c.<Configure>b__5_0
Received update for method ErrorModel.get_RequestId
Received update for method ErrorModel.set_RequestId
Received update for method ErrorModel.get_ShowRequestId
Received update for method ErrorModel..ctor
Received update for method ErrorModel.OnGet
Received update for method WeatherForecastController..ctor
Received update for method WeatherForecastController.Get
Received update for method WeatherForecastController..cctor
Received update for method WeatherForecastController+<>c__DisplayClass3_0..ctor
Received update for method WeatherForecastController+<>c__DisplayClass3_0.<Get>b__0
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Program+<>c.<>9
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Program+<>c.<>9__1_0
Received update for property RepoLiveSharpUpdateFailsWithMatBlazor.Server.Startup.Configuration
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Startup.<Configuration>k__BackingField
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Startup+<>c.<>9
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Startup+<>c.<>9__5_0
Received update for property RepoLiveSharpUpdateFailsWithMatBlazor.Server.Pages.ErrorModel.RequestId
Received update for property RepoLiveSharpUpdateFailsWithMatBlazor.Server.Pages.ErrorModel.ShowRequestId
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Pages.ErrorModel.<RequestId>k__BackingField
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Pages.ErrorModel._logger
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Controllers.WeatherForecastController.Summaries
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Controllers.WeatherForecastController.logger
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Controllers.WeatherForecastController+<>c__DisplayClass3_0.rng
Received update for field RepoLiveSharpUpdateFailsWithMatBlazor.Server.Controllers.WeatherForecastController+<>c__DisplayClass3_0.prefix
error: System.InvalidOperationException: Microsoft.AspNetCore.Hosting.IWebHostBuilder, Microsoft.AspNetCore.Hosting.Abstractions, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60 not found
  at LiveSharp.Runtime.IL.DocumentMetadata.DeserializeTypes (System.Xml.Linq.XElement[] types) <0x380fdd0 + 0x0018e> in <filename unknown>:0 
  at LiveSharp.Runtime.IL.DocumentMetadata..ctor (System.Xml.Linq.XElement documentElement, LiveSharp.Runtime.Virtual.VirtualAssembly virtualAssembly, LiveSharp.ILogger logger, System.Func`2[T,TResult] methodFilter) <0x35690e0 + 0x0012c> in <filename unknown>:0 
  at LiveSharp.Runtime.LiveSharpRuntime.UpdateDocument (System.Xml.Linq.XElement element, System.Func`2[T,TResult] methodFilter) <0x3568270 + 0x00016> in <filename unknown>:0 
  at LiveSharp.Runtime.LiveSharpRuntime.LiveSharpMessageReceived (System.String messageContent, System.Byte contentType, System.Int32 groupId) <0x3536c00 + 0x0003e> in <filename unknown>:0 
Exception thrown: 'System.Net.WebSockets.WebSocketException' in System.Net.WebSockets.dll

Worth noting:

ionoy commented 4 years ago

First issue

It seems like LiveSharp Runtime in the Client tries to handle the Server update. That's why it fails. I should probably add a project identifier with an update to mitigate that.

Second issue

Most recent LiveSharp builds compare two assemblies and calculate diff that needs to be sent to the application. In most cases, this is pretty efficient and error-proof. Unfortunately, with some code updates, the compiler changes all the metadata tokens, which means that raw IL is different. I need to create some kind of metadata map that would account for these changes.

EDIT: By the way, debugging will probably be supported with .NET 5.0 https://github.com/dotnet/corefx/pull/38749