Skip to content

[wasm][debugger] Fixing race condition - #64394

Merged
thaystg merged 8 commits into
dotnet:mainfrom
thaystg:thays_fix_race_condition_debugger_event_and_get_debugger_informations
Feb 7, 2022
Merged

[wasm][debugger] Fixing race condition#64394
thaystg merged 8 commits into
dotnet:mainfrom
thaystg:thays_fix_race_condition_debugger_event_and_get_debugger_informations

Conversation

@thaystg

@thaystgthaystg commented Jan 27, 2022

Copy link
Copy Markdown
Member

Unfortunatelly I wasn't able to reproduce it in a test case. To reproduce it using a Blazor app was also very difficult.

I created a separated buffer to receive the "pauses"(breakpoint, exception, user_break, etc.) from the debugger and another buffer to uses to the responses that we receive from debugger when we ask for some information (locals value, invoke method, object values, etc;)

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1427671
Fixes#64474

Test case to reproduce:

Change the content of FetchData.razor in a Blazor app from the template:

@page "/fetchdata"
@using BlazorApp89.Shared
@using System.Collections.ObjectModel
@inject HttpClient Http
<PageTitle>Weather forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await RetForecasts();
var otherVar = await GetObservableCollection();
Console.WriteLine(otherVar);
}
protected async Task<WeatherForecast[]> RetForecasts()
{
var a = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var b = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var c = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var d = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var e = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
Console.WriteLine(e);
return a;
}
protected async Task<ObservableCollection<WeatherForecast>> GetObservableCollection()
{
var forecastsLocal = await RetForecasts();
return new ObservableCollection<WeatherForecast>(forecastsLocal.ToList<WeatherForecast>());
}
}

Add a breakpoint on line: 46, step into hovering the mouse over the WeatherForecast[] on RetForecasts method.

@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @thaystg
See info in area-owners.md if you want to be subscribed.

Issue Details

Unfortunatelly I wasn't able to reproduce it in a test case. To reproduce it using a Blazor app was also very difficult.

I created a separated buffer to receive the "pauses"(breakpoint, exception, user_break, etc.) from the debugger and another buffer to uses to the responses that we receive from debugger when we ask for some information (locals value, invoke method, object values, etc;)

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1427671

Test case to reproduce:

Change the content of FetchData.razor in a Blazor app from the template:

@page "/fetchdata"
@using BlazorApp89.Shared
@using System.Collections.ObjectModel
@inject HttpClient Http
<PageTitle>Weather forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await RetForecasts();
var otherVar = await GetObservableCollection();
Console.WriteLine(otherVar);
}
protected async Task<WeatherForecast[]> RetForecasts()
{
var a = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var b = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var c = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var d = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
var e = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
Console.WriteLine(e);
return a;
}
protected async Task<ObservableCollection<WeatherForecast>> GetObservableCollection()
{
var forecastsLocal = await RetForecasts();
return new ObservableCollection<WeatherForecast>(forecastsLocal.ToList<WeatherForecast>());
}
}

Add a breakpoint on line: 46, step into moving the mouse over the WeatherForecast[] on RetForecasts method.

Author:thaystg
Assignees:-
Labels:

area-Debugger-mono

Milestone:-

@lewinglewing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we make the

Comment threadsrc/mono/wasm/runtime/debug.ts Outdated
private static int debuggerObjectId;
private static int cmdId;
private static int cmdId = 1;
private static int GetId() {return cmdId++;}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this to GetNewId?

}
};
commands_received = buffer_obj;
commands_received.set(id, buffer_obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if there is an existing entry for id.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if there is, should I print a warning?

{
private static int debuggerObjectId;
private static int cmdId;
private static int cmdId = 1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmdId == 0 is a special one now. Can you add a comment for that here?

@lewinglewing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small comment but looks good

Comment threadsrc/mono/wasm/runtime/debug.ts Outdated
Comment on lines +68 to +69
const { res_ok, res } = commands_received.get(id) as CommandResponse;
commands_received.delete(id);

@lewinglewingFeb 1, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest making a method that combines get and delete

thaystg added a commit to thaystg/runtime that referenced this pull request Feb 1, 2022

@lewinglewing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@thaystg
thaystg merged commit 116ee71 into dotnet:mainFeb 7, 2022
carlossanlop pushed a commit that referenced this pull request Mar 8, 2022
@ghostghost locked as resolved and limited conversation to collaborators Mar 9, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VS2022 Blazor debugging with F10/F11 goes into JS minimised code and not my code

3 participants

@thaystg@radical@lewing