pkulchenko / ZeroBraneStudio

Lightweight Lua-based IDE for Lua with code completion, syntax highlighting, live coding, remote debugger, and code analyzer; supports Lua 5.1, 5.2, 5.3, 5.4, LuaJIT and other Lua interpreters on Windows, macOS, and Linux
http://studio.zerobrane.com/
Other
2.62k stars 518 forks source link

ZBS and DCS World #992

Closed FullGas1 closed 1 year ago

FullGas1 commented 5 years ago

Hello Paul,

do you know if it's possible to connect ZBS to DCS world LUA environment for scripting and debuging in?

If it's possible, can you tell us how we can do it ?

I use actuallly Witchcraft witch permit to send from the Witchcraft console (snippets) a code to a node.js server on a port. And this node.js server relay it to DCA World by another port. But, this solution doesn't permit to debbug line by line, and the ergonomics of this solution is not comparable to ZBS.

I have tried to connect ZBS to Witchcraft node.js (it seems ok), but when I send a correct simple LUA code, I have an error message.

Thank's

pkulchenko commented 5 years ago

I can't say for sure, but you'd need to be able to load luasocket and mobdebug.lua into that environment if you want to be able to support remote debugging there. It's possible to get it to work in many cases, but there are some for sure that either disable some of debug.* methods or don't allow loading of binary modules. The documentation for remote debugging is available here.

kbastronomics commented 1 year ago

I've tried but I do get an error. I'd love to get this to work as debugging using good ole print statements kind of sucks I have this is BIOS.lua

-- Only needed to debug DCS BIOS
BIOS.log("Loading ZeroBrane Debug...")
package.path = package.path..";D:\\OneDrive\\OpenHornet\\ZeroBraneStudio\\lualibs\\mobdebug\\?.lua"
package.cpath = package.cpath..";D:\\OneDrive\\OpenHornet\\ZeroBraneStudio\\bin\\clibs\\?.dll"
require('mobdebug').start() 

and get this error

Loading ZeroBrane Debug...
2023-01-05 12:58:24.552 ERROR   Lua::Config (Main): Call error LuaExportStart:[string "D:\OneDrive\OpenHornet\ZeroBraneStudio\lualibs\mobdebug\mobdebug.lua"]:419: attempt to call field 'getupvalue' (a nil value)
stack traceback:
    [C]: in function 'getupvalue'
    [string "D:\OneDrive\OpenHornet\ZeroBraneStudio\lualibs\mobdebug\mobdebug.lua"]:419: in function 'capture_vars'
    [string "D:\OneDrive\OpenHornet\ZeroBraneStudio\lualibs\mobdebug\mobdebug.lua"]:689: in function <[string "D:\OneDrive\OpenHornet\ZeroBraneStudio\lualibs\mobdebug\mobdebug.lua"]:558>

Did you get this to work? Should I open a new issue?

pkulchenko commented 1 year ago

attempt to call field 'getupvalue' (a nil value)

It looks like you may not have debug.getupvalue in your environment. It's possible you don't have debug.getlocal either and both are needed to properly execute console commands and get stack/watch view.

You can try the following patch to see if that helps:

diff --git a/lualibs/mobdebug/mobdebug.lua b/lualibs/mobdebug/mobdebug.lua
index 36fa14c3..69c0f238 100644
--- a/lualibs/mobdebug/mobdebug.lua
+++ b/lualibs/mobdebug/mobdebug.lua
@@ -369,6 +369,7 @@ end

 local function restore_vars(vars)
   if type(vars) ~= 'table' then return end
+  if not debug.getlocal or not debug.getupvalue then return end

   -- locals need to be processed in the reverse order, starting from
   -- the inner block out, to make sure that the localized variables
@@ -413,7 +414,7 @@ end
 local function capture_vars(level, thread)
   level = (level or 0)+2 -- add two levels for this and debug calls
   local func = (thread and debug.getinfo(thread, level, "f") or debug.getinfo(level, "f") or {}).func
-  if not func then return {} end
+  if not func or not debug.getlocal or not debug.getupvalue then return {} end

   local vars = {['...'] = {}}
   local i = 1
kbastronomics commented 1 year ago

That does get me further along (ie DCS starts up and I can step thru code), just if i put a watch on a variable it returns nil

is there anyway I can force that to work? I can see the lua executable it's v 5.1.15 if there's anything I can check there

pkulchenko commented 1 year ago

I think that's the best that can be done without those functions (getlocal and getupvalue) present, as nothing that evaluates the code is going to work (although running, stepping and breakpoints should still work).

Can you print the list of functions available in debug table? Maybe you can ask in DCS forums if there is an option to enable those functions. It doesn't make much sense to disable them while keeping the rest of the debug library available.

kbastronomics commented 1 year ago

you have to excuse me I"m learning lua as I go here. how would I do that. print(debug) just return a big hex value (a pointer to the table I guess)

pkulchenko commented 1 year ago

Yes, you'd need to so something like for k,v in pairs(debug) do print(k, v) end in the script you execute from the IDE.

kbastronomics commented 1 year ago

I had to write this to a log file using the supplied log util in DCS I could not get the value to print to the log though

BIOS.log("Printing Debug Data...")
for k,v in pairs(debug) do 
  -- BIOS.log(string.format("BIOS.lua: KEY %s VALUE %d", k, v))
end 

Produced this

Loading ZeroBrane Debug...
Printing Debug Data...
debug
sethook
getmetatable
gethook
setmetatable
setlocal
traceback
setfenv
getinfo
getlocal
getfenv
pkulchenko commented 1 year ago

It looks like you may only be missing getupvalue, so getlocal should still work. Try this modified patch:

diff --git a/lualibs/mobdebug/mobdebug.lua b/lualibs/mobdebug/mobdebug.lua
index 36fa14c3..69c0f238 100644
--- a/lualibs/mobdebug/mobdebug.lua
+++ b/lualibs/mobdebug/mobdebug.lua
@@ -369,6 +369,7 @@ end

 local function restore_vars(vars)
   if type(vars) ~= 'table' then return end
+  if not debug.getupvalue then return end

   -- locals need to be processed in the reverse order, starting from
   -- the inner block out, to make sure that the localized variables
@@ -413,7 +414,7 @@ end
 local function capture_vars(level, thread)
   level = (level or 0)+2 -- add two levels for this and debug calls
   local func = (thread and debug.getinfo(thread, level, "f") or debug.getinfo(level, "f") or {}).func
-  if not func then return {} end
+  if not func or not debug.getupvalue then return {} end

   local vars = {['...'] = {}}
   local i = 1
pkulchenko commented 1 year ago

Actually, scratch that, as it's not going to help. I'll provide a new patch shortly.

pkulchenko commented 1 year ago

Try this patch:

diff --git a/lualibs/mobdebug/mobdebug.lua b/lualibs/mobdebug/mobdebug.lua
index 36fa14c3..7f27bdd6 100644
--- a/lualibs/mobdebug/mobdebug.lua
+++ b/lualibs/mobdebug/mobdebug.lua
@@ -317,7 +317,7 @@ local function stack(start)
     -- get upvalues
     i = 1
     local ups = {}
-    while func do -- check for func as it may be nil for tail calls
+    while func and debug.getupvalue do -- check for func as it may be nil for tail calls
       local name, value = debug.getupvalue(func, i)
       if not name then break end
       ups[name] = {value, select(2,pcall(tostring,value))}
@@ -397,7 +397,7 @@ local function restore_vars(vars)

   i = 1
   local func = debug.getinfo(3, "f").func
-  while true do
+  while debug.getupvalue do
     local name = debug.getupvalue(func, i)
     if not name then break end
     if not written_vars[name] then
@@ -417,7 +417,7 @@ local function capture_vars(level, thread)

   local vars = {['...'] = {}}
   local i = 1
-  while true do
+  while debug.getupvalue do
     local name, value = debug.getupvalue(func, i)
     if not name then break end
     if string.sub(name, 1, 1) ~= '(' then vars[name] = value end
kbastronomics commented 1 year ago

No Dice, Watched variables still returning nil

pkulchenko commented 1 year ago

Are you sure you're using the latest patch? You should be able to get the watches to work with it (assuming you do have debug.getlocal available).

Can you also check if the Stack window (Ctrl-Shift-S) is showing any values for local variables?

Can you also try printing local values from the Console (when the app is running and is stopped in the debugger)?

What do you get if you stop on line 4 in this script and try to print the value of baz in the Local console or check the stack?

local foo = 1
local function bar()
  local baz = 2
  print(foo, baz)
end
bar()
kbastronomics commented 1 year ago

image

so in the stack window i do see the variables in the console they return nill and watch window is nill

do you want me to add that script to lua script I'm running? I take it so but making sure

kbastronomics commented 1 year ago

I redid the patch and its working

pkulchenko commented 1 year ago

ok, just to confirm, you got the watches and local console values working with the latest patch?

kbastronomics commented 1 year ago

That is correct

pkulchenko commented 1 year ago

@kbastronomics, should be fixed now.