Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error spam (and/or crash) in release template / exported builds: "slot >= slot_max" is true. Returning: nullptr #70910

Closed
Dunkhan opened this issue Jan 4, 2023 · 47 comments · Fixed by #78987, #78988 or #85280

Comments

@Dunkhan
Copy link

Dunkhan commented Jan 4, 2023

Godot version

4.0 beta 10

System information

Windows 10

Issue description

In my rss reader on windows, when the user switches between feed lists - that is, when a VBoxContainer has all its children removed and a new set re-added, the application crashes with:

USER ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
at: get_instance (./core/object/object.h:974)

This only happens on the windows version and only when that version is built in release mode. In an earlier beta (7 or 10 I am not sure) it was happening occasionally on the linux build too, but that no longer appears to be an issue. I was not able to find any information or other bug reports about this error.

Steps to reproduce

I have no simple minimal reproduction available, but it is fairly constant in my current project. You can find the source here:
https://gitlab.com/gametheatre/poriferareader/Porifera

  1. Build a release windows version of the project
  2. Run the exported executable
  3. After running the project, subscribe to two or more RSS feeds.
  4. If it still has not crashed, switch back and forth between these feeds.

Because this appears to be an issue with the build system it is likely that it will be a major hassle to debug. Let me know if there is any help I can offer.

Minimal reproduction project

As mentioned above it is consistently reproducible with this (non minimal) project: https://gitlab.com/gametheatre/poriferareader/Porifera

As a temporary workaround, only creating debug builds for windows solves this.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 4, 2023

In general I feel like a lot of Godot error messages that come from the c++ code could be a bit more verbose. As far as I can tell from the code (I am not great at c++) it has something to do with signals. I have no idea what a slot is or what the slot_max value is based on. I will look into it more when I have time but if anyone has any insight in the mean time that would be appreciated.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 4, 2023

Looking into it further, the objects being created are subscribing to events. Is it possible that there is an issue with having too many subscriptions to the same event? If so I can work out a different way of passing these changes around.
I should mention I am using C# Mono, hence the word events instead of signals. The event being subscribed to is not a native Godot event and therefore is unlikely to have a signal component. On the other hand I have no idea how mono is integrated so maybe it does.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 17, 2023

This appears to be fixed in beta 12. I will do some more testing and confirm

@Dunkhan
Copy link
Author

Dunkhan commented Jan 17, 2023

Still happening on windows

@Dunkhan
Copy link
Author

Dunkhan commented Jan 18, 2023

While attempting to get debugging working on windows, I discovered that when the client is built on a windows machine, the issue does not happen. This means that it only happens when building a windows build on a linux system. This makes the bug less urgent but also easier to reproduce. I will update the reproduction.

@akien-mga
Copy link
Member

When you say "built on a Linux system", do you mean exporting the project with the official pre-compiled export templates, or are you compiling custom export templates with mingw?

@Dunkhan
Copy link
Author

Dunkhan commented Jan 18, 2023

exporting the project with the official pre-compiled export templates

@akien-mga
Copy link
Member

akien-mga commented Jan 18, 2023

I tried to reproduce it by exporting from Linux with 4.0 beta 13, and running the project in Wine, but it doesn't seem to crash. (FYI for testers, the repo requires the Mono build of Godot.)

image

As a side note, I had an error when exporting:

ERROR: Cannot open file 'res://Themes/MainTheme.tres'.
   at: load (scene/resources/resource_format_text.cpp:1581)
ERROR: Failed loading resource: res://Themes/MainTheme.tres. Make sure resources have been imported by opening the project in the editor at least once.
   at: _load (core/io/resource_loader.cpp:214)
ERROR: res://Item.tscn:10 - Parse Error: [ext_resource] referenced non-loaded resource at: res://Themes/MainTheme.tres
   at: _parse_ext_resource (scene/resources/resource_format_text.cpp:178)
ERROR: res://Item.tscn:47 - Parse Error: [ext_resource] referenced non-loaded resource at: res://Themes/MainTheme.tres
   at: _parse_ext_resource (scene/resources/resource_format_text.cpp:178)

But it's not necessarily related. This file is missing your GitLab repo.

Also had this error, which I suspect is a bug in the Mono module:

editor/export/editor_export_plugin.h:123 - Required virtual method EditorExportPlugin::_get_name must be overridden before calling.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 18, 2023

