Skip to content

Conversation

@sbomer
Copy link
Member

@sbomer sbomer commented Apr 1, 2022

Forgot to check for array length in #2689.

I'll see if I can find out what methods were hitting this in dotnet/runtime#67381 (comment), to see if they need different handling.

edit: the logs from that run suggest it might have been hit for the method SimpleWasmTestRunner.<Main>(String[]). I'm not clear on why the main method would be emitted with that name, but in any case this seems to be one example.

@sbomer sbomer requested a review from marek-safar as a code owner April 1, 2022 18:56
@sbomer sbomer requested a review from vitek-karas April 1, 2022 18:56
@sbomer sbomer merged commit b4acac5 into dotnet:main Apr 1, 2022
@akoeplinger
Copy link
Member

edit: the logs from that run suggest it might have been hit for the method SimpleWasmTestRunner.

(String[]). I'm not clear on why the main method would be emitted with that name, but in any case this seems to be one example.

That may be the async state machine since SimpleWasmTestRunner uses async Task<int> Main: https://sharplab.io/#v2:CYLg1APgAgDABFAjAVgNwFgBQWoGYEBMCiA7FgN5ZzUL5IBsCAHAvQDwCWAdgC4B8cALIBDbgAokMANoBdOMIBOAcwDOASio1KmGroQkEATlYA6AGIKA9gFsASgFMVAVwA2PMTDUYdNAL5ZfIA==

@sbomer
Copy link
Member Author

sbomer commented Apr 1, 2022

@akoeplinger thanks, I noticed that too - I still find the mangled method name surprising since it doesn't look like it gets mangled for this simple example: https://sharplab.io/#v2:EYLgtghglgdgNAFxFANgHwAICYCMBYAKAwAYACDHAVgG5CMBmcrUgYVIG9DTvSueKAbOQAc5AQB5YCAHykAstBgAKAJQc+PHlNJRSAXlLFaBTZowBOeYtXHTW0gGoDOW3fIB2Ha+4BfQj6A=.

(Here the state machine type is called <Main>d__0, but the entry point method is still called Main - and this logic should only be getting called on methods.)

@akoeplinger
Copy link
Member

akoeplinger commented Apr 2, 2022

@sbomer it seems to be some issue with SharpLab, if I compile and disassemble the same code locally then I do get this special <Main> method:

  .method private hidebysig specialname static
          int32  '<Main>'() cil managed
  {
    .entrypoint
    .custom instance void [System.Runtime]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( 01 00 00 00 )
    // Code size       19 (0x13)
    .maxstack  1
    .locals init (valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter`1<int32> V_0)
    IL_0000:  call       class [System.Runtime]System.Threading.Tasks.Task`1<int32> C::Main()
    IL_0005:  callvirt   instance valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter`1<!0> class [System.Runtime]System.Threading.Tasks.Task`1<int32>::GetAwaiter()
    IL_000a:  stloc.0
    IL_000b:  ldloca.s   V_0
    IL_000d:  call       instance !0 valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter`1<int32>::GetResult()
    IL_0012:  ret
  } // end of method C::'<Main>'

@ashmind how does SharpLab disassemble the IL? not using ildasm I assume?

@ashmind
Copy link

ashmind commented Apr 2, 2022

@akoeplinger It uses ReflectionDisassembler from ILSpy.

@akoeplinger
Copy link
Member

@ashmind hmm weird, if I use ReflectionDisassembler in a console app with similar code like you have in SharpLab then it does disassemble the <Main> method correctly:

using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;

using (var assemblyFile = new PEFile("_", File.OpenRead("bin/Debug/net6.0/C.dll")))
{
    var output = new PlainTextOutput(Console.Out) { IndentationString = "    " };
    var disassembler = new ReflectionDisassembler(output, CancellationToken.None)
    {
        DebugInfo = null,
        ShowSequencePoints = true
    };

    disassembler.WriteAssemblyHeader(assemblyFile);
    output.WriteLine(); // empty line
    disassembler.WriteModuleContents(assemblyFile);
}

Is it possible to see which flags SharpLab passes to Roslyn?

@ashmind
Copy link

ashmind commented Apr 2, 2022

@akoeplinger
Hmm, if it's an .entrypoint then there is no way to see it in SharpLab currently.
This is because by default SharpLab compiles to OutputKind.DynamicallyLinkedLibrary, so an entry point is not generated.

If you use any top level statements, SharpLab will automatically switch to OutputKind.ConsoleApplication.
However, top level statements will explicitly define Main rather than generating an automatic wrapper for C.Main.

Something I would have to think about -- might be worth having a way to force ConsoleApplication mode.

@akoeplinger
Copy link
Member

@ashmind ahh that explains it, thanks!

I think having a way to force console and maybe being able to view the options passed to Roslyn somewhere would make this clearer in the future 😄

Oh and thank you for creating sharplab, I use it all the time ❤️

agocke pushed a commit to dotnet/runtime that referenced this pull request Nov 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants