1583 posts
Location
Germany
Posted 29 August 2013 - 09:27 AM
Hello com,
I'm working on this little program now for an day and It won'T work right.
It's is a debugger which displays all variables of an program and allows you to change them.
here is the code:
Spoiler
Pastebin:
Spoiler
http://pastebin.com/RnmUL8yE Plain Text:
Spoiler
local args = {...}
local fileName = args[1]
local debugKey = keys.f2
local running = true
local programIsRunning = true
local env = {}
local fileContent = {}
local handle = fs.open(fileName,"r")
local sLine = handle.readLine()
while sLine do
fileContent[#fileContent+1] = sLine:gsub("local","") --make all variables global
sLine = handle.readLine()
end
handle.close()
local handle = fs.open(".debug_file","w")
for k,v in pairs(fileContent) do
handle.writeLine(v.."\n")
end
handle.close()
local function run()
dofile(".debug_file")
end
setfenv(run, env)
local function debug()
while true do
sleep(0)
term.setBackgroundColor(colors.lightGray)
term.clear()
term.setCursorPos(1,1)
for key,var in pairs(env) do
print(key, " = ", var)
end
end
end
local runCo = coroutine.create(run)
local debugCo = coroutine.create(debug)
coroutine.resume(runCo)
while running do
local evt = {os.pullEvent()}
if evt[1] == "key"and evt[2] == debugKey then
programIsRunning = not programIsRunning
end
if programIsRunning then
if coroutine.status(runCo) ~= "dead" then
coroutine.resume(runCo, unpack(evt))
end
else
if coroutine.status(debugCo) ~= "dead" then
coroutine.resume(debugCo, unpack(evt))
end
end
end
this is my test program:
local count = 1
while true do
count = count+1
term.setBackgroundColor(colors.green)
term.clear()
term.setCursorPos(1,1)
term.write("count = "..count)
sleep(1)
end
I want that it run the program and when I press F2 it switches between the modes. but It neither run the program nor displays the variables and if I hit the F2 key in the debug mode, it don't switches to the program. What I am doing wrong?
PS:
For now the "edit the variables" is not added
I hope someone can help me,
Freack100
1522 posts
Location
The Netherlands
Posted 29 August 2013 - 11:10 AM
You are not getting the environment of the program in question. To get the environment of a program I suggest doing something similair like this:
local file = fs.open( filename, 'r' )
local content = file.readAll():gsub( 'local', '' )
file.close()
local func, err = loadstring( content, filename )
if not func then
error( 'Compile error: ' .. err, 0 )
end
local ok, err_ = pcall( func ) -- you have to execute the function before you can get the environment
if not ok then
error( 'Runtime error: ' .. err_, 0 )
end
local fileEnv = getfenv( func )
-- this table contains everything from the _G table and the global vars of the file
1583 posts
Location
Germany
Posted 29 August 2013 - 11:24 AM
You are not getting the environment of the program in question. To get the environment of a program I suggest doing something similair like this:
local file = fs.open( filename, 'r' )
local content = file.readAll():gsub( 'local', '' )
file.close()
local func, err = loadstring( content, filename )
if not func then
error( 'Compile error: ' .. err, 0 )
end
local ok, err_ = pcall( func ) -- you have to execute the function before you can get the environment
if not ok then
error( 'Runtime error: ' .. err_, 0 )
end
local fileEnv = getfenv( func )
-- this table contains everything from the _G table and the global vars of the file
okay, now I get everything in the _G table but I only want the variables of my debugged program…
And why isn't the test program running while debugging?
1522 posts
Location
The Netherlands
Posted 29 August 2013 - 11:43 AM
You can filter out the _G table yourself, if you can't take that on, on yourself then I suggest that you start smaller
504 posts
Location
Seattle, WA
Posted 29 August 2013 - 12:18 PM
Engineer is probably right about your needing to start smaller if you can't filter out the table on your own, but since I don't really see the harm in explaining this one thing, I'll try to show you how I might go about it.
You could simply iterate through the table using pairs and remove anything that has a type of "function".
local functionIndexes = {}
for index, value in pairs (env) do
if type (value) == "function" then
functionIndexes[index] = true
end
end
for functionIndex, _ in pairs (functionIndexes) do
env[functionIndex] = nil
end
1583 posts
Location
Germany
Posted 29 August 2013 - 12:45 PM
I know how to filter it out :D/>
now I only have ne question left:
why isn't the test program running while debugging?
758 posts
Location
Budapest, Hungary
Posted 29 August 2013 - 01:24 PM
My best guess at a first glance is that the program errors out at the first API call, since it's environment contains nothing. Metatables for the win:
local env = setmetatable({}, {__index = _G})
BTW, I hope you know that the debugger will only notice the debug key if the program yields or errors out.