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

This autorun bootloader is failing spectacularly

Started by cyanisaac, 18 January 2016 - 09:40 PM
cyanisaac #1
Posted 18 January 2016 - 10:40 PM
This program, which is in a Lua resource pack (Under /assets/computercraft/lua/rom/autorun/, called "boot"). It is meant to act as a bootloader. It is failing spectacularly badly.

http://pastebin.com/T9MSJF84

This program seems to repeat itself over and over and over and over again, it also seems to cause java exceptions to be thrown, it's driving me insane. Any idea why this is happening?

Thank you all very much!
Bomb Bloke #2
Posted 18 January 2016 - 10:50 PM
In what way is it "failing"? You haven't even posted the error message here!

Java errors tend not to include script line numbers, but there's nothing stopping you from inserting print calls into your script until you're able to narrow down the specific lines which are at fault.
Lyqyd #3
Posted 18 January 2016 - 10:59 PM
You need to carefully review the normal startup sequence and ponder why starting the shell program with an empty environment table may not do what you want.
Dragon53535 #4
Posted 18 January 2016 - 11:23 PM
I believe Lyqyd is right here, and I'll probably give a much better explanation about it.

When you start shell on it's own through your use of:


os.run({}, "/rom/programs/shell")

You're recreating a new shell, with an empty environment table. Shell, when run does quite a bit of setup and then performs this little if statement:


local tArgs = { ... }
if #tArgs > 0 then
	-- "shell x y z"
	-- Run the program specified on the commandline
	shell.run( ... )
else
	-- "shell"
	-- Print the header
	term.setBackgroundColor( bgColour )
	term.setTextColour( promptColour )
	print( os.version() )
	term.setTextColour( textColour )
	-- Run the startup program
	if parentShell == nil then
		shell.run( "/rom/startup" )
	end
	-- Read commands and execute them
	local tCommandHistory = {}
	while not bExit do
		term.redirect( parentTerm )
		term.setBackgroundColor( bgColour )
		term.setTextColour( promptColour )
		write( shell.dir() .. "> " )
		term.setTextColour( textColour )

		local sLine
		if settings.get( "shell.autocomplete" ) then
			sLine = read( nil, tCommandHistory, shell.complete )
		else
			sLine = read( nil, tCommandHistory )
		end
		table.insert( tCommandHistory, sLine )
		shell.run( sLine )
	end
end

Which if you have an environment passed to it, with shell already existing, you don't really have a problem. With no parentShell existing (What it sees as an already existing shell) it defaults to rom/startup, at this bit:


-- Run the startup program
	if parentShell == nil then
		shell.run( "/rom/startup" )
	end

Okay, not exactly bad, it's going to run the built in startup that every computer has, but wait, inside of the startup file are these lines at the end:


if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then
local tFiles = fs.list( "/rom/autorun" )
table.sort( tFiles )
for n, sFile in ipairs( tFiles ) do
  if string.sub( sFile, 1, 1 ) ~= "." then
   local sPath = "/rom/autorun/"..sFile
   if not fs.isDir( sPath ) then
	shell.run( sPath )
   end
  end
end
end

Which searches through your autorun folder, and automatically runs your bootloader which eventually does:


os.run({}, "/rom/programs/shell")

And the entire process repeats itself.

The error you were getting was a stack overflow, in which you had too many functions running at one time without any of them returning.

As for how to stop this from happening, well I don't know what you're attempting to achieve so any advice I may try to give about how to correctly run your program may be entirely off.
Edited on 18 January 2016 - 10:26 PM
cyanisaac #5
Posted 18 January 2016 - 11:54 PM
I believe Lyqyd is right here, and I'll probably give a much better explanation about it.

When you start shell on it's own through your use of:


os.run({}, "/rom/programs/shell")

You're recreating a new shell, with an empty environment table. Shell, when run does quite a bit of setup and then performs this little if statement:


local tArgs = { ... }
if #tArgs > 0 then
	-- "shell x y z"
	-- Run the program specified on the commandline
	shell.run( ... )
else
	-- "shell"
	-- Print the header
	term.setBackgroundColor( bgColour )
	term.setTextColour( promptColour )
	print( os.version() )
	term.setTextColour( textColour )
	-- Run the startup program
	if parentShell == nil then
		shell.run( "/rom/startup" )
	end
	-- Read commands and execute them
	local tCommandHistory = {}
	while not bExit do
		term.redirect( parentTerm )
		term.setBackgroundColor( bgColour )
		term.setTextColour( promptColour )
		write( shell.dir() .. "> " )
		term.setTextColour( textColour )

		local sLine
		if settings.get( "shell.autocomplete" ) then
			sLine = read( nil, tCommandHistory, shell.complete )
		else
			sLine = read( nil, tCommandHistory )
		end
		table.insert( tCommandHistory, sLine )
		shell.run( sLine )
	end
end

Which if you have an environment passed to it, with shell already existing, you don't really have a problem. With no parentShell existing (What it sees as an already existing shell) it defaults to rom/startup, at this bit:


-- Run the startup program
	if parentShell == nil then
		shell.run( "/rom/startup" )
	end

Okay, not exactly bad, it's going to run the built in startup that every computer has, but wait, inside of the startup file are these lines at the end:


if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then
local tFiles = fs.list( "/rom/autorun" )
table.sort( tFiles )
for n, sFile in ipairs( tFiles ) do
  if string.sub( sFile, 1, 1 ) ~= "." then
   local sPath = "/rom/autorun/"..sFile
   if not fs.isDir( sPath ) then
	shell.run( sPath )
   end
  end
end
end

Which searches through your autorun folder, and automatically runs your bootloader which eventually does:


os.run({}, "/rom/programs/shell")

And the entire process repeats itself.

The error you were getting was a stack overflow, in which you had too many functions running at one time without any of them returning.

As for how to stop this from happening, well I don't know what you're attempting to achieve so any advice I may try to give about how to correctly run your program may be entirely off.

Thank you, I know how to fix this now.