thanks for trying, while I was thinking about your last question it occurred to me that I started exporting in a slightly different way at around the same time this started happening. I wrote a bash script that deploys the whole project. The script includes the lines:

rm -r $windowsBuildPath
mkdir $windowsBuildPath
$godot --export-release "Windows Desktop" $windowsBuildPath/Porifera.exe

Is this correct? Is it possible that this is required for the reproduction?
If there is a possibility of that I can do some tests to check.

I have no idea why it is still asking for 'res://Themes/MainTheme.tres', that was removed some time ago and I can't find any remaining references to it.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 18, 2023

My first test seems to confirm it is the script. Is it maybe the fact that the script builds release and when I do it by hand the default is debug?

@akien-mga
Copy link
Member

--export-release makes a release build yes, and in the export dialog in the editor there's a checkbox "Export with Debug". If you didn't disable it, then it's a debug build. You should see "(DEBUG)" in the window title.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 18, 2023

I was more asking if that could be causing the crash. I suppose I need to test that for myself though.

@akien-mga
Copy link
Member

Yes a release export is more likely to crash than a debug export, as it does less validation checks to save performance. But it would usually point out the error in debug mode.

@PauloVBettio
Copy link

This is happening to me as well. Running it through Wine does not throws any errors on the console, but running it on an actual Windows machine does, and crashes the game.

Windows:
image

Linux / Wine
image

I've used Linux to export my game with the official beta 14 export template.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 21, 2023

I did further tests and I am able to build a debug version on linux for windows and it does not crash. I will do a test to see how the windows -> windows release build does.

Edit: Ok I have confirmed that this has nothing to do with linux at all. Building a release version on windows for windows crashes in the same way.

I also spent some more time trying to decipher the engine code but the best I could do is figure out that some RID is not being initialised correctly. Is there someone who knows this part of the code that could possibly shed some light on why my project and PauloVBettio's project are affected an not others? I have to assume this is not affecting everyone or it would have been noticed sooner and by more people.

@PauloVBettio
Copy link

Building the game on an Windows machine gave me the same result as @Dunkhan. The game only shows the splash screen and crashes.

@shendo
Copy link
Contributor

shendo commented Jan 23, 2023

I encountered a similar issue with an Android project on Godot 4 recently.

No noticed problems until switching to release builds which would have lots of screen layout issues and occasional crashes, accompanied by the ‘slot_max’ error logs.

I believe the error message is just a symptom of referencing an invalid object.

In my case I was adding and removing Controls to Containers with GDScript but invalidly using Object.free() on the child before it was implicitly removed. Presumably, this was causing the container to read the already free’d memory with undefined results. The debug builds probably have some safety checks which result in the memory staying valid for longer.

Changing my code to explicitly call Container.remove_child() and use child.queue_free() fixed the issue.

@Dunkhan
Copy link
Author

Dunkhan commented Jan 23, 2023

So you have to remove the child and then free it? Why is there nothing about this in the documentation? This article specifically does not mention this. Neither does the node page.

@h0lley
Copy link

h0lley commented Feb 10, 2023

I am also getting spammed with

ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
   at: get_instance (./core/object/object.h:972)

on Ubuntu when a level is being loaded with a template_release build.
I reckon there's probably no single solution to it but it's project individual.

so the main issue seems to me that this error message is entirely cryptic to users.

@Dunkhan
Copy link
Author

Dunkhan commented Feb 15, 2023

I noticed I am also getting this error on linux builds, regardless of release or debug. There appear to be no symptoms in the programs behaviour though.

@YuriSizov
Copy link
Contributor

so the main issue seems to me that this error message is entirely cryptic to users.

According to the code comments, "This should never happen unless RID is corrupted." So it cannot really be made less cryptic, since this seems to be a critical failure causing invalid data. Would be amazing to get a small, purpose-built MRP to find the culprit.

@Dunkhan
Copy link
Author

Dunkhan commented Feb 15, 2023

Would be amazing to get a small, purpose-built MRP to find the culprit.

The stability of the last few beta releases with my project, and the amount of things that have randomly broken with no documentation or debug output, suggest to me that we should probably be testing with larger projects like this more. A small purpose built MRP is great for resolving a single issue, if the problem can be narrowed down that far, but there is no substitute for testing with scenarios that mirror real world usage. I predict that a lot of hidden bugs that only manifest in more complex use-cases are going to make the 4.0 release a real headache for a lot of people that migrate on release day.

Edit: sorry if this sounds dismissive, of course I would love to help narrow down the cause of this. I just wanted to mention some general concerns I have as well. RC2 is also a lot more stable than most of the recent versions and there are some very nice fixes so things are looking good in general.

@Brawmario
Copy link

I'd like to chime in, I'm also having this exact error when running the demo for my libsm64-godot addon on Linux every time, both in debug and release, but never on my Windows build. The addon has a GDExtension module in it which is compiled through the included GitHub action in the .github folder on a Ubuntu runner.

@sine707
Copy link

sine707 commented Mar 6, 2023

I also had this error occur when building for Windows Desktop and Web, building from Windows 10 on Godot 4.0 stable.

It happened when I cleared objects in a UI container with a for loop.
I eventually managed to get rid of it by replacing free() with queue_free()

Debug builds ran fine without errors, only release builds seem to be affected which makes it a particularly nasty bug.

It's easy to reproduce, here's a quick example.
A few iterations seem fine, but a large amount seems to raise the error.

func clear_and_repopulate() -> void:
	if container.get_child_count() > 0:
		for square in container.get_children():
			square.free()
	
	populate_squares()


func populate_squares() -> void:
	for _i in 300:
		var square: ColorRect = ColorRect.new()
		container.add_child(square)

@gynura
Copy link

gynura commented Sep 17, 2023

I am having this same error when building to linux or windows, again if I export it with DEBUG it works fine, really nasty bug and no real fix:

Reproduces with Godot 4.0.3 (Steam). Exporting for Windows, release. Both when exporting on a Windows and a Mac OS machine. The full log when running my exported application and performing steps to reproduce is just this:

Godot Engine v4.0.3.stable.official.5222a99f5 - https://godotengine.org
OpenGL API 3.3.0 NVIDIA 536.40 - Compatibility - Using Device: NVIDIA Corporation - NVIDIA GeForce RTX 2060 with Max-Q Design
 
USER ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
   at: get_instance (./core/object/object.h:972)

The crash happens every time when changing to a certain scene with get_tree().change_scene_to_file(). However, that scene I'm changing to, won't crash the application if it's set as the main one: the application will start normally. It's only when I try changing to the problematic scene, the crash happens.

When exporting for Windows with debug enabled, the issue doesn't reproduce, and there's nothing in the logs.

Edit: I was able to fix this by changing the scenes from load() to preload() and changing the scene with this code:

get_tree().change_scene_to_packed(scene_to_load)
queue_free()

@Koyper
Copy link
Contributor

Koyper commented Sep 21, 2023

Also crashes release builds in MacOS (arm64) about once every six executions. About one in four executions report no errors, the rest report a series of ERROR: Condition "slot >= slot_max" is true. Returning: nullptr.

The crash occassionally reports something like this:

(39992,0x209421280) malloc: Incorrect checksum for freed object 0x7fb8ce37e900: probably modified after being freed. Corrupt value: 0xb00007008ce358b5 (39992,0x209421280) malloc: *** set a breakpoint in malloc_error_break to debug

All debug builds run perfectly and report no issues with verbose output.

@homhomhomhomhom
Copy link

I am having this same error when building to linux or windows, again if I export it with DEBUG it works fine, really nasty bug and no real fix:

Reproduces with Godot 4.0.3 (Steam). Exporting for Windows, release. Both when exporting on a Windows and a Mac OS machine. The full log when running my exported application and performing steps to reproduce is just this:

Godot Engine v4.0.3.stable.official.5222a99f5 - https://godotengine.org
OpenGL API 3.3.0 NVIDIA 536.40 - Compatibility - Using Device: NVIDIA Corporation - NVIDIA GeForce RTX 2060 with Max-Q Design
 
USER ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
   at: get_instance (./core/object/object.h:972)

The crash happens every time when changing to a certain scene with get_tree().change_scene_to_file(). However, that scene I'm changing to, won't crash the application if it's set as the main one: the application will start normally. It's only when I try changing to the problematic scene, the crash happens.
When exporting for Windows with debug enabled, the issue doesn't reproduce, and there's nothing in the logs.

Edit: I was able to fix this by changing the scenes from load() to preload() and changing the scene with this code:

get_tree().change_scene_to_packed(scene_to_load)
queue_free()

didn't fix this error for me :(
I have the exact same error every time a scene change happens, even with change_scene_to_packed.
I have tried preloading and using @export var = PackedScene
but this error "ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
at: get_instance (./core/object/object.h:986)" is still happening

@Dunkhan
Copy link
Author

Dunkhan commented Oct 4, 2023

This error occurs for me when I unloaded and loaded a bunch of new nodes into the tree, there was never a scene change involved. Fiddling with the way things were loaded sometimes helped but it appears to be populating the tree that is the issue and not scene loading directly.

@Koyper
Copy link
Contributor

Koyper commented Oct 6, 2023

I was finally able to reproduce this bug and prevent it from happening (so far). In my case it is caused by removing children from a parent, immediately followed by adding new children to the same parent.

Internally, the parent node appears very sensitive to being blocked by removing children while adding a new child is being attempted.

In my case the parent is a VBoxContainer. I confirmed that the bug and fix also apply when the VBoxContainer is changed to a Control, so it apparently is not specific to a container type.

Only this combination of steps prevents the errors:

  1. Children must be removed using remove_child(), followed by queue_free(). The error occurs either by omitting the remove_child() step, or using free() instead of queue_free().
  2. The new children must be then be added via a separate function called with call_deferred("_add_new_children"). Adding the children in a for loop using call_deferred("add_children", new_child) does not work.
  3. Inside the _add_new_children() function, prefer to use `call_deferred("add_children", new_child), even though it so far seems to work without the deferred call. The bug is intermittent and why give it fuel?

It may also work to use a process, while or await to test that the children have been completely removed and freed prior to adding new children. If you need to handle a child after it's been added to the tree, you can use the child_entered_tree signal on the parent, which passes in the added child.

So if the above fix is applied to the example from @sine707:

func clear_and_repopulate() -> void:
	if container.get_child_count() > 0:
		for square in container.get_children():
			square.free()
	
	populate_squares()


func populate_squares() -> void:
	for _i in 300:
		var square: ColorRect = ColorRect.new()
		container.add_child(square)

It would look like this (untested):

func clear_and_repopulate() -> void:
	if container.get_child_count() > 0:
		for square in container.get_children():
			container.remove_child(square)
			square.queue_free()
	
	call_deferred("populate_squares")


func populate_squares() -> void:
	for _i in 300:
		var square: ColorRect = ColorRect.new()
		container.call_deferred("add_child", square)

@Dunkhan
Copy link
Author

Dunkhan commented Oct 7, 2023

Your reproduction matches my experience very closely. As far as the solution goes I found that using multiple defers did not always solve the problem though. This might be because I am using threads in c# so I was having difficulty establishing exactly when things happen and working out how to ensure that everything happens in the right order.

Hopefully this helps someone debug the internal functions though so we can make the behaviour more stable in the engine.

@Capital-EX
Copy link

so the main issue seems to me that this error message is entirely cryptic to users.

According to the code comments, "This should never happen unless RID is corrupted." So it cannot really be made less cryptic, since this seems to be a critical failure causing invalid data. Would be amazing to get a small, purpose-built MRP to find the culprit.

I'm not sure what happened between Godot 3 and Godot 4, but I have managed to make a MRP that seems to consistently triggers the bug when exported. @YuriSizov hopefully this can be of some use.

This code will trigger 2 error messages:

for i in range(100):
	var label = Label.new()
	label.text = "%d" % i
	$VBoxContainer.add_child(label)

for child in $VBoxContainer.get_children():
	child.free()

This code however will cause a spew of error message:

for i in range(100):
	var label = Label.new()
	label.text = "%d" % i
	$VBoxContainer.add_child(label)

for child in $VBoxContainer.get_children():
	child.free()

for i in range(100):
	var label = Label.new()
	label.text = "-%d" % i
	$VBoxContainer.add_child(label)

I have currently "fixed" this by purging free from every line of code in my project and replacing it with queue_free.

MRP

Freebug.zip

@KccbzZ
Copy link

KccbzZ commented Oct 14, 2023

I have this same exact issue, the game crashes when I have a release build for Windows and never in debug or in the editor. It's really frustrating because I have turned my project that I worked on for about 2 years inside-out just because of trying to hunt down this error... It seems to appear during run time when I change a scene..

As mentioned before by other people here, using free() instead of queue_free() also seems to create this error. I also tried to use call_deferred() when changing scenes, and I think it does seem to minimize the error in a (semi-)test scene to only print the error once rather than 3-5 times at a time, and sometimes it doesn't print it at all. The game still crashes upon scene change but less frequently.

I should probably say I'm using Godot 4.1.1.stable, and here's the error because why not:

image

I'd love to have a fix to this, I really don't want my project of 2 years to go to waste. And this error seems to appear for quite a few people so this does seem to need fixing.

@pshepjr
Copy link

pshepjr commented Oct 20, 2023

I am getting this error too and sad to see that there is apparently no fix for it... :(

@KccbzZ
Copy link

KccbzZ commented Oct 24, 2023

I am getting this error too and sad to see that there is apparently no fix for it... :(

@pshepjr In case your issue is also crashing upon scene change, see this comment from gmjosack #75422 (comment), it seems to have fixed it for me!

In terms of the "slot >= slot_max" error, gmjosack uses remove_child(child) before doing child.queue_free(), so perhaps that could be of some assistance too. Although I'm not sure if remove_child(child) is what fixed it for me.

I read that for Godot 4.2 they'll be focusing on stability so that's nice.

Hope that helps mate!

@YuriSizov YuriSizov modified the milestones: 4.2, 4.x Nov 15, 2023
@dogboydog
Copy link
Contributor

I had a crash following this error in 4.2 dev 5, only in release builds.

My code causing the crash was like this:

        root.CallDeferred("add_child", sceneInstance);
        foreach (var node in nodesToFree)
        {
            if (!IsInstanceValid(node)){ continue;}
            node.CallDeferred("queue_free");
        }

Changing to this (calling QueueFree() immediately instead of deferring it) seems to avoid the crash on Windows and Linux

       root.CallDeferred("add_child", sceneInstance);
        foreach (var node in nodesToFree)
        {
            if (!IsInstanceValid(node))
            {
                continue;
            }
            node.QueueFree();
        }

@akien-mga
Copy link
Member

akien-mga commented Nov 23, 2023

I can confirm the issue in 4.2-rc1 with @Capital-EX's MRP from #70910 (comment)

I can also clarify that this only happens with release templates (target=template_release), not with debug templates (target=template_debug). So the problem comes from a difference in code paths controlled by DEBUG_ENABLED.


Actually with that project in 4.1.3-stable Linux release template I get an endless error spam of the slot >= slot_max error, while in 4.2-rc1 I get a short burst of spamming that error (~10 times) and then a different error and a segmentation fault:

ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
   at: get_instance (./core/object/object.h:1033)
ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
   at: get_instance (./core/object/object.h:1033)
ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
   at: get_instance (./core/object/object.h:1033)
ERROR: Parameter "canvas_item" is null.
   at: canvas_item_clear (servers/rendering/renderer_canvas_cull.cpp:1558)
Segmentation fault (core dumped)

I'll try to compile a release template with debug symbols to get a stacktrace.

Edit: I don't reproduce the crash with a custom build with scons -j7 p=linuxbsd dev_build=yes dev_mode=yes linker=mold scu_build=all target=template_release. I'll have to assess whether dev_build or dev_mode impact things here, the crash might come from optimizations.

Edit 2: I moved the issue with the 4.2-specific crash to #85263 as it's not fully equivalent to the original bug report here. It's probably triggered by the same bug, but likely also by something 4.2 specific since it doesn't appear in 4.1, unlike the slot >= slot_max error spam.

@akien-mga akien-mga changed the title "slot >= slot_max" is true. Returning: nullptr Error in release template / exported builds: "slot >= slot_max" is true. Returning: nullptr Nov 23, 2023
@akien-mga akien-mga changed the title Error in release template / exported builds: "slot >= slot_max" is true. Returning: nullptr Error spam (and/or crash) in release template / exported builds: "slot >= slot_max" is true. Returning: nullptr Nov 23, 2023
@akien-mga akien-mga modified the milestones: 4.x, 4.3 Nov 23, 2023
@akien-mga akien-mga modified the milestones: 4.3, 4.2 Nov 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment