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

GDScript 2.0: Massive memory leaks when running a script via command line #68009

Open
MikeSchulze opened this issue Oct 29, 2022 · 6 comments
Open

Comments

@MikeSchulze
Copy link

MikeSchulze commented Oct 29, 2022

Godot version

v4.0.beta3.official [01ae26d]

System information

Windows 10

Issue description

I deployed a command line tool as SceneTree and it ends up with very many orphaned nodes.
Mainly StringNames orphans are detected.

And it also looks like classes with functions that return themselves are not handled correctly either.

class_name CmdConsole
extends RefCounted

func end_color() -> CmdConsole:
	return self
Resource still in use: res://addons/testplugin/CmdConsole.gd (GDScript)
Orphan StringName: res://addons/testplugin/CmdConsole.gd::0::CmdConsole.@implicit_new
Orphan StringName: res://addons/testplugin/CmdConsole.gd::5::CmdConsole.end_color
Orphan StringName: RefCounted

Also singletons are not freed.

#!/usr/bin/env -S godot -s
extends SceneTree

func _initialize():
	Engine.register_singleton("GlobalSignals", load("res://addons/testplugin/GlobalSignals.gd").new())
	quit(1)

func _finalize():
	Engine.unregister_singleton("GlobalSignals")
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
     at: cleanup (core/object/object.cpp:1996)
Leaked instance: GDScript:-9222514967540924276 - Resource path: res://addons/testplugin/GlobalSignals.gd
Leaked instance: GDScriptNativeClass:-9223002600947842753
Leaked instance: Node:862017116176795 - Node name:

Resource still in use: res://addons/testplugin/GlobalSignals.gd (GDScript)
Orphan StringName: value
Orphan StringName: _input
Orphan StringName: test
Orphan StringName: GDScript
Orphan StringName: res://addons/testplugin/GlobalSignals.gd

...

Steps to reproduce

I attached an small example project with example cases that results into orphan node detection.

Open a console and run:
Godot_v4.0-beta3_win64.exe --no-window -s -d CmdTool.gd --verbose

The output:

TextServer: Added interface "Dummy"
TextServer: Added interface "ICU / HarfBuzz / Graphite (Built-in)"
Godot Engine v4.0.beta3.official.01ae26d31 - https://godotengine.org
Text-to-Speech: SAPI initialized.
Vulkan devices:
  #0: NVIDIA NVIDIA GeForce GTX 980 - Supported, Discrete
Vulkan API 1.2.0 - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce GTX 980
- Vulkan Variable Rate Shading not supported
- Vulkan multiview supported:
  max view count: 32
  max instances: 134217727
- Vulkan subgroup:
  size: 32
  stages: STAGE_VERTEX, STAGE_TESSELLATION_CONTROL, STAGE_TESSELLATION_EVALUATION, STAGE_GEOMETRY, STAGE_FRAGMENT, STAGE_COMPUTE
  supported ops: FEATURE_BASIC, FEATURE_VOTE, FEATURE_ARITHMETIC, FEATURE_BALLOT, FEATURE_SHUFFLE, FEATURE_SHUFFLE_RELATIVE, FEATURE_CLUSTERED, FEATURE_QUAD, FEATURE_PARTITIONED_NV
  quad operations in all stages
