Jump to content




[1.74][SMP+SSP]This code crashes the computer with no errors even though it should work



  • You cannot reply to this topic
9 replies to this topic

#1 Yarillo

  • Members
  • 81 posts
  • LocationFrance

Posted 03 August 2015 - 03:41 PM

VERSION:
1.74
REPRODUCTION STEPS:
old = {}
old.turtle = turtle

function inspect()
  return old.turtle.inspect()
end
turtle.inspect = inspect

print(tostring(turtle.inspect()))
EXPECTED RESULT:
prints "true" or "false" depending on what's in front of the turtle

ACTUAL RESULT:

screen goes black, nothing happens, can't reboot, can't shut down, can't stop the script. Eventually, it reboots by itself.

PS: If you break the turtle while the screen is black, if you place it back (even in another spot) the script seems to still run. It still eventually stops. Also, once you did that, if you place another turtle (I placed it in the same spot as before, maybe it has something to do with it) the same thing will happen. The turtle will take a few minutes to turn on.

#2 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 03 August 2015 - 04:22 PM

This isn't really a bug with CC but rather a bug with your code. This line here:

old.turtle = turtle

Doesn't copy the table 'turtle'. It copies a pointer to the table 'turtle', thus 'old.turtle' would be equal to 'turtle'. Now, the problem here is that you create a new function 'inspect' which then calls the 'old.turtle.inspect()' function. And remember that doing 'old.turtle.inspect()' is calling the same function which appears in 'turtle.inspect()'. So when you actually assign a new function to 'turtle' table you also "affect" the 'old.turtle' table (which is the exact same table), and thus calling turtle.inspect ends up calling itself, over and over again until the computer crashes.

Now, you could say that this isn't really a bug. But it surely is something that could be dealt nicer on the CC-side.

#3 Yarillo

  • Members
  • 81 posts
  • LocationFrance

Posted 03 August 2015 - 04:28 PM

I didn't think it was a pointer. I thought it was the function itself that I duplicated. So I guess that makes sense.
Thanks !

#4 flaghacker

  • Members
  • 655 posts

Posted 03 August 2015 - 04:29 PM

View PostMKlegoman357, on 03 August 2015 - 04:22 PM, said:

But it surely is something that could be dealt nicer on the CC-side.

Well no, not really, that's simply how lua works.

#5 SquidDev

    Frickin' laser beams | Resident Necromancer

  • Members
  • 1,427 posts
  • LocationDoes anyone put something serious here?

Posted 03 August 2015 - 04:30 PM

View PostYarillo, on 03 August 2015 - 03:41 PM, said:

screen goes black, nothing happens, can't reboot, can't shut down, can't stop the script. Eventually, it reboots by itself.

View PostMKlegoman357, on 03 August 2015 - 04:22 PM, said:

Now, you could say that this isn't really a bug. But it surely is something that could be dealt nicer on the CC-side.

I'm slightly surprised this happens. There is a debug hook that executes every 1000 (I think) instructions that checks to ensure the computer shouldn't timeout, but that doesn't seem to be triggered correctly. Most 'too long without yielding' errors come from CC's methods (as opposed to Lua built-ins) which check for the timeout, but as you aren't calling any you will not get it.

I'm working off memory but I think:
while true do end
Will just get a black screen, but:
while true do term.write("x") end
will not.

Infinite loops without any CC methods being called are quite rare, so this generally isn't a problem.

Edited by SquidDev, 03 August 2015 - 04:32 PM.


#6 Yarillo

  • Members
  • 81 posts
  • LocationFrance

Posted 03 August 2015 - 04:35 PM

There still is a problem though, no error is being displayed.

#7 flaghacker

  • Members
  • 655 posts

Posted 03 August 2015 - 05:10 PM

Your code is equivalent to something like this: (for the reasons explained in other posts)
local function a()
  return a()
end

a()
It's infinitely recursive, it will never return. Normally something like that results in a stackoverflow error (indexoutofbounds in computercraft). Because you managed to accidently sneak in a proper tail call this doest happen, and you simply get an infinite loop. Your code is actually equivalent to
while true do

end

This should result in an error too, a "too long without yielding". That doest happen because computercraft can only terminate your code if you use some computercraft funstions (read, monitor.write, periphera.wrap, print, anything really...). This results in strange behaviour, including other computers in your world not reacting anymore.

The fix would be to "deep copy" the turtle table, like this:

local oldT = {}

for name, function in pairs(turtle) do
  oldT[name] = function
end

turtle.inspect = function(...)
  return oldT.inspect(unpack(arg))
end

Because of bad luck you got a couple of dark computercraft concepts working against you while debugging your code, but really the only problem is you copying the table wrong. I hope I managed to explain what's going on here, but feel free to ask further questions if I wasn't understandable at all :D

Edited by flaghacker, 03 August 2015 - 05:12 PM.


#8 SquidDev

    Frickin' laser beams | Resident Necromancer

  • Members
  • 1,427 posts
  • LocationDoes anyone put something serious here?

Posted 03 August 2015 - 05:33 PM

View Postflaghacker, on 03 August 2015 - 05:10 PM, said:

It's infinitely recursive, it will never return. Normally something like that results in a stackoverflow error (indexoutofbounds in computercraft). Because you managed to accidently sneak in a proper tail call this doest happen, and you simply get an infinite loop.

+1. Didn't catch that. In fact, +1 for an all-round good explanation of what occurred.

#9 flaghacker

  • Members
  • 655 posts

Posted 03 August 2015 - 06:06 PM

View PostSquidDev, on 03 August 2015 - 05:33 PM, said:

View Postflaghacker, on 03 August 2015 - 05:10 PM, said:

It's infinitely recursive, it will never return. Normally something like that results in a stackoverflow error (indexoutofbounds in computercraft). Because you managed to accidently sneak in a proper tail call this doest happen, and you simply get an infinite loop.

+1. Didn't catch that. In fact, +1 for an all-round good explanation of what occurred.

Hey thanks, really appreciated! I was actually about to start explaining why it doesn't cause a "too long without yielding" error when I thought "wait a sec, why no stackoverflow?" ;)

#10 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 03 August 2015 - 06:56 PM

Moved to Ask a Pro.





3 user(s) are reading this topic

0 members, 3 guests, 0 anonymous users