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

Using RefCounted objects as thread bind parameters causes segfault on exit #101222

Open
SpiceOctopus opened this issue Jan 7, 2025 · 2 comments

Comments

@SpiceOctopus
Copy link

SpiceOctopus commented Jan 7, 2025

Tested versions

  • Reproducible in 4.3

System information

Linux 6.12.7 and Windows 11. Appears to be system independent.

Issue description

Binding an object that inherits from RefCounted to a callable that is passed to WorkerThreadPool.add_task() will produce a stale reference.

I am not entirely sure at which point it is missing a decrement (or if that is something I should be handling manually).
The behavior does seem unintended.

Steps to reproduce

func _ready():
	var test = TestObject.new() # empty object that extends RefCounted
	print(test.get_reference_count()) # prints 1
	var id = WorkerThreadPool.add_task(threadproc.bind(test))
	WorkerThreadPool.wait_for_task_completion(id)
	print(test.get_reference_count()) # prints 2

func threadproc(obj : RefCounted):
	print(obj.get_reference_count()) # prints 3

Run as a build outside of the editor, close the program -> segfault on exit. On Windows the program will crash on exit and write EventLog entries.

Minimal reproduction project (MRP)

Archive.zip

@matheusmdx
Copy link
Contributor

I was unable to reproduce this issue, tested both in editor and in exported version. I added prints in the TestObject._init and in the predelete notification, the object inits normally, do the prints 1, 3 and 2 and after print the predelete notification, no crashes or logs when i close the program.

Godot v4.3.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated AMD Radeon RX 580 2048SP (Advanced Micro Devices, Inc.; 31.0.21921.1000) - AMD Ryzen 5 3600 6-Core Processor (12 Threads)

@SpiceOctopus
Copy link
Author

This is strange, when I tested earlier this was causing segfaults with 100% reproducibility.
When I test that same code again it does not do it now. Maybe I messed up an export.

If I remove the WorkerThreadPool.wait_for_task_completion(id) it will segfault again.

This might play into another problem.
WorkerThreadPool.wait_for_task_completion() has been weirdly unreliable for me in the past.
The documentation states that it must be called for any started task. Yet whenever I implemented it that way it would error out and tell me that the task does not exist when called after the task had finished.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants