OverviewFilesCommitsIssuesDocsReleasesPeers

nvidia-rtx-godot commits / a726265

Cap the "Attempted to free invalid ID" spam
Something upstream double-frees RIDs at high volume during dc-terrain streaming -- hundreds of reports per frame in a normal session. ERR_PRINT is not cheap (string construction plus synchronous stderr), so at that rate the reporting becomes a framerate problem stacked on top of the bug it is reporting, and it buries every other message in the log. Print the first 64 in full -- the existing backtrace_dump covers the first 20, which is the actual diagnostic -- then count silently and report a running total every 1000. The bug is unchanged and still visible; only the spam is bounded. Doubles as a discriminator for a performance investigation: if frame rate improves purely from capping the printing, the logging was a material part of the cost. Note the backtraces only resolve in a build with debug_symbols=yes; without them backtrace_dump returns nothing useful, which is why these reports have been unattributable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a726265c013b5ef66b1078f7ee829f686904018e
by plankatron <fleeky@gmail.com> · 2026-07-29T17:20:02.000Z

Changed files (1) +21 -2

servers/rendering/rendering_device.cpp +21 -2
……@@ -7864,11 +7864,30 @@ void RenderingDevice::_free_internal(RID p_id) {
78647864 trace_count++;
78657865 trace_suffix = "\n" + backtrace_dump() + " [trace " + itos(trace_count) + "/20]";
78667866 }
7867
7868 // This fires per double-freed RID, and something upstream can produce
7869 // hundreds per frame. ERR_PRINT is not cheap -- string building plus
7870 // synchronous stderr -- so unbounded spam becomes a framerate problem in
7871 // its own right, on top of whatever bug is causing the frees. Print the
7872 // first PRINT_LIMIT in full (the backtraces are the diagnostic), then
7873 // report a running total periodically instead of every occurrence.
7874 constexpr int PRINT_LIMIT = 64;
7875 static int invalid_free_count = 0;
7876 invalid_free_count++;
7877
7878 if (invalid_free_count <= PRINT_LIMIT) {
78677879#ifdef DEV_ENABLED
7868 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()) + " " + resource_name + trace_suffix);
7880 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()) + " " + resource_name + trace_suffix);
78697881#else
7870 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()) + trace_suffix);
7882 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()) + trace_suffix);
78717883#endif
7884 if (invalid_free_count == PRINT_LIMIT) {
7885 ERR_PRINT("Attempted to free invalid ID: reached " + itos(PRINT_LIMIT) +
7886 " reports; further occurrences are counted, not printed.");
7887 }
7888 } else if ((invalid_free_count % 1000) == 0) {
7889 ERR_PRINT("Attempted to free invalid ID: " + itos(invalid_free_count) + " total occurrences so far.");
7890 }
78727891 }
78737892
78747893 frames_pending_resources_for_processing = uint32_t(frames.size());