Game freezes randomly

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Game freezes randomly

Post by pgimeno »

milon wrote: Fri Jun 03, 2022 5:37 pm Any idea what the actual bug is, or how the rest of us can avoid it? I couldn't follow most of the jit-related stuff and just want to know what to avoid in my code, or when I need to potentially turn jit off.
Unfortunately, no. The code is complex, and the reproducibility rate is too low. Both factors make it unsuitable for a bug report.

My suspicion is that the outer pairs() loop somehow hits an endless loop, like it isn't advancing to the next element when it should, or it's going back to a previous element at some point, because the trace does show a call to next() but it just never ends. However I don't have a way to find out if that's actually the case. I also have no idea of what can be triggering it.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Game freezes randomly

Post by ReFreezed »

Printing out the indices for the pairs loop in findName() reveals that the loop is stuck for no reason:

Code: Select all

local reported = false

function Game:findName(askedname)
	local result = {}
	local looped = {}

	for i, v in pairs(self.gameloop) do
		looped[#looped+1] = i

		for j, name in ipairs(v.classes) do
			if name == askedname then
				if result[1000] and not reported then
					reported = true
					local objCount = 0
					for _ in pairs(self.gameloop) do -- This loop does not get stuck, even though it's exactly the same as the outermost loop!
						objCount = objCount + 1
					end
					print("objCount="..objCount, "#classes="..#v.classes, "i="..i, "j="..j, "name="..name)
					print("looped", table.concat(looped, ","))
				end
				insert(result, v)
			end
		end
	end

	return result
end

-- Example output:
--
-- objCount=45 #classes=4 i=1046 j=4 name=Player
-- looped 1379,1026,1034,1036,1042,1046,1048,1379,1026,1034,1036,1042,1046,1048,1379,1026...
--
Notice how 'looped' contains a repeating pattern (1379...1048,1379). All the numbers are different every run, including how many values are in the repeating pattern. LuaJIT is definitively doing something weird in that particular place.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Game freezes randomly

Post by pgimeno »

That's a clever idea for debugging this issue, good find! So my suspicion of it jumping back to a previous element was correct.

If we could isolate the problem in an as-simple-as-possible program using LuaJIT without Löve, maybe it could be reported to Pall. Unfortunately it's not suitable for a bug report in this format.

Side note, the case where you (ReFreezed) saw a memory overflow was probably because the inner loop found a match, and it was adding the element over and over. I didn't get that problem in the few times I managed to reproduce it. In fact, you're reporting results only when there's a match.
User avatar
slime
Solid Snayke
Posts: 3132
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Game freezes randomly

Post by slime »

There have been a couple fixes to the JIT-compileable path for pairs() in LuaJIT in the past few months - I'm curious if the issue is still reproducible if someone compiles and uses the latest LuaJIT 2.1 code from git.
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Game freezes randomly

Post by pgimeno »

I'm going to try, but the reproducibility rate in my case is so low that I can't be sure whether the issue is gone or I just didn't hit the bug.

I'll add a new post if I hit the bug even in latest 2.1, or if I hit 200 runs without experiencing the bug.
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Game freezes randomly

Post by pgimeno »

200 runs through the first level later without any freezes, it seems like the issue might indeed be fixed in the latest LuaJIT.

It's still possible that reproducing the issue required doing something that I didn't do. I always got the freeze at the transition between the first level and the second before, but it may be dependent on LuaJIT's code length or who knows.

I'd be more comfortable if someone else can try and replicate these results. I guess a test build with a new LuaJIT will help some people.

As a side note, I think I have the speedrun record for the first level of Ayte's game :)
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Game freezes randomly

Post by ReFreezed »

I edited the code to allow the player to move a lot faster to speed up testing. For me the game usually freezes 2 or 3 rooms in, if it happens at all - otherwise I just restart the game.

Anyway, regardless what causes the freeze/error in the end, the fact that new stuff is inserted into the game.gameloop table while some caller is iterating over the table using pairs() most certainly puts us in the lovely undefined land. (Specifically, Game:summon() is called while the loop in Game:step() is running.) The real solution is probably just to not do that.

Also pgimeno, could you upload that test build with the new LuaJIT (if it's for Windows)?
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Game freezes randomly

Post by pgimeno »

ReFreezed wrote: Sat Jun 04, 2022 10:23 pm Anyway, regardless what causes the freeze/error in the end, the fact that new stuff is inserted into the game.gameloop table while some caller is iterating over the table using pairs() most certainly puts us in the lovely undefined land. (Specifically, Game:summon() is called while the loop in Game:step() is running.) The real solution is probably just to not do that.
Good catch, but I don't think the UB should affect a different loop.

The reason it's undefined behaviour is because adding an element can possibly expand the hash table, causing a reorganization of its elements, and therefore it might iterate over already iterated items and skip others. Even if not expanding it, it's indeterminate whether the newly added element will be iterated or not, depending on where it falls relative to the current element being iterated. ipairs() does not have that problem.

But at worst, that's a reason to crash in that loop, not in the other one. Still, I wonder if removing that UB would solve the problem. It's easy to store all keys from game.gameloop into a temporary array and loop through that array instead, to get well-defined behaviour.

ReFreezed wrote: Sat Jun 04, 2022 10:23 pm Also pgimeno, could you upload that test build with the new LuaJIT (if it's for Windows)?
It's for Linux.
User avatar
Kartik Agaram
Prole
Posts: 34
Joined: Fri Apr 01, 2022 4:46 am

Re: Game freezes randomly

Post by Kartik Agaram »

I noticed something similar in a very different app (a text editor). There too, I was able to turn off the JIT compiler entirely without anything seeming slower.

https://github.com/akkartik/lines.love/issues/3
Post Reply

Who is online

Users browsing this forum: No registered users and 224 guests