wolfpld / tracy

Frame profiler
https://tracy.nereid.pl/
Other
9.89k stars 658 forks source link

Memory: active allocations are incorrectly displayed in call stack tree (swapped?) #723

Closed idbrii closed 7 months ago

idbrii commented 7 months ago

These checkboxes in the Memory window's call stack tree for "Only active allocations" and "Only inactive allocations" don't work correctly:

image

I'm using tracy v0.10 37aff70dfa50cf6307b3fee6074d627dc2929143.

My expectations:

I was trying to investigate memory and what tracy was showing me didn't make sense. Eventually, I realized that the way it categorized allocations was incorrect. If I made a simple application with a button to free + allocate, then clicking that button shows ever increasing values under "Only active allocations" but most of those allocations are inactive. I think the checkbox labels are just swapped, but I'm not certain.

Repro:

  1. Run build_win32.bat to build and run
  2. Attach Tracy
  3. Click "Free + Allocate" once
  4. Tracy shows 2 entries under "Active allocations" but 0 active allocations in the call stack tree after one allocation
  5. Tracy shows 1 inactive allocation in the call stack tree, but that's actually our active allocation
  6. Click "Free + Allocate" several times
  7. Tracy shows many KB of active allocations in the call stack tree, but only one KB inactive

Here's a simple repro program. Using imgui's example_win32_directx12 as a base, this patch integrates tracy and adds some buttons to allocate. It expects a clone of tracy next to the imgui folder.

diff --git a/examples/example_win32_directx12/build_win32.bat b/examples/example_win32_directx12/build_win32.bat
index 68e3c921..9c7af00c 100644
--- a/examples/example_win32_directx12/build_win32.bat
+++ b/examples/example_win32_directx12/build_win32.bat
@@ -1,9 +1,16 @@
+call "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\vcvars64.bat" x64 >NUL
+
+pushd %~dp0
+
 @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
 @REM Important: to build on 32-bit systems, the DX12 backends needs '#define ImTextureID ImU64', so we pass it here.
 @set OUT_DIR=Debug
 @set OUT_EXE=example_win32_directx12
-@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared"
-@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp
+@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I..\..\..\tracy\public
+@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp ..\..\..\tracy\public\TracyClient.cpp
 @set LIBS=d3d12.lib d3dcompiler.lib dxgi.lib
 mkdir Debug
-cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
+cl /nologo /Zi /MD /utf-8 %INCLUDES% /D TRACY_ENABLE /D TRACY_CALLSTACK /D ImTextureID=ImU64 /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
+
+
+call Debug\example_win32_directx12.exe
diff --git a/examples/example_win32_directx12/main.cpp b/examples/example_win32_directx12/main.cpp
index b146129e..5318f9ca 100644
--- a/examples/example_win32_directx12/main.cpp
+++ b/examples/example_win32_directx12/main.cpp
@@ -60,6 +60,20 @@ void WaitForLastSubmittedFrame();
 FrameContext* WaitForNextFrameResources();
 LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

+#include "tracy/Tracy.hpp"
+void* operator new(std::size_t count)
+{
+    auto ptr = malloc(count);
+    TracyAlloc(ptr, count);
+    return ptr;
+}
+void operator delete(void* ptr) noexcept
+{
+    TracyFree(ptr);
+    free(ptr);
+}
+
+
 // Main code
 int main(int, char**)
 {
@@ -153,6 +167,27 @@ int main(int, char**)

             ImGui::Begin("Hello, world!");                          // Create a window called "Hello, world!" and append into it.

+            {
+                ZoneScopedNS("Buttons", 10);
+
+                static char* data = nullptr;
+
+                if (ImGui::Button("Allocate")) {
+                    data = new char[1024];
+                }
+
+                if (ImGui::Button("Free")) {
+                    delete[] data;
+                    data = nullptr;
+                }
+
+                if (ImGui::Button("Free + Allocate")) {
+                    delete[] data;
+                    data = new char[1024];
+                }
+            }
+
+
             ImGui::Text("This is some useful text.");               // Display some text (you can use a format strings too)
             ImGui::Checkbox("Demo Window", &show_demo_window);      // Edit bools storing our window open/close state
             ImGui::Checkbox("Another Window", &show_another_window);

Thanks this great profiler and making it open source!

wolfpld commented 7 months ago

Yeah, looks to be so. This is the test application:

obraz