Code Monkey home page Code Monkey logo

local-lua-debugger-vscode's Introduction

Local Lua Debugger for Visual Studio Code

A simple Lua debugger which requires no additional dependencies.


Notice of Breaking Change

Beginning in version 0.3.0, projects which use sourcemaps to debug code transpiled from another language (such as TypescriptToLua), must specify the scriptFiles launch configuration option in order to use breakpoints in the original source files. This allows these to be resolved at startup instead of at runtime which allows for a significant performance increase.


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 either stdio or pipes (named pipes on Windows, fifos on Linux).
    • Some enviroments may require command line options to support stdio communication (ex. Solar2D requires /no-console flag)
    • Use of io.read or other calls that require user input will cause problems in stdio mode. Set program.communication to pipe to work around this.
  • 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)
  • Some environments will not load required files from the standard filesystem. In these cases, you may be able to load the debugger manually using the file path stored in LOCAL_LUA_DEBUGGER_FILEPATH:
    package.loaded["lldebugger"] = assert(loadfile(os.getenv("LOCAL_LUA_DEBUGGER_FILEPATH")))()
    require("lldebugger").start()

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.

scriptFiles

A list of glob patterns identifying where to find Lua scripts in the workspace when debugging. This is required for placing breakpoints in sourcemapped files (ex. 'ts' scripts when using TypescriptToLua), as the source files must be looked up ahead of time so that breakpoints can be resolved.

Example: scriptFiles: ["**/*.lua"]

ignorePatterns

A list of Lua patterns that specifies files to skip when stepping through code.

Example: ignorePatterns: ["^/usr"]

stepUnmappedLines

Step into Lua when stepping through source-mapped code and no mapping is available for the current line.

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.

program.communication

Specifies how the extension communicates with the debugger.

Possible values:

  • stdio (default): Messages are embeded in stdin and stdout.
  • pipe: Pipes are created for passing messages (named pipes on Windows, fifos on Linux). Use this if your environment has issues with stdio communication.

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()
  ...

Note that console must be set to false (the default value) in conf.lua, or the debugger will not be able to communicate with the running program.

game/conf.lua

function love.conf(t)
  t.console = false
end

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"
      ],
      "ignorePatterns": "^/usr"
    },
    {
      "name": "Debug Busted via Lua Interpreter",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "lua"
      },
      "args": [
        "test/start-interpreter.lua"
      ],
      "ignorePatterns": "^/usr"
    }
  ]
}

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)

Defold

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "dmengine"
      },
      "args": ["./build/default/game.projectc"],
      "scriptRoots": ["."] // Required for debugger to find scripts
    }
  ]
}
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
  local lldebugger = loadfile(os.getenv("LOCAL_LUA_DEBUGGER_FILEPATH"))()
  lldebugger.start()
end

function init(self)
  ...
end

Information on downloading dmengine for your platform can be found here.

Solar2D / Corona

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug",
      "type": "lua-local",
      "request": "launch",
      "windows": {
        "program": {
          "command": "C:\\Program Files (x86)\\Corona Labs\\Corona\\Corona Simulator.exe",
        },
        "args": [
          "/no-console",
          "/debug",
          "${workspaceFolder}\\main.lua"
        ]
      },
      "osx": {
        "program": {
          "command": "/Applications/Corona/CoronaSimulator.app/Contents/MacOS/CoronaSimulator",
        },
        "args": [
          "-no-console"
          "YES"
          "-debug"
          "1"
          "-project"
          "${workspaceFolder}/main.lua"
        ]
      }
    }
  ]
}
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
  local lldebugger = loadfile(os.getenv("LOCAL_LUA_DEBUGGER_FILEPATH"))()
  lldebugger.start()
end

...

TypescriptToLua (Custom Environment)

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug TSTL",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "my_custom_environment"
      },
      "args": [
        ...
      ],
      "scriptFiles": ["**/*.lua"] // Required for breakpoints in ts files to work
    }
  ]
}
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
  require("lldebugger").start()
end

...

tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    ...
  },
  "tstl": {
    "noResolvePaths": ["lldebugger"] // Required so TSTL ignores the missing dependency
  }
}

local-lua-debugger-vscode's People

Contributors

dependabot[bot] avatar tomblind avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

local-lua-debugger-vscode's Issues

Printing problems

Printing {{}} prints }}

This code causes the debugger to stop working/hang:

print("{method = \"test\"}")
print("{{}}")

arg is not forwarded to lua program

The arg variable, which contains a command line arguments passed to the lua program, is nil when run in the debugger. This should be set the same is if the program was run normally.

Corona SDK config setup

I created a launch environment for Corona SDK, but the one issue I ran into is that it doesn't automatically find lldebugger when I do require("lldebugger").start(). What I ended up doing was copying in the lldebugger.lua file from inside the extension.
Is this because it was launched from Corona SDK?

For anyone wanting to debug Corona SDK:

{
    // 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": [
        {
            "type": "lua-local",
            "request": "launch",
            "name": "Debug Corona",
            "program": {
                "command": "/Applications/Corona/CoronaSimulator.app/Contents/MacOS/CoronaSimulator"
            },
            "args": [
                "-no-console YES -debug 1 -project ${workspaceFolder}/main.lua"
            ]
        }
    ]
}

Also I removed the spaces from the path and created a copy there. Do you know how to use spaces in the path?

Thanks for the great extension! :)

Sincerely,
Michael Wickey

Allow skipping specific paths

I am using this addon with busted framework and each time im running the debugger i need to cycle through a lot of busted internal files. It was ok at first but now It would be nice if there is an option to skip specific paths

For example a path such as /usr/local/share/lua/5.1/busted/environment.lua could be skipped by ignoring all paths that start with /usr/local/share/ or just /usr

Maybe this might be helpful but i'm using the following launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Busted - Lua Interpreter",
            "type": "lua-local",
            "request": "launch",
            "program": {
                "command": "busted"
            },
            "args": [
                "-o ./lua/test/glua_test.lua",
                "-m ./lua/?.lua",
                "--helper lua/test/init.lua",

                // unit testing
                "lua/test/setup.lua",
                "lua/test/file.lua"
            ],
        }
    ]
}

Correctly parse absolute paths on macOS & Linux in some cases

[drive, pathPart] = path.match(`^[@=]?([\\/]*)(.*)`);

Do we really need to get the drive in this case?

I don't know about Windows but, for example, on macOS the path '/path/to/there.lua' will be separated to '/' and 'path/to/there.lua' that is not correct. In this case file breakpoints and sources in the stack doesn't work. So I change

[drive, pathPart] = path.match('^[@=]?([\\/]*)(.*)');

to

drive = ''
[drive, pathPart] = path.match(`^[@=]?[\\/]*(.*)`);

and then everything works fine because isAbsolute function also begins to work correctly. I think there is no way to detect is path the absolute or not on macOS and Linux by parsing the string.

The bugfix can make to be possible to use local-lua-debugger with Defold engine. I'm ready to prepare pull request with the instruction how to do it.

Support for torch table that may not have the length operator

While running preprocess.lua, debugger throws this error

/root/torch/install/bin/luajit: ....local-lua-debugger-vscode-0.1.8/debugger/lldebugger.lua:431: torch.CmdLine has no length operator
stack traceback:
	[C]: in function '__len'
	....local-lua-debugger-vscode-0.1.8/debugger/lldebugger.lua:431: in function 'buildVariable'
	....local-lua-debugger-vscode-0.1.8/debugger/lldebugger.lua:493: in function 'vars'
	....local-lua-debugger-vscode-0.1.8/debugger/lldebugger.lua:903: in function 'debugBreak'
	....local-lua-debugger-vscode-0.1.8/debugger/lldebugger.lua:1088: in function <....local-lua-debugger-vscode-0.1.8/debugger/lldebugger.lua:1063>
	preprocess.lua:10: in main chunk
	[C]: at 0x00405d50

preprocess.lua

require 'fairseq'
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
    require("lldebugger").start()
end
local tok = require 'fairseq.text.tokenizer'
local lmc = require 'fairseq.text.lm_corpus'
local plpath = require 'pl.path'
local pldir = require 'pl.dir'

local cmd = torch.CmdLine() -- Error generated at this line
cmd:option('-sourcelang', 'de', 'source language')
cmd:option('-targetlang', 'en', 'target language')
cmd:option('-trainpref', 'train', 'training file prefix')
cmd:option('-validpref', 'valid', 'validation file prefix')
cmd:option('-testpref', 'test', 'testing file prefix')
cmd:option('-alignfile', '', 'an alignment file (optional)')
cmd:option('-ncandidates', 1000, 'number of candidates per a source word')
cmd:option('-thresholdtgt', 0,
    'map words appearing less than threshold times to unknown')
cmd:option('-thresholdsrc', 0,
    'map words appearing less than threshold times to unknown')
cmd:option('-nwordstgt', -1,
    'number of target words to retain')
cmd:option('-nwordssrc', -1,
    'number of source words to retain')
cmd:option('-destdir', 'data-bin')

local config = cmd:parse(arg)
assert(not (config.nwordstgt >= 0 and config.thresholdtgt > 0),
    'Specify either a frequency threshold or a word count')
assert(not (config.nwordssrc >= 0 and config.thresholdsrc > 0),
    'Specify either a frequency threshold or a word count')

local langcode = config.sourcelang .. '-' .. config.targetlang
local srcext = string.format('.%s.%s', langcode, config.sourcelang)
local tgtext = string.format('.%s.%s', langcode, config.targetlang)
pldir.makepath(config.destdir)
...
...

Request UTF8 support

Function parameters cannot be displayed in locals

Sorry, I don’t speak English, this is Google Translate

Stops after setting the debugger hook even with stopOnEntry set to false

This happens when I use "program": { "lua": "lua" } or "program": { "lua": "luajit" } but does not happen when I use "program": { "command": "love" }. In both cases it seems stopOnEntry is ignored, but it always stops with lua and luajit and never stops with love. I don't know if this is intended or known or even if it happens in other systems, using linux here.

Loop in gettable

Place breakpoints at both prints

local Object = setmetatable({
  __classname = "Object",
  __tostring = function() return "Object" end
}, {
  __classname = "Object",
  __tostring = function() return "Object" end
})
Object.__index = Object

print "no errors" -- breakpoint here

local object = {
  __classname = "Object",
  __tostring = function() return "Object" end
}
Object = setmetatable(object, object)
Object.__index = Object

print "loop in gettable?" -- breakpoint here

If you just run this code, there is no errors, everything works fine. But if you debug it - first part of code also works fine, but second throws error: "[error] ....local-lua-debugger-vscode-0.2.0/debugger/lldebugger.lua:29: loop in gettable".

Both parts of this code does the same things, but second one is optimized - it store the same data in table object.

Unable to build with TypeScriptToLua because `'lldebugger'` require path can't be resolved

I'm trying to get this extension working with TypeScriptToLua under LOVE, but when I build, I get

> yarn build
yarn run v1.22.11
$ yarn build:tstl && yarn build:copy
$ tstl -p tsconfig.json
error TSTL: Could not resolve require path 'lldebugger' in file src\main.ts.

I looked in your test cases but didn't see anything special that ought to make this error go away. I tried searching Github for the string require("lldebugger").start() in TypeScript files and the only result was your test case. Looking at other issues in this repo related to TypeScriptToLua and LOVE, it looks like no one else ran into this problem.

My project is based on the LOVE TypeScript Template.

My src\main.ts is currently:

if (os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1") {
  require("lldebugger").start();
}

love.load = () => {
  const [content] = love.filesystem.read("res/index.txt");
  print(content);
};

love.draw = () => {
  love.graphics.print("Hello World!", 400, 300);
};

tsconfig.json:

