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

Can't debug .NET Framework-targeted C# DLLs generated via Roslyn #2223

Open
ciaphas01 opened this Issue Apr 26, 2018 · 11 comments

Comments

Projects
None yet
5 participants
@ciaphas01
Copy link

ciaphas01 commented Apr 26, 2018

(Let me preface this by saying I'm aware that Desktop .NET C# debugging has limited support. That said...)

Environment data

dotnet --info output: dotnet not installed
VS Code version: 1.22.2
C# Extension version: 1.14.0

Steps to reproduce

  1. Create and build a C# program that, using Roslyn, dynamically generates an assembly that appears to meet the requirements for limited debugging support in VS Code.

Code utilized to generate .DLL: (latest versions of Visual Studio and Roslyn Nuget packages)

            Script script = CSharpScript.Create("int x = 0; x += 2;", ScriptOptions.Default
                        .WithReferences(new MetadataReference[] {
                            MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                            MetadataReference.CreateFromFile (typeof(Logger).Assembly.Location) // for Logger class
                        })
                        .WithImports(
                            "ScriptingWindow" // for static Logger class
                            , "System.Collections.Generic" // for IEnumerable goodies
                        ).WithEmitDebugInformation(true));
            var comp = script.GetCompilation().WithOptions(new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary, platform: Platform.X64));

            using (var modFS = new FileStream("UserCode.dll", FileMode.Create))
            using (var pdbFS = new FileStream("UserCode.pdb", FileMode.Create))
            {
                EmitResult result = comp.Emit(modFS, pdbFS, options: new EmitOptions(false, DebugInformationFormat.PortablePdb));
                if (result.Success)
                    Logger.Write("Compiled and saved!");
                else
                {
                    Logger.Write("Failed!");
                }
            }
  1. Add dll to VS Code debug configuration (see launch.json)
  2. Attempt to start debugging.

Expected behavior

Debugger launches and attaches, allowing me to break when my application loads and launches the script contained in that DLL.

Actual behavior

Receive error code 0x800700c1. Turning on engine logging reveals the following:

-> (C) {"command":"initialize","arguments":{"clientID":"vscode","clientName":"Visual Studio Code","adapterID":"clr","pathFormat":"path","linesStartAt1":true,"columnsStartAt1":true,"supportsVariableType":true,"supportsVariablePaging":true,"supportsRunInTerminalRequest":true,"locale":"en-us"},"type":"request","seq":1}
-> (C) {"command":"launch","arguments":{"name":"UserCode","type":"clr","request":"launch","program":"C:\\Users\\jnorm\\Documents\\UserCode/UserCode.dll","args":[],"cwd":"C:\\Users\\jnorm\\Documents\\UserCode","console":"internalConsole","stopAtEntry":true,"logging":{"engineLogging":false},"justMyCode":false,"__sessionId":"651f6060-f602-45f6-8250-e964dfe7b6b8"},"type":"request","seq":2}
<- (E) {"seq":3,"type":"event","event":"output","body":{"category":"console","output":"-------------------------------------------------------------------\nYou may only use the Microsoft .NET Core Debugger (vsdbg) with\nVisual Studio Code, Visual Studio or Visual Studio for Mac software\nto help you develop and test your applications.\n-------------------------------------------------------------------\n"}}
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
<- (R) {"seq":4,"type":"response","request_seq":2,"success":true,"command":"launch"}
<- (E) {"seq":5,"type":"event","event":"initialized","body":{}}
-> (C) {"command":"setExceptionBreakpoints","arguments":{"filters":["all","user-unhandled"]},"type":"request","seq":4}
<- (R) {"seq":6,"type":"response","request_seq":4,"success":true,"command":"setExceptionBreakpoints"}
-> (C) {"command":"configurationDone","type":"request","seq":5}

launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "UserCode",
            "type": "clr",
            "request": "launch",
            //"preLaunchTask": "build",
            "program": "${workspaceFolder}/UserCode.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "console": "internalConsole",
            "stopAtEntry": true,
            //"internalConsoleOptions": "openOnSessionStart"
            "logging":{
                "engineLogging": true
            },
            "justMyCode": false,
        },
// remainder elided
}
@AndrewJRichardson

This comment has been minimized.

Copy link

AndrewJRichardson commented Jun 25, 2018

I have the same issue, once debugging is launched get error 0x800700c1. I also understand this functionality is limited currently, but would prefer not to have to keep jumping between Code and VS, as I much prefer the VS Code experience over Visual Studio.

Engine logging gives

-> (C) {"command":"initialize","arguments":{"clientID":"vscode","clientName":"Visual Studio Code","adapterID":"clr","pathFormat":"path","linesStartAt1":true,"columnsStartAt1":true,"supportsVariableType":true,"supportsVariablePaging":true,"supportsRunInTerminalRequest":true,"locale":"en-gb"},"type":"request","seq":1}
-> (C) {"command":"launch","arguments":{"name":"CLR","type":"clr","request":"launch","preLaunchTask":"build","program":"C:\\Users\\andre\\Documents\\source\\WebApplication1\\WebApplication1/bin/WebApplication1.dll","args":[],"cwd":"C:\\Users\\andre\\Documents\\source\\WebApplication1\\WebApplication1","console":"internalConsole","stopAtEntry":false,"internalConsoleOptions":"openOnSessionStart","logging":{"engineLogging":false},"__sessionId":"cd3165b1-0fd1-48f0-b65a-1eda66a662c6"},"type":"request","seq":2}
<- (E) {"seq":3,"type":"event","event":"output","body":{"category":"console","output":"-------------------------------------------------------------------\nYou may only use the Microsoft .NET Core Debugger (vsdbg) with\nVisual Studio Code, Visual Studio or Visual Studio for Mac software\nto help you develop and test your applications.\n-------------------------------------------------------------------\n"}}
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
<- (R) {"seq":4,"type":"response","request_seq":2,"success":true,"command":"launch"}
<- (E) {"seq":5,"type":"event","event":"initialized","body":{}}
-> (C) {"command":"setExceptionBreakpoints","arguments":{"filters":["user-unhandled"]},"type":"request","seq":4}
<- (R) {"seq":6,"type":"response","request_seq":4,"success":true,"command":"setExceptionBreakpoints"}
-> (C) {"command":"configurationDone","type":"request","seq":5}
-> (C) {"command":"threads","type":"request","seq":6}
<- (E) {"seq":7,"type":"event","event":"output","body":{"category":"telemetry","output":"VS/Diagnostics/Debugger/vsdbg/LaunchFailed","data":{"VS.Diagnostics.Debugger.vsdbg.OSFamily":"Windows","VS.Diagnostics.Debugger.vsdbg.Version":"15.7.20515.3 commit:e54b6660abc5bdb699607ee63ea2a5a9ae5b32b5","VS.Diagnostics.Debugger.vsdbg.WindowsVersion":"6.2.9200","VS.Diagnostics.Debugger.vsdbg.ErrorCode":-2147024703}}}
<- (R) {"seq":8,"type":"response","request_seq":5,"success":false,"command":"configurationDone","message":"Unknown Error: 0x800700c1"}
<- (E) {"seq":9,"type":"event","event":"output","body":{"category":"telemetry","output":"VS/Diagnostics/Debugger/vsdbg/CommandFailed","data":{"VS.Diagnostics.Debugger.vsdbg.OSFamily":"Windows","VS.Diagnostics.Debugger.vsdbg.Version":"15.7.20515.3 commit:e54b6660abc5bdb699607ee63ea2a5a9ae5b32b5","VS.Diagnostics.Debugger.vsdbg.WindowsVersion":"6.2.9200","VS.Diagnostics.Debugger.vsdbg.Command":"threads","VS.Diagnostics.Debugger.vsdbg.ErrorCode":-1842151413,"VS.Diagnostics.Debugger.vsdbg.AdapterId":"clr"}}}
<- (R) {"seq":10,"type":"response","request_seq":6,"success":false,"command":"threads","message":"Error processing 'threads' request. Unknown Error: 0x9233000b"}
-> (C) {"command":"disconnect","arguments":{"restart":false},"type":"request","seq":7}
<- (E) {"seq":11,"type":"event","event":"output","body":{"category":"telemetry","output":"VS/Diagnostics/Debugger/vsdbg/DebugCompleted","data":{"VS.Diagnostics.Debugger.vsdbg.OSFamily":"Windows","VS.Diagnostics.Debugger.vsdbg.Version":"15.7.20515.3 commit:e54b6660abc5bdb699607ee63ea2a5a9ae5b32b5","VS.Diagnostics.Debugger.vsdbg.WindowsVersion":"6.2.9200","VS.Diagnostics.Debugger.vsdbg.DebugCompleted.BreakCounter":0,"VS.Diagnostics.Debugger.vsdbg.AdapterId":"clr"}}}
<- (R) {"seq":12,"type":"response","request_seq":7,"success":true,"command":"disconnect"}
 

I did notice in the window log that the renderer has the following issue every time I attempt to debug, I have tested other C# applications that successfully launch the debugger and I do not get the same error:

[renderer1] [error] Error processing 'threads' request. Unknown Error: 0x9233000b: Error: Error processing 'threads' request. Unknown Error: 0x9233000b
    at file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:2459:933
    at Object.v [as _notify] (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:150:375)
    at Object.enter (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:153:592)
    at n.Class.derive._oncancel._run (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:154:896)
    at n.Class.derive._oncancel._error (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:154:413)
    at file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:2460:151
    at t.e.acceptMessage (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:2398:968)
    at t.handleData (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:2399:804)
    at Socket.<anonymous> (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:2399:300)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:191:7)
    at readableAddChunk (_stream_readable.js:178:18)
    at Socket.Readable.push (_stream_readable.js:136:10)
    at Pipe.onread (net.js:560:20)
@gregg-miskelly

This comment has been minimized.

Copy link
Contributor

gregg-miskelly commented Jun 25, 2018

@ciaphas01 @AndrewJRichardson sorry, this feel through the cracks earlier.

0x800700c1 means that there was an attempt to execute a program that isn't a valid executable (win32 error code ERROR_BAD_EXE_FORMAT).

Looking at ciaphas01's launch.json, this is because program pointing at a .dll. That works for .NET Core because .NET Core has a launcher program (dotnet.exe). But for full framework, there is no such launcher program. So you need to point program at the .exe you want to run.

@AndrewJRichardson do you have the same problem?

Here is the documentation we have on desktop .NET development: https://github.com/OmniSharp/omnisharp-vscode/wiki/Desktop-.NET-Framework

@AndrewJRichardson

This comment has been minimized.

Copy link

AndrewJRichardson commented Jun 25, 2018

@gregg-miskelly Yeah, I am trying to debug an ASP.net desktop application, which as far as I am aware don't have exes as they are run through IIS.

So my guess is I need to set up a script to deploy debug dev builds to a local IIS and then attach the debugger to that. Does that sound accurate?

Any plans to support this natively in the future (or is there something simple I am missing)? I understand that Code is a multi-plat editor and so the extension is focused on .net core, but it seems kind of a waste to not support the full framework.

Thanks for the info anyway.

EDIT: I figured out I could just use a publish profile and deploy on build property switches with MSBuild so the script part was not as complex as I thought it would be. It would still be nice to see first class support for CLR in the app though if possible :).

@gregg-miskelly

This comment has been minimized.

Copy link
Contributor

gregg-miskelly commented Jun 25, 2018

@AndrewJRichardson Assuming there is a 64-bit version of IIS Express (and your app supports running there), it would probably be easier to launch IIS Express in the right way to load your dll.

As you said, the debugging support in VS Code is primarily focused on cross-platform aspects. We have added some basic full framework support for scenarios where the cost was reasonable (ex: launching an exe). The cost for fully supporting all projects is pretty enormous, so Visual Studio will always have a breadth of support that this extension will not be able to match. That said, better integration with something like IISExpress might be possible.

@AndrewJRichardson

This comment has been minimized.

Copy link

AndrewJRichardson commented Jun 25, 2018

Ahh yes, Express would be the better option, can update frontend files without needing to redeploy each time, thanks.

Yeah I can imagine supporting all projects would be monumental undertaking. Better integration with IIS Express would likely be enough for most local debugging needs in terms of web apps. Though it wasn't too much of a hassle to set up in the end and learnt something while doing it.

@szul

This comment has been minimized.

Copy link
Contributor

szul commented Sep 3, 2018

@AndrewJRichardson Mind sharing your solution for getting the debugger running under non-Core ASP.NET? I’ve been stuck on this for a bit. If you have an example launch.json and CSPROJ that would be awesome.

@gregg-miskelly

This comment has been minimized.

@AndrewJRichardson

This comment has been minimized.

Copy link

AndrewJRichardson commented Sep 3, 2018

@szul I don't know how far you have got with this so I will explain each step.

DISCLAIMER: I am not an expert in building/running C# and ASP.net outside of Visual Studio, most of the stuff I mention here I only learned through trying to get debugging working in VS Code. There may be much better ways to do this I am unaware of.

Inside the csproj of your project you need to set the debug type to portable. If your solution contains multiple projects you will need to change the csproj of each one you want to be able to debug. Each config has a debug type, so you may need to change multiple.

If the solution has ever been opened in Visual Studio it seems the default build task will suffice for the building, though you can add some args to set which config you would like it to run.

The slightly wonky bit comes from getting it to run. You need to goto the application host file for IIS express. Usually in Documents > IISExpress > Config. If you edit that file and add a site (or see if the project you are running already has a site in that file). They look something like this:

<site name="aSite" id="38">
    <application path="/" applicationPool="Clr4IntegratedAppPool">
        <virtualDirectory path="/" physicalPath="C:/path/to/project/folder" />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:64177:localhost" />
     </bindings>
</site>

Once you have the site in that file you can look launch IIS Express with a site argument. So for the site above it would be: iisexpress /site:aSite. You don't need to restart IIS express each time you make changes, it will detect changes when you build.

When you want to debug just attach to IIS express with a launch task like this:

{
    "name": "iis express",
    "type": "clr",
    "request": "attach",
    "preLaunchTask": "a Pre-launch task",
    "processName": "iisexpress"
},

I usually have a pre-launch task that builds the project and opens a browser window to the right address, so starting a debug will have behavior similar to Visual Studio.

@szul

This comment has been minimized.

Copy link
Contributor

szul commented Sep 3, 2018

@gregg-miskelly I have. Wasn’t able to get the debugger to attach without error. Talked a bit with the Microsoft guy who added the PR, but couldn’t get it running correctly.

@AndrewJRichardson Thanks! I’ll try this route. Didn’t have any IISExpress configuration changes, so maybe that will make the difference.

@szul

This comment has been minimized.

Copy link
Contributor

szul commented Sep 12, 2018

@AndrewJRichardson This got it working. I use the IIS Express VSCode extension, so I didn't need to do anything with the application config changes. It made those automatically. I think the secret sauce missing from my previous attempts was doing an "attach" debug process. I was attempting to launch the application and debug all in one shot.

@AndrewJRichardson

This comment has been minimized.

Copy link

AndrewJRichardson commented Sep 13, 2018

@szul Yeah I had the same problem, though I forgot to mention it. I don't use the extension but If you run IIS Express as a task it will block any tasks you have chained after it, until it is exited. I'm not sure if there is a way around that with VS Code's task runner but since IIS Express updates after builds without needing to be restarted I just kept it as a completely separate task that I run once and then forget about.

Anyway glad you got it sorted!

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