Repository: godotengine/godot (language: cpp)

Issue:
"Attempted to free invalid ID" errors are printed when exiting a project run with Debug Canvas Item Redraw
### Tested versions

- Reproducible in: 4.4.beta2, 4.4.beta2
- Not reproducible in: 4.3.stable, 4.4.beta1

### System information

Godot v4.4.beta (36d90c73a) - Fedora Linux 41 (KDE Plasma) on X11 - X11 display driver, Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4090 (nvidia; 565.77) - 13th Gen Intel(R) Core(TM) i9-13900K (32 threads)

### Issue description

Running the MRP with `--debug-canvas-item-redraw` will result in the following on exit:

```
ERROR: Attempted to free invalid ID: 4509715660816
   at: _free_internal (./servers/rendering/rendering_device.cpp:6106)
ERROR: Attempted to free invalid ID: 4526895530004
   at: _free_internal (./servers/rendering/rendering_device.cpp:6106)
ERROR: Attempted to free invalid ID: 4539780431895
   at: _free_internal (./servers/rendering/rendering_device.cpp:6106)
```

The invalid IDs are the usually same on every run (in this particular project), especially the first one. No further information about this is printed when using `--verbose`.

The feature still works correctly, so it's not a big issue but we should still aim to fix it.

I've bisected this to https://github.com/godotengine/godot/pull/101931. cc @stuartcarnie 

### Steps to reproduce

- Add a CheckButton node.
- With the editor being run from a terminal (so you can see all errors on exit), enable **Debug > Visible Canvas Item Redraw** or run the project with `--debug-canvas-item-redraw` when using Forward+ or Mobile.
- Exit the project and notice errors being printed in the terminal.

### Minimal reproduction project (MRP)

[test_debug_canvas_item_redraw.zip](https://github.com/user-attachments/files/18739163/test_debug_canvas_item_redraw.zip)


Discussion / hints:

Fix patch:
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 172d6e547118..6da4d24e7256 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -3299,6 +3299,8 @@ void RendererCanvasRenderRD::_prepare_batch_texture_info(RID p_texture, TextureS
 
 RendererCanvasRenderRD::~RendererCanvasRenderRD() {
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+
 	//canvas state
 
 	material_storage->material_free(default_canvas_group_material);
@@ -3346,7 +3348,9 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() {
 		}
 	}
 
-	RendererRD::TextureStorage::get_singleton()->canvas_texture_free(default_canvas_texture);
+	// Disable the callback, as we're tearing everything down
+	texture_storage->canvas_texture_set_invalidation_callback(default_canvas_texture, nullptr, nullptr);
+	texture_storage->canvas_texture_free(default_canvas_texture);
 	//pipelines don't need freeing, they are all gone after shaders are gone
 
 	memdelete(shader.default_version_data);


Test patch: