Jump to content




This autorun bootloader is failing spectacularly


4 replies to this topic

#1 cyanisaac

  • Members
  • 369 posts
  • LocationSan Diego, CA

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!

#2 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

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.

#3 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

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.

#4 Dragon53535

  • Members
  • 973 posts
  • LocationIn the Matrix

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 by Dragon53535, 18 January 2016 - 11:26 PM.


#5 cyanisaac

  • Members
  • 369 posts
  • LocationSan Diego, CA

Posted 18 January 2016 - 11:54 PM

View PostDragon53535, on 18 January 2016 - 11:23 PM, said:

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.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users