Using present mode: VK_PRESENT_MODE_FIFO_KHR
Using "winink" pen tablet driver...
Creating VMA small objects pool for memory type index 7
Shader 'CanvasSdfShaderRD' SHA256: 143ba49ea6f38cc53f4e6580d7bfa307fe8ae1329caaa2890996dacb00646a8c
Shader 'SkeletonShaderRD' SHA256: 4e4fd7496baa2519df4c1680f607e36682002028b192bae12c187a2db66003d8
Shader 'ParticlesShaderRD' SHA256: 5c2a7901a8878518cf985113c48b0e8ee4ec42cfa10e4fc933ad21806c67504b
Shader 'ParticlesCopyShaderRD' SHA256: ecd2c072a5c09e0864e2830f05be7686137a11fd60110ef7434093283e1063ee
Shader 'CanvasShaderRD' SHA256: 4314cd81cacd5fddd6e6dafec299f28d8fe0579a6e02b2d9997dd6bdabaaa178
Shader 'CanvasOcclusionShaderRD' SHA256: 7086a1a6c6125ad298d7accf8dc52f12abacdebe749ebe5b94442c079deef5ca
Shader 'ClusterRenderShaderRD' SHA256: dfdadcddd267ed38800fde4439bb19ce1bf165e028c776f85f7d2036394a82b1
Shader 'ClusterStoreShaderRD' SHA256: 671f556d730c98687fdfe698ab1dc938c034ae539efc04733ee02c6c650c8d6e
Shader 'ClusterDebugShaderRD' SHA256: c2bafaff0cd34516d36efe2531b9567f6cb72a25c916be9e1dd374b9cf47cf12
Shader 'SceneForwardClusteredShaderRD' SHA256: 7345cd6b097fc2a81bf265e9370a72b8f3db4847d0241c28c4fec372049a53af
Shader 'ResolveShaderRD' SHA256: 5590c026234403a5272a7ffb626d284f9d1626fc094a90270806facf76d8b586
Shader 'TaaResolveShaderRD' SHA256: c423142756c3086c74899f65d11a90b37e70e9da36fe8502030f8f12a8036347
Shader 'SsEffectsDownsampleShaderRD' SHA256: 1acf201fa6b7189f9df2d3f2991f1a63363d0df87fa27a81d74b0803e0afa249
Shader 'SsilShaderRD' SHA256: 86dc1194e65194dfad9ee9f4f97de32b7ecba4275384d903ec09e375f0ccae2b
Shader 'SsilImportanceMapShaderRD' SHA256: f3caf760975e6228c316efd5928dec6d52a21f09ed4928f8a277b314ae0815dd
Shader 'SsilBlurShaderRD' SHA256: 1a4641db50f054e9fb218b9ebd04c70510d436fd3fa57c3871edabab1ae8237c
Shader 'SsilInterleaveShaderRD' SHA256: ed4cee50422c0fff3a1956983baa28fef11dd8cfe3b5a8d615e64127d85a1f37
Shader 'SsaoShaderRD' SHA256: dbb5434468cbc94b8c26fe5bd23721b14152cdf6dd04591fd147df1eb456ea9a
Shader 'SsaoImportanceMapShaderRD' SHA256: 4ddbd1e6cab72633bf0f8b20fb3d5c48ed25e051025e70a084ba52be2fe23986
Shader 'SsaoBlurShaderRD' SHA256: d360ed67fb070811331d4b67552e359a4d2d1b1ec1e9437b47335d8f9a51fdbe
Shader 'SsaoInterleaveShaderRD' SHA256: 1c6b60e8aaf25ce6715bfb837199fcd7977e1bdda4dfef84e45d8b20a5859c9d
Shader 'ScreenSpaceReflectionScaleShaderRD' SHA256: 8b2dd1bc4af07e739c99ce76254002a1e7dade3bfd2ddd67e96c9e3788882db2
Shader 'ScreenSpaceReflectionShaderRD' SHA256: 528515cfabd13ef2a50e475176babf4752ad1e9719b991486f72076ab117fba4
Shader 'ScreenSpaceReflectionFilterShaderRD' SHA256: 6b29eaa2661a760429306f6cf21fdc2fc299b5379cc397c26dc0ee5606d61353
Shader 'SubsurfaceScatteringShaderRD' SHA256: c5c6e660b0c0b2d470eb630f3ac2d240ddf6b54979d34caa5a2d4e3800a72d03
Shader 'SkyShaderRD' SHA256: 6c4511cd9c22265485459f4bd548738e9a117e2e55664c0bcbf95e6542634a7d
Shader 'VoxelGiShaderRD' SHA256: 3981ab7187c6c299855d62ea2309f02d5f989d18909e6468b05385b4803e265d
Shader 'VoxelGiDebugShaderRD' SHA256: a3f20f093c28525a191108dd305b1d7df0d52d37b2660be671252ef59ec21f41
Shader 'SdfgiPreprocessShaderRD' SHA256: 49cc32820cbea975c7b03c3a94c152686690dec76019d426585a6594ac022eb8
Shader 'SdfgiDirectLightShaderRD' SHA256: f3a68cc4188c267e8d5bfda2ff62b3d934793c4b814e5e516e96145f9a1aebaa
Shader 'SdfgiIntegrateShaderRD' SHA256: 45b78e07824e66a498d87a4de60742393eced867f49daa69811d34a2a0ed476b
Shader 'GiShaderRD' SHA256: 13c542f7e2032a316eb51e308bd2f4fdfaab029a2b484103f72c7aeeaddf390b
Shader 'SdfgiDebugShaderRD' SHA256: 3e646b55e2036b1faf76582bbfa53082a755964286d876f2e1ccee992df7adda
Shader 'SdfgiDebugProbesShaderRD' SHA256: 496ae66ecbdaa047d1a4887cc88d93b2c738f075a10dd409de986e9c4f6c037d
Shader 'VolumetricFogShaderRD' SHA256: 39e3934f5788b326b5d47902a2393c00c374c101c32618dac6127ec32d9605fc
Shader 'VolumetricFogProcessShaderRD' SHA256: 2d33a44a6881d539d9b34394b0cc0a7fcec06d2e347f2e14c4b13ae30a0611a0
Shader 'BokehDofShaderRD' SHA256: 5ad0fddcd372eef0ef5e3de6b56954b40a1d356e2b2268f09afc96e259d140d5
Shader 'CopyShaderRD' SHA256: 88685ac76285b7cbfdec348d1fa68f6a53ecf41cf88420c78abbce541d7176f8
Shader 'CopyToFbShaderRD' SHA256: 88546b37cdb49ca43957d4272a471f23c507a502d33f04fa1014e735e42c9cef
Shader 'CubeToDpShaderRD' SHA256: ff93df57d04553dfad431dd5cd6384bc9e0adfb3eb747c2657b451e52d2510f8
Shader 'CubemapDownsamplerShaderRD' SHA256: 0d714c29bfc83766149261eaf70136e2cac13b27741ed8889e74fdcf2ba95959
Shader 'CubemapFilterShaderRD' SHA256: d3f85a17efd76b0dc1f31233a0d19b01c669eec8ef4781a9722f594555cfeb24
Shader 'CubemapRoughnessShaderRD' SHA256: 1a5ab131f5130f3b5b7814f8b74b2ba9d5b3eccc7c8694c2958c48fa9cc52218
Shader 'SpecularMergeShaderRD' SHA256: d6ec8ae26e1a579b731ce0b1ec5b4a404bae1448e47fa0cb0797f7b9f2c26ce7
Shader 'TonemapShaderRD' SHA256: 82bc7ebbf73b777c64f9a382a34cfbed6841fe2e84a4d2720478142a4eb3ede8
Shader 'VrsShaderRD' SHA256: 0915d1d9ae31595667e5acfaad602eb55b3c452898494c330e54b8717b68379c
Shader 'FsrUpscaleShaderRD' SHA256: 147f667b6d7c4f2f397c45378b100831328bce19e0692f97e6b5d65b67b1a6a1
Shader 'LuminanceReduceShaderRD' SHA256: 4e80de8b54f44a05025a2b583ef50c3bfea5dfddf1ba8e44ae6e8e456d871fcb
Shader 'RoughnessLimiterShaderRD' SHA256: f7a8f337471e7c6522a9b67787228349deec867bac50d9518ca1f21db41f9dcf
Shader 'SortShaderRD' SHA256: f5e0a6ff315662ced3d367bbc3685079ecc114ff09957cf7e76c9a7c6571f3a3
Shader 'BlitShaderRD' SHA256: 27af37dcbc0fcd13395aa8a19bc02f1fe8b7e9e8b29a1ac2404ad0b474104031
WASAPI: Activated device using IAudioClient3 interface
WASAPI: wFormatTag = 65534
WASAPI: nChannels = 2
WASAPI: nSamplesPerSec = 48000
WASAPI: nAvgBytesPerSec = 384000
WASAPI: nBlockAlign = 8
WASAPI: wBitsPerSample = 32
WASAPI: cbSize = 22
WASAPI: mix_rate = 48000
WASAPI: fundamental_period_frames = 480
WASAPI: min_period_frames = 480
WASAPI: max_period_frames = 480
WASAPI: selected a period frame size of 480
WASAPI: detected 2 channels
WASAPI: audio buffer frames: 480 calculated latency: 10ms

TextServer: Primary interface set to: "ICU / HarfBuzz / Graphite (Built-in)".
CORE API HASH: 1657891440
EDITOR API HASH: 1097532847
ERROR: 'The class variable '_console' is declared but never used in the script.'
Loaded builtin certs
TestClassB:_init <RefCounted#-9223372010749427305>
_initialize
CLIRunner:_init CLIRunner:<Node#26323452310>
TestClassA:_init TestClassA:<Node#26541556115>
_finalize
 root
    CLIRunner
    TestClassA
 root
XR: Clearing primary interface
XR: Removed interfaceNative mobile
XR: Removed interfaceOpenXR
ERROR: Condition "_first != nullptr" is true.
   at: ~List (./core/templates/self_list.h:106)
ERROR: Condition "_first != nullptr" is true.
   at: ~List (./core/templates/self_list.h:106)
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
     at: cleanup (core/object/object.cpp:1996)
Leaked instance: GDScript:-9222514967540924276 - Resource path: res://addons/testplugin/GlobalSignals.gd
Leaked instance: GDScriptNativeClass:-9223000401924587197
Leaked instance: Node:862017116176796 - Node name:
Leaked instance: GDScript:-9222533109482782294 - Resource path: res://addons/testplugin/CmdConsole.gd
Leaked instance: GDScriptNativeClass:-9222887152226926063
Hint: Leaked instances typically happen when nodes are removed from the scene tree (with `remove_child()`) but not freed (with `free()` or `queue_free()`).
ERROR: Resources still in use at exit (run with --verbose for details).
   at: clear (core/io/resource.cpp:473)
Resource still in use: res://addons/testplugin/CmdConsole.gd (GDScript)
Resource still in use: res://addons/testplugin/GlobalSignals.gd (GDScript)
Orphan StringName: _enter_tree
Orphan StringName: _unhandled_input
Orphan StringName: _ready
Orphan StringName: _exit_tree
Orphan StringName: SceneMultiplayer
Orphan StringName: GDScriptNativeClass
Orphan StringName: res://addons/testplugin/CmdConsole.gd::0::CmdConsole.@implicit_new
Orphan StringName: value
Orphan StringName: _input
Orphan StringName: test
Orphan StringName: GDScript
Orphan StringName: res://addons/testplugin/GlobalSignals.gd
Orphan StringName: res://addons/testplugin/CmdConsole.gd
Orphan StringName: FileAccess
Orphan StringName: _shortcut_input
Orphan StringName: end_color
Orphan StringName: _process
Orphan StringName: Node
Orphan StringName: _unhandled_key_input
Orphan StringName: res://addons/testplugin/CmdConsole.gd::5::CmdConsole.end_color
Orphan StringName: RefCounted
Orphan StringName: res://addons/testplugin/GlobalSignals.gd::0::@implicit_new
Orphan StringName: _get_configuration_warnings
Orphan StringName: @implicit_new
Orphan StringName: _physics_process
StringName: 25 unclaimed string names at exit.

Minimal reproduction project

orphan.zip

@adamscott
Copy link
Member

adamscott commented Oct 29, 2022

My PR #67714 does not fix the leak, but it reduces its scope.

_finalize
 ┖╴root
    ┠╴CLIRunner
    ┖╴TestClassA
 ┖╴root
XR: Clearing primary interface
XR: Removed interfaceNative mobile
XR: Removed interfaceOpenXR
ERROR: Condition "_first != nullptr" is true.
   at: ~List (./core/templates/self_list.h:106)
PulseAudio: context terminated
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
     at: cleanup (core/object/object.cpp:1996)
Leaked instance: Node:875761011523990 - Node name: 
Leaked instance: GDScript:-9222503422668832357 - Resource path: res://addons/testplugin/GlobalSignals.gd
Leaked instance: GDScriptNativeClass:-9222885502959484398
Hint: Leaked instances typically happen when nodes are removed from the scene tree (with `remove_child()`) but not freed (with `free()` or `queue_free()`).
ERROR: Resources still in use at exit (run with --verbose for details).
   at: clear (core/io/resource.cpp:473)
Resource still in use: res://addons/testplugin/GlobalSignals.gd (GDScript)
Orphan StringName: _enter_tree
Orphan StringName: _unhandled_input
Orphan StringName: _ready
Orphan StringName: _exit_tree
Orphan StringName: SceneMultiplayer
Orphan StringName: GDScriptNativeClass
Orphan StringName: value
Orphan StringName: _input
Orphan StringName: test
Orphan StringName: GDScript
Orphan StringName: FileAccess
Orphan StringName: _shortcut_input
Orphan StringName: _process
Orphan StringName: Node
Orphan StringName: _unhandled_key_input
Orphan StringName: _get_configuration_warnings
Orphan StringName: _physics_process
StringName: 17 unclaimed string names at exit.

@MikeSchulze
Copy link
Author

MikeSchulze commented Feb 18, 2023

@Chaosus, @Calinou
Still detects orphan nodes in v4.0.rc2.official [d2699dc]

Here an small tool to find Engine core orphan nodes.
orphan.zip

Looks like there is also a chaching issue.
If you run the script inital from command line. (no .godot folder exists)
$GODOT_BIN --headless --path . -e -s res://example.gd --verbose
it shows:
StringName: 156 unclaimed string names at exit.
Run the script a second attemp it shows:
StringName: 187 unclaimed string names at exit.

MikeSchulze added a commit to MikeSchulze/gdUnit4 that referenced this issue Feb 18, 2023
)

# Why
Running the `GdUnitCmdTool` ends with an signal 11 and many orphan
resource detected


# What
- fixed the signal 11 by using a copy to iterate over singletons before
freeing
- when iterating over an array and removing elements during the
iteration, godot ended up with signl 11
- moving the func `assert_failed_at` to another posision (very strange
results, it crashed for no reason)
- using typed array on `load_testsuites()`
- fix some orphan issues around singleton implementation
- centralize code to finaly cleanup in new `quit` function to avoid
orphan nodes
- format touched code according to code style

# Note
It still detects orphan nodes see:
godotengine/godot#68009
@vnen vnen modified the milestones: 4.0, 4.x Feb 22, 2023
@MikeSchulze
Copy link
Author

Hello, what is the current status on the subject?
It feels like there are more and more memory leaks,

StringName: 871 unclaimed string names at exit.

@MikeSchulze
Copy link
Author

Hi, if there some update here?

@Calinou
Copy link
Member

Calinou commented Jul 11, 2023

Hi, if there some update here?

Leaks of this kind are fixed on a best-effort basis, when contributors are available to do so. As a result, we can't give an ETA for fixing this.

@okla
Copy link

okla commented Feb 15, 2024

Also having this issue when exporting using 4.2.1.stable.
godot --headless --verbose --path . --export-release Linux/X11 on a test project with a single Control node in it gives the following output

Orphan StringName: Node (static: 4, total: 5)
StringName: 1 unclaimed string names at exit.

Adding my GDExtension to the project changes the output to a lot more orphaned string names

StringName: 31 unclaimed string names at exit.

Also, on Windows, closing the exported project window takes ~15 seconds for it to exit and prints

munmap_chunk(): invalid pointer
Aborted (core dumped)

(not sure if this is related though).

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

No branches or pull requests

6 participants