nil check on get_luaentity() #3601

Open
opened 2023-01-23 17:46:48 +00:00 by AliasAlreadyTaken · 22 comments

According to flux and wsor, get_luaentity() can return nil. This
is neither documented in https://github.com/minetest/minetest/blob/master/doc/lua_api.txt#L7154 nor do a lot of mods check for nil at this place.

  • Question devs under which circumstances get_luaentity()
  • Go through all mentions of get_luaentity() and nil-proof it
  • PR our findings to the API doc, since get_luaentity() is very poorly documented
  • Maybe mention in modder forum of minetest?
  • PR to all upstream mods when we found their non nil-proofed get_luaentity()
According to flux and wsor, get_luaentity() can return nil. This is neither documented in https://github.com/minetest/minetest/blob/master/doc/lua_api.txt#L7154 nor do a lot of mods check for nil at this place. * [ ] Question devs under which circumstances get_luaentity() * [ ] Go through all mentions of get_luaentity() and nil-proof it * [ ] PR our findings to the API doc, since get_luaentity() is very poorly documented * [ ] Maybe mention in modder forum of minetest? * [ ] PR to all upstream mods when we found their non nil-proofed get_luaentity()
Author
Owner

Followup of #3597

Followup of #3597
AliasAlreadyTaken added the
1. kind/bug
2. prio/low
2. prio/good first issue
labels 2023-01-23 17:48:38 +00:00
Member

it returns nil generally when either

  1. the object is a player
  2. the object is a stale reference to something which was unloaded

i'm not certain under which conditions minetest.get_objects_inside_radius would return stale references - looking at the code, it should be filtering them out.

after a cursory review of the code, most of the places where get_luaentity() is used seem to be immediately after creating an object (minetest.add_entity()) - which can fail if the object failed to be created, which is actually a rare occurrence.

it returns `nil` generally when either 1. the object is a player 2. the object is a stale reference to something which was unloaded i'm not certain under which conditions `minetest.get_objects_inside_radius` would return stale references - looking at the code, [it should be filtering them out](https://github.com/minetest/minetest/blob/b8aaad4f1ef2e4b22cb7d47de9cb54068ccbbe18/src/script/lua_api/l_env.cpp#L711). after a cursory review of the code, most of the places where `get_luaentity()` is used seem to be immediately after creating an object (`minetest.add_entity()`) - which can fail if the object failed to be created, which is actually a rare occurrence.
Author
Owner

Happened again in a different piece of code: #3606

The servers it happened on were 5.7.0-dev. The live server which is 5.6.1 runs this piece of code flawlessly. Is it possible this is a 5.7.0+ problem?

The code at the specific location flux mentioned didn't change for 2 years, but maybe something else somewhere else did, that may have affected it?

Also I was told the maintainer of Mineclone experienced a similar problem here: https://git.minetest.land/MineClone2/MineClone2/pulls/3324/files

Happened again in a different piece of code: #3606 The servers it happened on were 5.7.0-dev. The live server which is 5.6.1 runs this piece of code flawlessly. Is it possible this is a 5.7.0+ problem? The code at the specific location flux mentioned didn't change for 2 years, but maybe something else somewhere else did, that may have affected it? Also I was told the maintainer of Mineclone experienced a similar problem here: https://git.minetest.land/MineClone2/MineClone2/pulls/3324/files
Member

The servers it happened on were 5.7.0-dev. The live server which is 5.6.1 runs this piece of code flawlessly. Is it possible this is a 5.7.0+ problem?

seems quite possible. which commit of 5.7.0-dev is the server?

> The servers it happened on were 5.7.0-dev. The live server which is 5.6.1 runs this piece of code flawlessly. Is it possible this is a 5.7.0+ problem? seems quite possible. which commit of 5.7.0-dev is the server?
Author
Owner

The servers it happened on were 5.7.0-dev. The live server which is 5.6.1 runs this piece of code flawlessly. Is it possible this is a 5.7.0+ problem?

seems quite possible. which commit of 5.7.0-dev is the server?

Test Server says it's on b8aaad4f1, but git says it can't find this commit?

Maybe it was reverted?

However since the Mineclone maintainer also found a similar issue, I'd guess the problem is in more than one commit.

> > The servers it happened on were 5.7.0-dev. The live server which is 5.6.1 runs this piece of code flawlessly. Is it possible this is a 5.7.0+ problem? > > seems quite possible. which commit of 5.7.0-dev is the server? Test Server says it's on b8aaad4f1, but git says it can't find this commit? Maybe it was reverted? However since the Mineclone maintainer also found a similar issue, I'd guess the problem is in more than one commit.
https://github.com/minetest/minetest/commit/b8aaad4f1ef2e4b22cb7d47de9cb54068ccbbe18
Member

the immediate common denominator seems to be use of get_objects_inside_radius and get_objects_in_area. assuming that anything which doesn't check whether the objects returned by those is a valid object, i've found the following issues:

the immediate common denominator seems to be use of `get_objects_inside_radius` and `get_objects_in_area`. assuming that anything which doesn't check whether the objects returned by those is a *valid* object, i've found the following issues: * [ ] [meseportals](https://gitea.your-land.de/your-land/minetest-meseportals/src/commit/49853f81e25f584f55fb08728636ce6a98b1afea/node_behaviors.lua#L163) * [ ] [mobs_redo](https://gitea.your-land.de/your-land/mobs_redo/src/commit/bbcdc4b67d0e431d6045614d53adb85266973456/api.lua#L1316) * [ ] [moremesecons](https://gitea.your-land.de/your-land/MoreMesecons/src/commit/13645134a6015c7a38330f8850dde20b8909bece/moremesecons_entity_detector/init.lua#L46) * [ ] [petz](https://gitea.your-land.de/your-land/petz/src/commit/1770d622be0a10e1ae926f2cb4554f43e7b50c7c/kitz/api/api_clear_mobs.lua#L3) * [x] [smartshop](https://github.com/fluxionary/minetest-smartshop/commit/23000ff87fe0f97b62721c2ac8d4bc585e0d9612) * [ ] [spears](https://gitea.your-land.de/your-land/spears/src/commit/01e2bb97213381b47c7633523d923a77f3a7c1f8/functions.lua#L96) * [ ] [tnt](https://gitea.your-land.de/your-land/tnt/src/commit/9dc575d534cb2b72405c64b14090c81341de08f1/init.lua#L159) * [ ] [water_life](https://gitea.your-land.de/your-land/water_life/src/commit/d20a8b071fbea360fda8acff32ec1859e24ddeca/api.lua#L375) (herd members include anything that doesn't have a luaentity, like players or invalid objects...) * [ ] [yl_arena](https://gitea.your-land.de/your-land/yl_arena/src/commit/8afe3e7f2ba5003a02db654405ee389cd064f2ca/functions.lua#L277) * [ ] [yl_event](https://gitea.your-land.de/your-land/yl_events/src/commit/6e8f34ffa404f077a60b505b4825f225485edefb/temp.lua#L24) * [ ] [yl_monsterrace](https://gitea.your-land.de/your-land/yl_monsterrace/src/commit/72797da6d14d53d98ebb2262a56c5a26284f21b9/functions.lua#L157) (and several other uses) * [ ] [yl_nether_mobs](https://gitea.your-land.de/your-land/yl_nether_mobs/src/commit/8e2a4dce5f6b8540926d8f2c476e9507b132fe1f/wither.lua#L99)
Member

b8aaad4f1e

i'll rebuild my local server and see if i can't shake anything out

> https://github.com/minetest/minetest/commit/b8aaad4f1ef2e4b22cb7d47de9cb54068ccbbe18 i'll rebuild my local server and see if i can't shake anything out

b8aaad4f1e

i'll rebuild my local server and see if i can't shake anything out

Not saying thats the culprit, just linked to the commit which is probably the one Alias git couldn´t find

> > https://github.com/minetest/minetest/commit/b8aaad4f1ef2e4b22cb7d47de9cb54068ccbbe18 > > i'll rebuild my local server and see if i can't shake anything out Not saying thats the culprit, just linked to the commit which is probably the one Alias git couldn´t find
Member
local function override(get_objects)
    return function(...)
        local objects = get_objects(...)
        for i = 1, #objects do
            local obj = objects[i]
            if not (obj:is_player() or obj:get_luaentity()) then
                minetest.log("error", "invalid object?" .. dump({
                    pos = dump(obj:get_pos()),
                }))
            end
         end
         return objects
     end
 end
 
 minetest.get_objects_in_area = override(minetest.get_objects_in_area)
 minetest.get_objects_inside_radius = override(minetest.get_objects_inside_radius)
```lua local function override(get_objects) return function(...) local objects = get_objects(...) for i = 1, #objects do local obj = objects[i] if not (obj:is_player() or obj:get_luaentity()) then minetest.log("error", "invalid object?" .. dump({ pos = dump(obj:get_pos()), })) end end return objects end end minetest.get_objects_in_area = override(minetest.get_objects_in_area) minetest.get_objects_inside_radius = override(minetest.get_objects_inside_radius) ```
Member

i added a fix to moremesecons in a PR for something else: https://github.com/minetest-mods/MoreMesecons/pull/32

i guess we never put that logging code in the actual yl codebase

i added a fix to moremesecons in a PR for something else: https://github.com/minetest-mods/MoreMesecons/pull/32 i guess we never put that logging code in the actual yl codebase
Author
Owner

i guess we never put that logging code in the actual yl codebase

Should we?

> i guess we never put that logging code in the actual yl codebase Should we?
Member

i guess we never put that logging code in the actual yl codebase

Should we?

this issue hasn't actually occurred in quite a while, has it? maybe if it resurfaces.

> > i guess we never put that logging code in the actual yl codebase > > Should we? this issue hasn't actually occurred in quite a while, has it? maybe if it resurfaces.
Member

the MoreMesecons PR was accepted

the MoreMesecons PR was accepted
flux added the
4. step/partially fixed
label 2023-08-18 01:14:04 +00:00
Member

i guess we never put that logging code in the actual yl codebase

Should we?

this issue hasn't actually occurred in quite a while, has it? maybe if it resurfaces.

well, i guess i summoned the bug by mentioning it: #5155

i added a modified version of that code to yl_commons: a82eabdfb6

this version actually removes the "bad" objects from the return value so that other unsafe code won't crash, but note that it makes two of our most expensive functions even more expensive (see #3723). i should aim to patch all the other bad uses and then disable the "bugfix", but that's going to be a pain.

> > > i guess we never put that logging code in the actual yl codebase > > > > Should we? > > this issue hasn't actually occurred in quite a while, has it? maybe if it resurfaces. well, i guess i summoned the bug by mentioning it: #5155 i added a modified version of that code to yl_commons: https://gitea.your-land.de/your-land/yl_commons/commit/a82eabdfb6ff745546dca50fb9e18168373bef30 this version actually removes the "bad" objects from the return value so that other unsafe code won't crash, but note that it makes two of our most expensive functions even more expensive (see #3723). i should aim to patch all the other bad uses and then disable the "bugfix", but that's going to be a pain.
Member

alias writes in #5253:

We have a couple of those in the log:

2023-09-09 11:12:17: ERROR[Server]: INVALID OBJECT?! {
	properties = {
		eye_height = 1.625,
		breath_max = 0,
		wield_item = "",
		infotext = "yl_speak_up:human",
		colors = {
			{
				a = 255,
				r = 255,
				g = 255,
				b = 255
			}
		},
		spritediv = {
			x = 1,
			y = 1
		},
		initial_sprite_basepos = {
			x = 0,
			y = 0
		},
		automatic_face_movement_dir = false,
		automatic_face_movement_max_rotation_per_sec = -1,
		backface_culling = true,
		damage_texture_modifier = "^[brighten",
		shaded = true,
		zoom_fov = 0,
		makes_footstep_sound = false,
		stepheight = 0,
		nametag_color = {
			a = 255,
			r = 255,
			g = 255,
			b = 255
		},
		nametag_bgcolor = false,
		static_save = true,
		show_on_minimap = false,
		mesh = "",
		physical = false,
		collide_with_objects = true,
		collisionbox = {
			-0.5,
			-0.5,
			-0.5,
			0.5,
			0.5,
			0.5
		},
		visual = "sprite",
		visual_size = {
			x = 1,
			y = 1,
			z = 1
		},
		use_texture_alpha = false,
		is_visible = true,
		selectionbox = {
			-0.5,
			-0.5,
			-0.5,
			0.5,
			0.5,
			0.5,
			rotate = false
		},
		pointable = true,
		hp_max = 1,
		automatic_rotate = 0,
		glow = 0,
		nametag = "",
		textures = {
			"unknown_object.png"
		}
	},
	hp = 100,
	is_player = false,
	pos = "(2003,14.5,1172)",
	entity_name = "yl_speak_up:human",
	nametag_attributes = {
		text = "",
		color = {
			a = 255,
			r = 255,
			g = 255,
			b = 255
		},
		bgcolor = false
	}
}

alias writes in #5253: We have a couple of those in the log: ``` 2023-09-09 11:12:17: ERROR[Server]: INVALID OBJECT?! { properties = { eye_height = 1.625, breath_max = 0, wield_item = "", infotext = "yl_speak_up:human", colors = { { a = 255, r = 255, g = 255, b = 255 } }, spritediv = { x = 1, y = 1 }, initial_sprite_basepos = { x = 0, y = 0 }, automatic_face_movement_dir = false, automatic_face_movement_max_rotation_per_sec = -1, backface_culling = true, damage_texture_modifier = "^[brighten", shaded = true, zoom_fov = 0, makes_footstep_sound = false, stepheight = 0, nametag_color = { a = 255, r = 255, g = 255, b = 255 }, nametag_bgcolor = false, static_save = true, show_on_minimap = false, mesh = "", physical = false, collide_with_objects = true, collisionbox = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, visual = "sprite", visual_size = { x = 1, y = 1, z = 1 }, use_texture_alpha = false, is_visible = true, selectionbox = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, rotate = false }, pointable = true, hp_max = 1, automatic_rotate = 0, glow = 0, nametag = "", textures = { "unknown_object.png" } }, hp = 100, is_player = false, pos = "(2003,14.5,1172)", entity_name = "yl_speak_up:human", nametag_attributes = { text = "", color = { a = 255, r = 255, g = 255, b = 255 }, bgcolor = false } } ```
Member
	pos = "(2003,14.5,1172)",
	entity_name = "yl_speak_up:human",

this is Amanda.

i added some code to add a stack trace to see if there's any pattern b27043c302

``` pos = "(2003,14.5,1172)", entity_name = "yl_speak_up:human", ``` this is Amanda. i added some code to add a stack trace to see if there's any pattern https://gitea.your-land.de/your-land/yl_commons/commit/b27043c302147f05d31dc06979270dbb5d9c8c67
Author
Owner

2023-12-14 23:47:58: ERROR[Server]: LuaEntity name "water_life:crocodile" not defined
2023-12-14 23:48:00: ERROR[Server]: INVALID OBJECT?! {
2023-12-14 23:48:00: ERROR[Server]: INVALID OBJECT?! {
2023-12-14 23:48:01: ERROR[Server]: INVALID OBJECT?! {

There occurred 90 incidents lately, unfortunately the debug code was not yet ingame.

2023-12-14 23:47:58: ERROR[Server]: LuaEntity name "water_life:crocodile" not defined 2023-12-14 23:48:00: ERROR[Server]: INVALID OBJECT?! { 2023-12-14 23:48:00: ERROR[Server]: INVALID OBJECT?! { 2023-12-14 23:48:01: ERROR[Server]: INVALID OBJECT?! { There occurred 90 incidents lately, unfortunately the debug code was not yet ingame.
Member

2023-12-14 23:47:58: ERROR[Server]: LuaEntity name "water_life:crocodile" not defined

i'm pretty sure that was me trying to spawn one in to test something, not realizing that they name is "water_life:croc"

> 2023-12-14 23:47:58: ERROR[Server]: LuaEntity name "water_life:crocodile" not defined i'm pretty sure that was me trying to spawn one in to test something, not realizing that they name is "water_life:croc"
Member

per #6575, the cause if this is probably almost always unknown objects.

i'm not sure why Amanda was implicated though, unless we started up the server w/out NPCs once, or in that intermediate era where they weren't aliased properly?

per #6575, the cause if this is probably almost always unknown objects. i'm not sure why Amanda was implicated though, unless we started up the server w/out NPCs once, or in that intermediate era where they weren't aliased properly?
Author
Owner

So the 100% repro is "unknown object" ? I'm fairly certain there was a brief time on main where we switched from one type of NPC to another, but they should never have been on for more than a minute or so, just in case I started the server by mistake. If NPCs were unknown objects, they're fairly easy to spot

So the 100% repro is "unknown object" ? I'm fairly certain there was a brief time on main where we switched from one type of NPC to another, but they should never have been on for more than a minute or so, just in case I started the server by mistake. If NPCs were unknown objects, they're fairly easy to spot
Member

the 100% repro is "unknown object" ?

yes, not sure about the rest of it though. there might be another cause.

> the 100% repro is "unknown object" ? yes, not sure about the rest of it though. there might be another cause.
Sign in to join this conversation.
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: your-land/bugtracker#3601
No description provided.