Samsung / netcoredbg

NetCoreDbg is a managed code debugger with GDB/MI, VSCode DAP and CLI interfaces for CoreCLR.
MIT License
838 stars 103 forks source link

vscode interpreter does not load launchSettings.json #137

Closed Jarvismkennedy closed 1 year ago

Jarvismkennedy commented 1 year ago

I am trying to get debugging setup for C# projects in Neovim. I have also tried in vscodium and I am having the same issue, the launchSettings.json is not being loaded so I am missing environment variables that are defined there. The debugger starts but the program just creashes with an argument null exception because the environment variables are not set.

If I start the debugger in cli mode with netcoredbg --interpreter=cli -- dotnet run path/to/my/dll, then it runs fine, but if I start the debugger using neovim-dap with the vscode interpreter, or if I run the debugger from vscodium, the program crashes because of the missing environment variables.

Is there a workaround for this?

viewizard commented 1 year ago

Debugger don't really need any environment variables for start debuggee process. You just confirme this by netcoredbg --interpreter=cli -- dotnet run path/to/my/dll. Please, provide vscode protocol log with Neovim<->netcoredbg interaction.

Jarvismkennedy commented 1 year ago

The process starts, but it crashes on an argument null exception because an environment variable which is defined in launchSettings.json is never set.

Here is the exact setup, I create a new web app with dotnet new webapp, and change the default Properties/launchSettings.json to:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:44139",
      "sslPort": 44347
    }
  },
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5114",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "MY_ENV_VAR": "TEST_VAR"
      }
    },
    "https": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:7070;http://localhost:5114",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "MY_ENV_VAR": "TEST_VAR"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "MY_ENV_VAR": "TEST_VAR"
      }
    }
  }
}

then in the Program.cs I have

var env_var = Environment.GetEnvironmentVariable("MY_ENV_VAR");
Console.WriteLine(env_var);
if (env_var is null)
{
    throw new Exception("MY_ENV_VAR is null");
}

using the command dotnet run I get the console output TEST_VAR, but running the debugger with the vscode interpreter throws the exception.

And here is the log dap_log.txt

viewizard commented 1 year ago

This looks like launchSettings.json is MSVS IDE configuration file, VSCode IDE (and probably vscodium) use .vscode/launch.json for the same... https://learn.microsoft.com/en-gb/aspnet/core/fundamentals/environments?view=aspnetcore-7.0#development-and-launchsettingsjson

You probably could use env ASPNETCORE_ENVIRONMENT=Development MY_ENV_VAR=TEST_VAR netcoredbg for start debugger instead, child process should receive all parent's envs. Or try env ASPNETCORE_ENVIRONMENT=Development MY_ENV_VAR=TEST_VAR dotnet ... in order to start debuggee with envs you need.

Jarvismkennedy commented 1 year ago

Okay, thanks for the help. I don't really understand whats going on here because it seems to read the launchSettings.json when I run it with the cli interpreter rather than the vscode interpreter.

But I will just parse the json and set the env vars myself when launching the debugger, this seems to be working.

Jarvismkennedy commented 1 year ago

Here is a working dap config in case anyone finds this thread trying to setup netcoredbg in neovim. I am keeping the environment variables as json at project_root/.nvim/env.json

dap.adapters.coreclr = {
    type = "executable",
    command = "/usr/local/netcoredbg",
    args = { "--interpreter=vscode", "--engineLogging=dap_log.txt" },
}

vim.g.dotnet_build_project = function()
    local default_path = vim.fn.getcwd() .. "/"
    if vim.g["dotnet_last_proj_path"] ~= nil then
        default_path = vim.g["dotnet_last_proj_path"]
    end
    local path = vim.fn.input({ prompt = "Path to your *proj file: ", default = default_path, completion = "file" })
    vim.g["dotnet_last_proj_path"] = path
    local cmd = 'dotnet build -c Debug "' .. path .. '"'
    print("\n")
    print("Cmd to execute: " .. cmd)
    local f = os.execute(cmd)
    if f == 0 then
        print("\nBuild: OK")
    else
        print("\nBuild: ERR: " .. f)
    end
end

vim.g.dotnet_get_dll_path = function()
    local request = function()
        return vim.fn.input({
            prompt = "Path to dll: ",
            default = vim.fn.getcwd() .. "/bin/Debug/",
            completion = "file",
        })
    end

    if vim.g["dotnet_last_dll_path"] == nil then
        vim.g["dotnet_last_dll_path"] = request()
    else
        if
            vim.fn.confirm("Do you want to change the path to dll?\n" .. vim.g["dotnet_last_dll_path"], "&yes\n&no", 2)
            == 1
        then
            vim.g["dotnet_last_dll_path"] = request()
        end
    end
    return vim.g["dotnet_last_dll_path"]
end
local launch_json = vim.fn.getcwd() .. "/.nvim/env.json"
local readAll = function(file)
    local f = assert(io.open(file, "rb"))
    local content = f:read("*all")
    f:close()
    return content
end

local load_json = function()
    return vim.json.decode(readAll(launch_json))
end
vim.g.dotnet_get_env = function()
    if vim.g["dotnet_env_vars"] == nil then
        vim.g["dotnet_env_vars"] = load_json()
    end
    return vim.g["dotnet_env_vars"]
end

local config = {
    {
        type = "coreclr",
        name = "launch - netcoredbg",
        request = "launch",
        console = "integratedTerminal",
        env = vim.g.dotnet_get_env,
        program = function()
            if vim.fn.confirm("Should I recompile first?", "&yes\n&no", 2) == 1 then
                vim.g.dotnet_build_project()
            end
            local dll = vim.g.dotnet_get_dll_path()
            return dll
        end,
    },
}
dap.configurations.cs = config