{
  "compilerOptions": {
    "lib": ["esnext"],
    "rootDir": "src",
    "outDir": "game",
    "types": [
      "lua-types/jit",
      "love-typescript-definitions",
      "typescript-to-lua/language-extensions"
    ]
  },
  "tstl": {
    "luaLibImport": "require",
    "luaTarget": "JIT",
    "noImplicitSelf": true,
    "sourceMapTraceback": true
  }
}

.vscode\launch.json, largely copy-pasted from the README:

{
  // 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": "Debug Love",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "love"
      },
      "args": [
        "game"
      ],
      "scriptRoots": [
        "game"
      ]
    }
  ]
}

TSTL 'self' is not being translated to 'this' when using source mapping.

Hi there! Thanks for the amazing extension.

I'm running into a debugging issue when using source mapping for TSTL. It appears that the 'self' variable is not being translated to 'this'. So I cannot inspect 'this' or fields on 'this' because this is nil.

An inconvenient work-around. If i just store my fields in local variables, I am able to inspect them.

// Unable to inspect 'this' or 'this._thing'.
// I am able to inspect 'localThing' once I've let the line execute.
const localThing = this._thing;

Nice work! i like it. Unimportant a few things..

1- Globals's window is jam-packed with Lua's own globals so i can't find my own globals. can you seperatly capsulate them?
2- can you magic for escape from require("lldebugger").start() line?
3-if we make step on last line, we're falling inside lldebuuger.lua. here, the debugging must be end...

Configuring Löve2d project with TypescriptToLua

Great VS extension! I am trying to configure a TypescriptToLua project to use breakpoints with your debugger. I've successfully gotten breakpoints to work with the transpiled lua files (i.e. adding break points directly to the generated .lua files), but breakpoints set in the original source-mapped .ts files are entirely ignored.

Could you provide what the project structure should look like or extra information/config on running with love?

My current launch.json looks like this:

{
  "configurations": [
    {
      "type": "lua-local",
      "request": "launch",
      "name": "Debug LÖVE",
      "program": {
        "command": "love"
      },
      "args": ["${workspaceFolder}/game"],
      "sourceRoot": "${workspaceFolder}/src",
      "stopOnEntry": true
    }
  ]
}

Where tstl builds the game to the game folder, and the original TypeScript source resides in src.

I added the require("lldebugger").start() line to the main.ts file. It works with breakpoints directly in the lua files, so I am assuming the debugger is functioning fine and it is just a configuration issue.

Thanks in advance!

Fails on io.read() call

Just call io.read() method.
The entered data will not be processed, the debugger also fails.

Can't debug io function in lua?

Like below, it can't pause at io.write(content) line:
gif

Test Code:

local filePath = "./res/test.txt"
local content = "file edit selection view goto debug terminal help\n"

local oldOut = io.output()
io.output(filePath)
io.write(content)
io.output(oldOut)

local oldIn = io.input()
io.input(filePath)
local text = io.read("*a")
print(text)
io.input(oldIn)

Crash when entering in mapSources function

If i call a non existing function. The debugger will enter into this call, resulting in a crash

image

If i wrap the code with the .call(function() end) then it no longer crashes and shows a nice error
image

I'd like to show this error in the console. I found out this can be done with dbusted and a custom output handler but the crash from the debugger still happens.

Adding a nill check at the first screenshot fixes the problem but i am not sure if it's the correct fix because if i use the function shown in the second screenshot then more stuff gets printed to console. In the first screenshot nothing is printed because of the nill check.

Another question is if there is any way to call the .call(function() end) only once and affecting all the tests instead of wrapping it around code ?

TIC-80 support

Your debugger is awesome, but unfortunately, it is not compatible with tic-80 because there is no access to global os:

 TIC-80 tiny computer
 version 1.0.1770-dev Pro (60e63de)
 https://tic80.com (C) 2017-2021

 loading cart...

>./run/debugger.lua:1: attempt to index a nil value (global 'os')
>

Maybe you have some idea how to fix it?

Breakpoints doesn't work on Windows with custom lua runtime

Breakpoint doesn't work when using custom lua runtime on Windows platform.
This happen because of path to set breakpoint is wrongly formatted with forward slash instead of backslash for drive name.
Now it looks like this: C:/somefolder\anotherfolder\script.lua
And correct format should look like this: C:\somefolder\anotherfolder\script.lua

`getPrintableValue` crashes debug session on `tostring`

When debugging with metatables that override __tostring the table might end up in a state when __tostring crashes (for example nil properties not being expected to be nil after full constructor is executed). I've fixed my local version of the lldebugger.lua with a pcall like this:

    local function getPrintableValue(value)
        local valueType = type(value)
        if valueType == "string" then
            return ("\"" .. tostring(value)) .. "\""
        elseif ((valueType == "number") or (valueType == "boolean")) or (valueType == "nil") then
            return tostring(value)
        else
            local _, x = pcall(tostring, value) -- FIX HERE
            return ("[" .. x) .. "]"
        end
    end

Proper fix would be to do the fix in send.ts but since I don't have time to setup full ts build yet, I'm posting here for anyone who might have a similar issue.

Adding and removing breakpoints on runtime?

It looks like the debugger updates breakpoints only on onDebuggerStop(msg).

Is it possible to update breakpoints on setBreakPointsRequest(response, args) immediately or in some timer function?

How to specify working directory to find require'd modules

Here is a script I am trying to debug and I encounter an error when stepping over the require line:

-- lesson6 - Michael Uman - Exercise OO programming

-- Added to support local-lua debugger
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
    require("lldebugger").start()
end

local r = require("car")

local cars = {
    Car:new("Ford",         "Mustang GT",   2019),
    Car:new("Toyota",       "Camry",        2012),
    Car:new("Chevrolet",    "Camero",       2018),
    Car:new("Dodge",        "Challenger",   2015),
}

-- Sort table by year
table.sort(cars, function (a,b) return a:year() < b:year() end)

for key, value in pairs(cars) do
    value:print();
end

If I execute this code in VSCode local-lua plugin I get the following message when stepping over the require "car" line:

Exception has occurred.
lesson6.lua:5: module 'car' not found:
	no field package.preload['car']
	no file '/home/muman/.vscode-server/extensions/tomblind.local-lua-debugger-vscode-0.1.3/debugger/car.lua'
	no file '/usr/local/lib/lua/5.2/car.so'
	no file '/usr/lib/x86_64-linux-gnu/lua/5.2/car.so'
	no file '/usr/lib/lua/5.2/car.so'
	no file '/usr/local/lib/lua/5.2/loadall.so'
	no file './car.so'

This code executes fine in my WSL environment with the following output:

muman@DESKTOP-BSPUQUB:~/lua-stuff$ lua lesson6.lua 
2012 Toyota       - Camry       
2015 Dodge        - Challenger  
2018 Chevrolet    - Camero      
2019 Ford         - Mustang GT  

My launch.json script is reproduced below:

{
    // 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": "lesson6",
            "type": "lua-local",
            "request": "launch",
            "stopOnEntry": true,
            "cwd": "${workspaceFolder}",
            "program": {
                "lua": "lua",
                "file": "${workspaceFolder}/lesson6.lua"
              }
        }
    ]
}

I have tried setting the environment LUA_PATH but can't seem to get it to work.

Is there a solution to this issue?

Thank you,
Michael Uman
Sr. Software Engineer
Wunder-Bar Inc.

[LOVE2D] white screen on startup?

Hi, I'm having an issue where trying to run my Love2D project through the debugger results in freezing at a white screen on start up, with no error explaining what I did wrong. I followed the instructions pretty closely. If it's important, here's my Love project:
game.zip

I call require("lldebugger").start() in main.lua.

EDIT: Here's my launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lua-local",
            "request": "launch",
            "name": "Debug LOVE",
            "program": {
                "command": "love"
            },
            "args": [
                "${workspaceFolder}"
            ],
            "scriptRoots": [
                "${workspaceFolder}"
            ]
        }
    ]
}

Breakpoints without source maps failing...

re: https://github.com/ts-defold/defold-lldebugger/tree/extension

When debugging in Defold and setting breakpoints in *.lua, or *.script files, the debugger skips right past them.
Interestingly enough, when using sourcempas and putting breakpoints in *.ts files, the debugger respects the breakpoints.

Defold has various names for it's lua script files, *.gui_script, *.script, as well as using *.lua for module files.

This was all being tested on macOS. Let me know how else I can help, and if the project is working for you at all.

Attached is a fully configured and built project, that you should be able to execute directly from vscode (without even installing defold ;))

Basic 3D project.zip

Feature request: Detect and highlight error from debug console

I use Local Lua Debugger for running LÖVE, but I don't always require lldebugger, as that tends to slow down the game by a lot. I only do that when I actually want to debug something. However, one thing that's really nice about using the debugger is that when you get an error it will jump to that line and highlight it. I understand if it's not possible to do this without lldebugger, but the error also gets printed to the debug console. If possible, I would like Local Lua Debugger to read the contents of the debug console and interpret and highlight any error that appears in there.

If there is another solution to this, I would like to know. Perhaps with #20 the game doesn't run as slow and I can always be using lldebugger.

Allow use within busted unit tests

Not sure on the technical hurdles here, but being able to run a debugger within your unit tests would be awesome.

Busted allows calling the runner from within a regular lua file, so the launcher should be possible:

require 'busted.runner'()

describe("a test", function()
  -- tests to here
end)

(see documentation here: https://olivinelabs.com/busted/#usage)

And running it:

lua test.lua

However, when trying to combine the debugger and the above, the debugger gets halted before the first test is actually run. Could be due a limitation of lua51, not sure.

Export environment vars?

I need to export SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR=0 for love2d on linux.
How would I do this?

Bootstrap script for Defold

This may be useful for other engines as well where the require statement is using custom loaders...

The gist of it is:

  • Look for "tomblind.local-lua-debugger" in LUA_PATH
  • Use loadfile to load then execute the lldebugger.lua file from the extension
  • Add it to the path.loaded table
  • Somewhere later require and start the debugger
//@ts-expect-error package
const path = [...package.path.split(";")];
const debuggerPath = path.filter((path) => path.includes("tomblind.local-lua-debugger"))[0];
print(debuggerPath);
if (debuggerPath != null) {
  const [debuggerModule, err] = loadfile(`${debuggerPath.substr(0, debuggerPath.indexOf("?.lua"))}lldebugger.lua`);
  if (debuggerModule) {
    //@ts-expect-error package
    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    package.loaded["lldebugger"] = debuggerModule();
  } else print(err);
}

if (os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1") {
  const r = require;
  // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment
  const lldebugger = r("lldebugger");
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
  lldebugger.start();
}

Some of this code is working around a few bugs, strict mode, and aslant configs I have setup.

Breakpoints don't work with TypeScriptToLua

As the title states. Breakpoints do not work in .ts files when transpiling them with TSTL. Breakpoints in the transpiled Lua do work.
I am also using the custom environment for LÖVE as it was described in the readme.

ts.config:

{
  "compilerOptions": {
    "target": "esnext",
    "lib": ["esnext"],
    "moduleResolution": "node",
    "types": ["lua-types/jit", "love-typescript-definitions"],
    "strict": true,
    "outDir": "build",
    "rootDir": "src",
    "baseUrl": "src",
    "sourceRoot": "src",
    "sourceMap": true,
  },
  "tstl": {
    "luaTarget": "JIT",
    "noHeader": true,
    "sourceMapTraceback": true,
  }
}

launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Love",
      "type": "lua-local",
      "request": "launch",
      "program": {
        "command": "lovec"
      },
      "args": ["${workspaceFolder}/build"],
      "sourceRoot": "${workspaceFolder}/src",
      "verbose": true,
    }
  ]
}

output with verbose set to true

[request] launchRequest

[request] setBreakPointsRequest

[request] configurationDoneRequest

[info] launching `"lovec" C:\Users\Laptop-Justin\Documents\TSTL/build` from "c:\Users\Laptop-Justin\Documents\TSTL"

[info] process launched

[request] threadsRequest

[message] {"threadId":1,"breakType":"step","tag":"$luaDebug","type":"debugBreak","message":"step"}

[command] break clear

[message] {"type":"breakpoints","breakpoints":[],"tag":"$luaDebug"}

[command] break set c:\Users\Laptop-Justin\Documents\TSTL\src\init.ts:9

[message] {"type":"breakpoints","breakpoints":[{"file":"C:\\Users\\Laptop-Justin\\Documents\\TSTL\\src\\init.ts","enabled":true,"line":9}],"tag":"$luaDebug"}

[command] autocont
loaded

[info] debugging ended: 0

Using lldebugger.stop/start to limit the debugged code triggers a break immediately

I just wanted to give this debugger a try but due to the size/complexity of my game (city builder using LÖVE) there's no way I'll be able to have the debugger active for all code (fps drops from 60fps to multiple seconds per frame).
Tried to use lldebugger.start()/stop() to narrow down the code to some submodule but calling lldebugger.start() during runtime immediately triggers a break at the current line of code.

In lldebugger.lua, line 1616 you test for "not breakImmediately" and if that evaluates to true, test the LOCAL_LUA_DEBUGGER_VSCODE env variable which is true when debugging so breakImmediately is always true when using lldebugger.start() during runtime. Is this intentionally for some reason?

I modified the file locally to only check the env variable when breakImmediately is nil which seems to work as expected and makes the debugger quite usable in my situation.

Relative file paths

Hi there!

I'm having issues regarding relative file paths for assets (images) and require paths (other lua files).

  • It appears that when running my program through the debugger, all paths are relative to the lldebugger.lua instead of the lua53.exe.

I have my launch.json configured to use the lua53.exe interpreter and main.lua as my entry file.

Folder structure:

  • lua53.exe
  • main.lua
  • imageLoader.lua
  • assets
    • image.png

main.lua is not able to find imageLoader.lua via require()

I bundled the two files together to avoid require(), but then my program is unable to find the image.

Any help or work arounds would be greatly appreciated!

Thank you.

Luajit does not work in OSX

Launch json "program": { "lua": "/usr/local/bin/lua5.1" works.

But when I set "program": { "lua": "/usr/local/bin/luajit-2.1.0-beta3" then I get error:

/usr/local/bin/luajit-2.1.0-beta3: ....local-lua-debugger-vscode-0.1.2/debugger/lldebugger.lua:1065: assertion failed!
stack traceback:
	[C]: in function 'assert'
	....local-lua-debugger-vscode-0.1.2/debugger/lldebugger.lua:1065: in function <....local-lua-debugger-vscode-0.1.2/debugger/lldebugger.lua:1048>
	[builtin:remove]: in function 'remove'
	....local-lua-debugger-vscode-0.1.2/debugger/lldebugger.lua:1219: in function 'popHook'
	....local-lua-debugger-vscode-0.1.2/debugger/lldebugger.lua:1247: in function 'runFile'
	(command line):1: in main chunk
	[C]: at 0x0100001680

Breakpoints are sometimes not properly recognized

I can't reproduce this bug in another project.
I'm using Love2D and wrap the update and draw calls arround a lldebugger.call, so that any breakpoints and whatever should get recognized. However recently in a project I noticed a strange and annoying behaviour.
Let's say I have main.lua, A.lua, B.lua, C.lua, and D.lua. The module D is used from A to C and in main.lua. Now I can easly create breakpoints in main.lua, A.lua and D.lua, but when trying to put breakpoints in B.lua or C.lua, the debugger steps right over them.
The only way that the debugger recognizes the breakpoints, is to step into B.lua or C.lua and put breakpoints when I am inside that file. Untill the end of this debugging session, any new breakpoints are recognized properly. If I restart the debugger, the same behaviour repeats.
I'm sorry, that I can't put an example to reproduce the behaviour, I had trouble finding a way. If I come up with an example, I will post it here.

Edit:
Interesting side effect: When copying the project files into another directory, there the issue disappears. Are there maybe any caches that are responsible?

Edit 2:
I could solve the issue by deleting the contents of %appdata%\Code\User\workspaceStorage

Add `scriptRoots` option for platforms with custom loaders

Love (and potentially other platforms) uses custom loaders to load scripts from alternate locations outside of package.path. Currently, the debugger cannot resolve these scripts for breakpoints, etc...

A new configuration option should be added so these paths can be manually checked when resolving the script's location in vscode.

See #8

stdout is printed to console only when app exit

When executing a simple app like:

while true do os.execute("sleep 1") print("foo") end
Nothing is outputed to debug console.

When I kill the application, all printed string show in the console logs.

I'm using version 0.1.10 of the extension.

Error levels are not handled properly

When calling error("message") the editor breaks on the correct layer.
Since error("message") should be the same as error("message", 1), I would expect the same behaviour from the debugger, however it is handled as if error("message", 2) has been called. And when i call error("message", 2) I get pointed to layer 3. So when I wanna address the correct call layer in lua, I get pointed to layer + 1 in local-lua-debugger.
I suppose it has something to do with when you have overridden the error function.

Strings containing escape characters

local sep = "\027" -- escape character
local s = "hello " .. sep .. " world"

print(s)

Place break point on print statement - local variable pane won't show variable 's'.

Continued debugging after stopping is difficult if not impossible.

Can't see debugger when path is not the workspace folder.

I have my project set up in such way that my workspace has a folder game, and in that folder is my main.lua.

My launch.json looks like this:

{
    "configurations": [
      {
        "type": "lua-local",
        "request": "launch",
        "name": "Debug LÖVE",
        "program": {
          "command": "love"
        },
        "args": [
          "${workspaceFolder}/game"
        ]
      }
    ]
  }

When debugging, it does pause at the breakpoints, but it doesn't open the files and the line does not get highlighted.

LuaJit won't work in Linux

Hi, It seems LauJit debugger is not working for me. It is not even getting started.
debug console(VS code) shows this on pressing F5(starting debugger) :

/root/torch/install/bin/luajit: stack overflow
stack traceback:
	[C]: in function 'running'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1200: in function 'assert'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1200: in function 'assert'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1200: in function 'assert'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1200: in function 'assert'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1200: in function 'assert'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1200: in function 'assert'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1200: in function 'assert'
	....local-lua-debugger-vscode-0.1.7/debugger/lldebugger.lua:1067: in function '__index'
	preprocess.lua:4: in main chunk

whereas on bash this works perfectly

luajit preprocess.lua -sourcelang en -targetlang hi \
  -trainpref $TEXT/train -validpref $TEXT/valid -testpref $TEXT/test \
  -thresholdsrc 3 -thresholdtgt 3 -destdir data-bin/iitb

Steps to reproduce :

root@fe0c432a3c8d:~/NPMT# whereis luajit
luajit: /root/torch/install/bin/luajit

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug Custom Lua Environment",
            "type": "lua-local",
            "request": "launch",
            "program": {
                "command": "/root/torch/install/bin/luajit"
            },
            "env": {
                "TEXT":"data/IITB_small",
                "LD_LIBRARY_PATH":"/usr/local/lib:$LD_LIBRARY_PATH"
            },
            "args": ["preprocess.lua","-sourcelang","en","-targetlang","hi","-trainpref","$TEXT/train","-validpref","$TEXT/valid","-testpref","$TEXT/test","-thresholdsrc","3","-thresholdtgt","3","-destdir","data-bin/iitb"]
        }
    ]
}

preprocess.lua


require 'fairseq'
require("lldebugger").start()

local tok = require 'fairseq.text.tokenizer'
local lmc = require 'fairseq.text.lm_corpus'
local plpath = require 'pl.path'
local pldir = require 'pl.dir'
...
...
...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.