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

Setting environment variable for adapter deletes them all instead. #1088

Open
FalcoGer opened this issue Nov 11, 2023 · 5 comments
Open

Setting environment variable for adapter deletes them all instead. #1088

FalcoGer opened this issue Nov 11, 2023 · 5 comments

Comments

@FalcoGer
Copy link

FalcoGer commented Nov 11, 2023

Debug adapter definition and debug configuration

I want to use gdb as my adapter. I have the pwndbg extension installed in gdb and I would like to use it. In my ~/.gdbinit I load it with the ~ shorthand for the home directory.

However pwndbg prints ansi color sequences. To prevent that, you can configure an environment variable PWNDBG_DISABLE_COLORS=1.

This is my adapter:

    dap.adapters.gdb = {
        type = "executable",
        command = "/usr/local/bin/gdb",
        args = { "--interpreter", "dap" },
        options = {
            env = env,
        },
    }

When not setting env in options, gdb knows about all the environment variables. For example when I start a session with DAP and use REPL and type in shell echo ${HOME} it prints the correct home directory.

When I do set env in options, pwndbg does not load at all, because it can not determine the correct path from ~, presumably because ${HOME} isn't set.

Furthermore there is no documentation for what format env is supposed to be. I have tried

local env = {}
env["PWNDBG_DISABLE_COLORS"] = "1"
local env = {"PWNDBG_DISABLE_COLORS", "1"}
local env = {{"PWNDBG_DISABLE_COLORS", "1"}}
local env = {PWNDBG_DISABLE_COLORS = "1"}

and

local env = {"PWNDBG_DISABLE_COLORS=1"}

none of which seem to be setting that environment variable, that is shell echo ${PWNDBG_DISABLE_COLORS} in REPL does only print an empty line.

The only thing that comes up when I type shell env in REPL is this

dap> shell env
LC_CTYPE=C.UTF-8
COLUMNS=80
PWD=/home/****/Documents/test
LINES=24

When not setting env in options I get dozens of environment variables.

My configuration

    -- local env = {"PWNDBG_DISABLE_COLORS=1"}
    dap.adapters.gdb = {
        type = "executable",
        command = "/usr/local/bin/gdb",
        args = { "--interpreter", "dap" },
        options = {
        --    env = env,
        },
    }

    -- debugee configuration
    dap.configurations.c = {
        {
        name = "Launch",
        type = "gdb",
        request = "launch",
        program = function()
            return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
        end,
        cwd = "${workspaceFolder}",
        },
    }
    dap.configurations.cpp = dap.configurations.c
    dap.configurations.rust = dap.configurations.c

Debug adapter version

9d81c11

Steps to Reproduce

  1. Configure GDB for cpp (see config above)
  2. Compile some cpp source file and set a breakpoint
  3. Run debugging session
  4. Open REPL
  5. type shell env to send that command to gdb
  6. take note of the number of envirionment variables
  7. close nvim
  8. edit the config file and add any envionment variable
  9. open cpp source file and set a breakpoint
  10. run debugging session
  11. open REPL
  12. type shell env
  13. take note that almost everything is gone, and that the variable you have tried to set is not there either.

Expected Result

  • All environment variables are preserved
  • The ones added via options.env are also present
  • Documentation for the format of env and maybe an example

Actual Result

  • Almost all environment variables are purged
  • The ones added via options.env are also not present
  • Only a mention in the documentation that the field exists at all
@FalcoGer
Copy link
Author

Tried

    local osEnv = {}

    for line in io.popen("set"):lines() do
        envName = line:match("^[^=]+")
        osEnv[envName] = os.getenv(envName)
    end
    osEnv["PWNDBG_DISABLE_COLORS"] = "1"

    dap.adapters.gdb = {
        type = "executable",
        command = "/usr/local/bin/gdb",
        args = { "--interpreter", "dap" },
        options = {
        --    env = env,
            env = osEnv,
        },
    }

But that also cleared out everything.

@FalcoGer
Copy link
Author

FalcoGer commented Nov 14, 2023

Found a workaround. After installing the posix library (sudo luarocks --lua-version=5.1 install luaposix), I can do this.

    require('posix').setenv("PWNDBG_DISABLE_COLORS", "1")
    dap.adapters.gdb = {
        type = "executable",
        command = "/usr/local/bin/gdb",
        args = { "--interpreter", "dap" },
    }

FalcoGer added a commit to FalcoGer/dotfiles that referenced this issue Nov 14, 2023
@JacobCrabill
Copy link

Encountering this same issue myself. Here's my workaround:

Core config file:

-- Configure the GDB adapter to allow loading local .gdbinit files
dap.adapters.gdb = {
  type = "executable",
  command = gdb_bin,
  args = { "-i", "dap", "-iex", "set auto-load safe-path " .. vim.fn.getcwd() },
  name = 'gdb'
}

Project-specific config file (I use a Telescope picker that loads configurations from a dap-config.lua in the current working directory):

-- Create a .gdbinit file that sets up the desired dnvironment variables
local function setup_gdbinit(custom_env, cwd)
  local gdbinit = cwd or vim.fn.getcwd()
  gdbinit = gdbinit .. '/.gdbinit'
  local f = io.open(gdbinit, 'w')
  if f ~= nil then
    print('Opened file ' .. gdbinit .. ' for storing environment')
    for key, value in pairs(custom_env) do
      f:write('set env ' .. key .. '=\"' .. value .. '\"\n')
    end
    f:close()
  else
    error("Unable to open file '" .. gdbinit .. ".gdbinit' for editing")
  end
end
                                                                         
return {
  configurations = {
    cpp = {
      {
        name = "My Test Executable with GDB + Custom env",
        type = 'gdb',
        request = 'launch',
        cwd = '${workspaceFolder}',
        stopOnEntry = false,
        program = function()
          -- Specify any desired environment variables
          local custom_env = {
            LD_LIBRARY_PATH = vim.env.LD_LIBRARY_PATH .. ':' .. vim.env.HOME .. '/.local/lib/',
            PATH = vim.env.PATH ..  ':' .. vim.env.HOME .. '/.local/bin/',
          }
          setup_gdbinit(custom_env)
          -- The executable to debug
          return 'build/bin/my_test'
        end,
        args = { '-a', '-b', '-o', 'foo.out' },
      },
    },
  },
                                                                         
  adapters = {}
}

@kirillrogovoy
Copy link

Faced the same problem. Worked around it by creating a wrapper script to simply set the env:

#!/bin/sh
ELS_ELIXIR_OPTS="--sname sunrise --cookie secret" exec /Users/kirillrogovoy/.cache/nvim/elixir-tools.nvim/installs/elixir-lsp/elixir-ls/tags_v0.21.1/1.16.2-26/debug_adapter.sh

@mfussenegger
Copy link
Owner

mfussenegger commented Jun 1, 2024

Note that the env option on the adapter is for the adapter process itself.

To set the environment variables for your application you need to set an option in the launch configuration. Usually it is called env, but it might differ from adapter to adapter.

See https://sourceware.org/gdb/current/onlinedocs/gdb.html/Debugger-Adapter-Protocol.html for the gdb docs.

As for the removal of the adapters env variables and its format
I'm inclined to keep that behavior, if it would implicitly inherit and extend the variables there wouldn't be a straightforward way to remove any. (x = nil in lua removes a key, I'd have to special case it for vim.NIL or something)
But I guess it would make sense to at least add PATH, and to document and change the format to an object. This would also mirror the behavior of nvim-lint.

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

No branches or pull requests

4 participants