Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm][debugger] Fixing race condition #64394

Conversation

thaystg
Copy link
Member

@thaystg thaystg commented Jan 27, 2022

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

ghost commented Jan 27, 2022

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: -

Copy link
Member

@lewing lewing left a comment

Choose a reason for hiding this comment

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

should we make the

src/mono/wasm/runtime/debug.ts Outdated Show resolved Hide resolved
@@ -700,7 +700,7 @@ public PointerValue(long address, int typeId, string varName)
internal class MonoSDBHelper
{
private static int debuggerObjectId;
private static int cmdId;
private static int cmdId = 1;
private static int GetId() {return cmdId++;}
Copy link
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?

@@ -43,7 +43,7 @@ export function mono_wasm_add_dbg_command_received(res_ok: boolean, id: number,
value: base64String
}
};
commands_received = buffer_obj;
commands_received.set(id, buffer_obj);
Copy link
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
Member Author

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?

@@ -700,7 +700,7 @@ public PointerValue(long address, int typeId, string varName)
internal class MonoSDBHelper
{
private static int debuggerObjectId;
private static int cmdId;
private static int cmdId = 1;
Copy link
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?

Copy link
Member

@lewing lewing left a comment

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 on lines 68 to 69
const { res_ok, res } = commands_received.get(id) as CommandResponse;
commands_received.delete(id);
Copy link
Member

@lewing lewing Feb 1, 2022

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
Copy link
Member

@lewing lewing left a comment

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:main Feb 7, 2022
carlossanlop pushed a commit that referenced this pull request Mar 8, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Mar 9, 2022
Sign up for free to 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