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

Blazor-Wasm: StreamReader.ReadLineAsync fails when called in the while loop header compiled in mode Release and Optimize=true #19936

Closed
mkArtakMSFT opened this issue Jun 8, 2020 · 6 comments
Assignees

Comments

@mkArtakMSFT
Copy link


Issue moved from dotnet/aspnetcore#22595

  • Please respond to @Tewr.

From @Tewr on Friday, June 5, 2020 6:19:32 PM

Describe the bug

The following code fails when compiled with Optimize=true:

public async Task<List<string>> ReadLinesBrokenAsync(Stream stream, Encoding encoding)
 {
     using (var reader = new StreamReader(stream, encoding))
     {
         string line;
         var result = new List<string>();

         while ((line = await reader.ReadLineAsync()) != null)
         {
             result.Add(line);
         }
         return result;
     }
 }

await reader.ReadLineAsync() returns null when it shouldn't.

Workaround:

public async Task<List<string>> ReadLinesWorkingAsync(Stream stream, Encoding encoding)
 {
     using (var reader = new StreamReader(stream, encoding))
     {
         string line;
         var result = new List<string>();
         line = await reader.ReadLineAsync();
         while (line != null)
         {
             result.Add(line);
             line = await reader.ReadLineAsync();
         }
         return result;
     }
 }

... or simply compile without Optimize set to true. Linker settings does not seem to have an impact.

To Reproduce

Minimal repro project: https://github.com/Tewr/BlazorStreamReaderOptimizerBug

Exceptions (if any)

Further technical details

First reported here and later here.

Original reporter also posted here:
https://developercommunity.visualstudio.com/content/problem/1055568/blazor-wasm-release-mode-streamreaderreadlineasync.html

  • ASP.NET Core version
  • Include the output of dotnet --info
    .NET Core SDK (reflecting any global.json):
    Version: 5.0.100-preview.1.20155.7
    Commit: 1c44853056

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18362
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.100-preview.1.20155.7\

Host (useful for support):
Version: 5.0.0-preview.1.20120.5
Commit: 3c523a6a7a

.NET Core SDKs installed:
2.1.4 [C:\Program Files\dotnet\sdk]
2.1.103 [C:\Program Files\dotnet\sdk]
2.1.200-preview-007474 [C:\Program Files\dotnet\sdk]
2.1.200 [C:\Program Files\dotnet\sdk]
2.1.201 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.300-preview1-008174 [C:\Program Files\dotnet\sdk]
2.1.300-preview2-008533 [C:\Program Files\dotnet\sdk]
2.1.300 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.600-preview-009472 [C:\Program Files\dotnet\sdk]
2.1.601 [C:\Program Files\dotnet\sdk]
2.1.700-preview-009597 [C:\Program Files\dotnet\sdk]
2.1.700-preview-009618 [C:\Program Files\dotnet\sdk]
2.1.800-preview-009696 [C:\Program Files\dotnet\sdk]
2.2.103 [C:\Program Files\dotnet\sdk]
3.0.100-preview8-013656 [C:\Program Files\dotnet\sdk]
3.0.100-preview9-014004 [C:\Program Files\dotnet\sdk]
3.0.100-rc1-014190 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]
3.1.101 [C:\Program Files\dotnet\sdk]
3.1.200 [C:\Program Files\dotnet\sdk]
3.1.300-preview-015135 [C:\Program Files\dotnet\sdk]
5.0.100-preview.1.20155.7 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.0-preview1-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.0-preview2-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.0-preview1-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.0-preview2-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview7.19365.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview8.19405.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview9.19424.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-rc1.19457.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.0-preview.1.20124.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.7 [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.0-preview1-26216-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.0-preview2-26406-04 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.0 [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.1.3-servicing-26724-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview-27324-5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview7-27912-14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview8-28405-07 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview9-19423-09 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.0-preview.1.20120.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-preview7-27912-14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.0.0-preview8-28405-07 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.0.0-preview9-19423-09 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.0-preview.1.20127.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

  • The IDE (VS / VS Code/ VS4Mac) you're running on, and it's version
    Microsoft Visual Studio Community 2019 Preview
    Version 16.7.0 Preview 1.0
@marek-safar
Copy link
Member

Does this look like potential interpreter bug @BrzVlad ?

@BrzVlad
Copy link
Member

BrzVlad commented Jun 10, 2020

I'm not convinced. I can't reproduce this issue by running the code in a standalone wasm sample. Then again, I'm not exactly sure what this Optimize flag does behind the scenes. Locally I had the code compiled using csc 3.5.0 and made sure I passed -optimize+ to it.

@Tewr
Copy link

Tewr commented Jun 13, 2020

I think you might have noticed, and not sure if significant, but my original description of the bug contains a small incorrectnes: await reader.ReadLineAsync() does not return null, it returns the empty string.

Thus, if you pass a string containing newlines as the source, the while loop will loop as many times as you have newlines.

@Tewr
Copy link

Tewr commented Jun 18, 2020

I updated the example repository and removed a lot of code as it turns out this has nothing to do with StreamReader. Just an async call returning string in while header is enough.

The bug should be renamed "Blazor-Wasm: async Task<string> methods fail when called in the while loop header compiled in mode Release and Optimize=true"

Here is the gist of the reproduction of the bug:

public async Task<List<string>> WhileHeaderBrokenAsync()
    {
        string line;
        var result = new List<string>();
        while ((line = await ReadLineAsync()) != null)
        {
            result.Add(line);
        }
        return result;
    }

    public async Task<string> ReadLineAsync()
    {
        this.i++;
        if (this.i > 3)
        {
            return null;
        }

        return i.ToString();
    }

@BrzVlad BrzVlad self-assigned this Jun 19, 2020
@BrzVlad
Copy link
Member

BrzVlad commented Jun 19, 2020

@Tewr That's a nice small repro case. Thanks

Took a look at this. Observed that I can reproduce with release but not with debug and I can't reproduce at all if I include the offending code inside a separate shared library. Checked how the files get compiled with blazor. Turns out that csc compiles with /optimize+ /debug+ even in release mode, but only for blazor app, shared libraries are compiled with /debug-. @mkArtakMSFT Is there a reason for this or is it a bug ? I don't know whether using /debug+ could result in worse code generated by csc.

Using these compile flags I was able to reproduce the failure outside of wasm, with a desktop app and the result is pretty uninteresting. This issue was fixed already with dotnet/runtime#35524

@BrzVlad BrzVlad closed this as completed Jun 19, 2020
@Tewr
Copy link

Tewr commented Jun 19, 2020

Thanks! @mkArtakMSFT how can I be notified when the fix mentioned above is integrated in blazor, is it already part of a future release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants