This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
H4X0RZ's profile picture

Need Help With My Debug Program

Started by H4X0RZ, 29 August 2013 - 07:27 AM
H4X0RZ #1
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:
SpoilerPastebin:
Spoilerhttp://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
Engineer #2
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
H4X0RZ #3
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?
Engineer #4
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
Grim Reaper #5
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
H4X0RZ #6
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?
LBPHacker #7
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.