Skip to content
master
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Local Lua Debugger for Visual Studio Code

A simple Lua debugger which requires no additional dependencies.


Features

  • Debug Lua using stand-alone interpretor or a custom executable
  • Supports Lua versions 5.1, 5.2, 5.3 and LuaJIT
  • Basic debugging features (stepping, inspecting, breakpoints, etc...)
  • Conditional breakpoints
  • Debug coroutines as separate threads
  • Basic support for source maps, such as those generated by TypescriptToLua

Usage

Lua Stand-Alone Interpreter

To debug a Lua program using a stand-alone interpreter, set lua-local.interpreter in your user or workspace settings:

"lua-local.interpreter": "lua5.1"

Alternatively, you can set the interpreter and file to run in launch.json:

{
  "configurations": [
    {
      "type": "lua-local",
      "request": "launch",
      "name": "Debug",
      "program": {
        "lua": "lua5.1",
        "file": "main.lua"
      }
    }
  ]
}

Custom Lua Environment

To debug using a custom Lua executable, you must set up your launch.json with the name/path of the executable and any additional arguments that may be needed.

{
  "configurations": [
    {
      "type": "lua-local",
      "request": "launch",
      "name": "Debug Custom Executable",
      "program": {
        "command": "executable"
      },
      "args": [
        "${workspaceFolder}"
      ]
    }
  ]
}

You must then manually start the debugger in your Lua code:

require("lldebugger").start()

Note that the path to lldebugger will automatically be appended to the LUA_PATH environment variable, so it can be found by Lua.


Requirements & Limitations

  • The Lua environment must support communication via stdio.
    • Some enviroments may require command line options to support this (ex. Corona requires /no-console flag)
    • Use of io.read or other calls that require user input will cause problems
  • The Lua environment must be built with the debug library, and no other code should attempt to set debug hooks.
  • You cannot manually pause debugging while the program is running.
  • In Lua 5.1 and LuaJIT, the main thread cannot be accessed while stopped inside of a coroutine.

Tips

  • For convenience, a global reference to the debugger is always stored as lldebugger.
  • You can detect that the debugger extension is attached by inspecting the environment variable LOCAL_LUA_DEBUGGER_VSCODE. This is useful for conditionally starting the debugger in custom environments.
    if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
      require("lldebugger").start()
    end
  • Some custom environments will not break on uncaught runtime errors. To catch a runtime error, you can wrap the code with lldebugger.call():
    lldebugger.call(function()
      --code causing runtime error
    end)

Additional Configuration Options

scriptRoots

A list of alternate paths to find lua scripts. This is useful for environments like LÖVE, which use custom resolvers to find scripts in other locations than what is in package.config.

breakInCoroutines

Break into the debugger when errors occur inside coroutines.

  • Coroutines created with coroutine.wrap will always break, regardless of this option.
  • In Lua 5.1, this will break where the coroutine was resumed and the message will contain the actual location of the error.

stopOnEntry

Automatically break on first line after debug hook is set.

cwd

Specify working directory to launch executable in. Default is the project directory.

args

List of arguments to pass to Lua script or custom environment when launching.

env

Specify environment variables to set when launching executable.

verbose

Enable verbose output from debugger. Only useful when trying to identify problems with the debugger itself.


Custom Environment Examples

LÖVE

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Love",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "love"
      },
      "args": [
        "game"
      ],
      "scriptRoots": [
        "game"
      ]
    }
  ]
}
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
  require("lldebugger").start()
end

function love.load()
    ...

Busted

Note that even when using busted via a lua interpreter, it must be set up as a custom environment to work correctly.

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Busted CLI",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "busted"
      },
      "args": [
        "test/start-cli.lua"
      ]
    },
    {
      "name": "Debug Busted via Lua Interpreter",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "lua"
      },
      "args": [
        "test/start-interpreter.lua"
      ]
    }
  ]
}

test/start-cli.lua

if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
  require("lldebugger").start()
end

describe("a test", function()
  ...
end)

test/start-interpreter.lua

--busted should be required before hooking debugger to avoid double-hooking
require("busted.runner")()

if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
  require("lldebugger").start()
end

describe("a test", function()
  ...
end)

About

Local Lua Debugger for VSCode

Resources

License

Packages

No packages published