KhronosGroup / Vulkan-ValidationLayers

Vulkan Validation Layers (VVL)
https://vulkan.lunarg.com/doc/sdk/latest/linux/khronos_validation_layer.html
Other
761 stars 403 forks source link

Possible leak with validation layers on vkCreateInstance and vkDestroyInstance ? #8408

Closed alfux closed 2 months ago

alfux commented 2 months ago

Environment:

Describe the Issue

When I use debug utils messenger with vkCreateInstance and vkDestroyInstance, I get a memory leak at the end of the program.

Expected behavior

No memory leak.

Additional context

I'm following the Khronos Vulkan Tutorial (https://docs.vulkan.org/tutorial/latest) and I get a memory leak when I check the app with the command leaks --atExit -- ./vulkan_leak_test.

This is a small test program I wrote to reproduce the issue. ```c++ #include #include #include static VKAPI_ATTR VkBool32 VKAPI_CALL callback( VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageTypeFlagsEXT message_types, const VkDebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data ) { switch (message_severity) { case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: std::cerr << "Warning[" << message_types << "]: "; break ; case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: std::cerr << "Error[" << message_types << "]: "; break ; default : std::cerr << "Info[" << message_types << "]: "; } std::cerr << p_callback_data->pMessage << std::endl << std::endl;; (void)p_user_data; return (VK_TRUE); } int main(void) { std::cout << "Start of the test program" << std::endl << std::endl; VkDebugUtilsMessengerCreateInfoEXT debug_info {}; debug_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; debug_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; debug_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; debug_info.pfnUserCallback = callback; std::vector validation_layers {"VK_LAYER_KHRONOS_validation"}; std::vector extensions { VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME }; VkInstanceCreateInfo create_info {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; create_info.enabledExtensionCount = static_cast (extensions.size()); create_info.ppEnabledExtensionNames = extensions.data(); create_info.enabledLayerCount = static_cast (validation_layers.size()); create_info.ppEnabledLayerNames = validation_layers.data(); create_info.pNext = reinterpret_cast (&debug_info); VkInstance instance {}; if (vkCreateInstance(&create_info, nullptr, &instance) != VK_SUCCESS) { std::cerr << "failed instance creation" << std::endl; return (1); } vkDestroyInstance(instance, nullptr); std::cout << "End of the test program" << std::endl; return (0); } ```
This is the makefile I use to compile. ```Makefile SRC := main.cpp OBJ := main.o VULKAND := /Users/alfux/VulkanSDK/1.3.290.0/macOS VULKANL := -L$(VULKAND)/lib -lvulkan -rpath $(VULKAND)/lib VULKANI := -I$(VULKAND)/include CFLAGS += -Wall -Wextra -g -std=c++2b CC := c++ NAME := vulkan_leak_test all : $(NAME) $(NAME) : $(OBJ) $(CC) $(CFLAGS) $(VULKANL) $^ -o $@ %.o : %.cpp $(CC) $(CFLAGS) $(VULKANI) -c $< -o $@ clean : rm -rf $(OBJ) fclean : clean rm -rf $(NAME) re : fclean all .PHONY : all clean fclean re ```
This is the output with the debug utils messenger created. ``` leaks --atExit -- ./vulkan_leak_test vulkan_leak_test(82624) MallocStackLogging: could not tag MSL-related memory as no_footprint, so those pages will be included in process footprint - (null) vulkan_leak_test(82624) MallocStackLogging: recording malloc and VM allocation stacks using lite mode Start of the test program Info[1]: Searching for ICD drivers named ../../../lib/libMoltenVK.dylib Info[1]: Loading layer library /Users/alfux/VulkanSDK/1.3.290.0/macOS/share/vulkan/explicit_layer.d/../../../lib/libVkLayer_khronos_validation.dylib Info[1]: Unloading layer library /Users/alfux/VulkanSDK/1.3.290.0/macOS/share/vulkan/explicit_layer.d/../../../lib/libVkLayer_khronos_validation.dylib End of the test program Process 82624 is not debuggable. Due to security restrictions, leaks can only show or save contents of readonly memory of restricted processes. Process: vulkan_leak_test [82624] Path: /Users/USER/Desktop/*/vulkan_leak_test Load Address: 0x100590000 Identifier: vulkan_leak_test Version: 0 Code Type: ARM64 Platform: macOS Parent Process: leaks [82623] Date/Time: 2024-08-18 19:55:53.225 +0200 Launch Time: 2024-08-18 19:55:52.235 +0200 OS Version: macOS 14.5 (23F79) Report Version: 7 Analysis Tool: /usr/bin/leaks Physical footprint: 11.5M Physical footprint (peak): 11.5M Idle exit: untracked ---- leaks Report Version: 4.0, multi-line stacks Process 82624: 2394 nodes malloced for 385 KB Process 82624: 1 leak for 96 total leaked bytes. STACK OF 1 INSTANCE OF 'ROOT LEAK: ': 11 dyld 0x1926fe0e0 start + 2360 10 vulkan_leak_test 0x1005911d4 main + 400 main.cpp:61 9 libvulkan.1.3.290.dylib 0x100b79440 vkCreateInstance + 988 8 libvulkan.1.3.290.dylib 0x100b73a04 loader_create_instance_chain + 2000 7 libVkLayer_khronos_validation.dylib 0x10c6cb540 vulkan_layer_chassis::CreateInstance(VkInstanceCreateInfo const*, VkAllocationCallbacks const*, VkInstance_T**) + 3388 6 libvulkan.1.3.290.dylib 0x100b70a20 terminator_CreateInstance + 1328 5 libMoltenVK.dylib 0x101aeb4d0 vkCreateInstance + 72 4 libMoltenVK.dylib 0x101b043f4 MVKInstance::MVKInstance(VkInstanceCreateInfo const*) + 228 3 libMoltenVK.dylib 0x101b04a34 MVKInstance::initDebugCallbacks(VkInstanceCreateInfo const*) + 92 2 libMoltenVK.dylib 0x101b03d0c MVKInstance::createDebugUtilsMessenger(VkDebugUtilsMessengerCreateInfoEXT const*, VkAllocationCallbacks const*) + 52 1 libc++abi.dylib 0x192a3fbd4 operator new(unsigned long) + 32 0 libsystem_malloc.dylib 0x1928c0a68 _malloc_zone_malloc_instrumented_or_legacy + 148 ==== 1 (96 bytes) ROOT LEAK: [96] Binary Images: 0x100590000 - 0x100593fff +vulkan_leak_test (0) <4B4AF056-D230-35DA-8214-44DB072D0471> /Users/*/Desktop/*/vulkan_leak_test ... 0x25aefa000 - 0x25aefdffb libsystem_sanitizers.dylib (8) /usr/lib/system/libsystem_sanitizers.dylib ```
And this is the output without the debug utils messenger. ```c++ create_info.pNext = nullptr; ``` Output: ``` leaks --atExit -- ./vulkan_leak_test vulkan_leak_test(82667) MallocStackLogging: could not tag MSL-related memory as no_footprint, so those pages will be included in process footprint - (null) vulkan_leak_test(82667) MallocStackLogging: recording malloc and VM allocation stacks using lite mode Start of the test program End of the test program Process 82667 is not debuggable. Due to security restrictions, leaks can only show or save contents of readonly memory of restricted processes. Process: vulkan_leak_test [82667] Path: /Users/USER/Desktop/*/vulkan_leak_test Load Address: 0x104ebc000 Identifier: vulkan_leak_test Version: 0 Code Type: ARM64 Platform: macOS Parent Process: leaks [82666] Date/Time: 2024-08-18 19:57:29.309 +0200 Launch Time: 2024-08-18 19:57:28.935 +0200 OS Version: macOS 14.5 (23F79) Report Version: 7 Analysis Tool: /usr/bin/leaks Physical footprint: 11.5M Physical footprint (peak): 11.5M Idle exit: untracked ---- leaks Report Version: 4.0, multi-line stacks Process 82667: 2393 nodes malloced for 385 KB Process 82667: 0 leaks for 0 total leaked bytes. ```

I apologize if the issue is on my end, I'm just starting to learn Vulkan, but as I don't see any handle to this feature I don't know if I can or should free the memory myself as with the debug utils messenger we get with vkCreateDebugUtilsMessengerEXT and destroy with vkDestroyDebugUtilsMessengerEXT. The Khronos Vulkan tutorial seems to suggest vkDestroyInstance should clean up the debug utils messenger at the end of this section: https://docs.vulkan.org/tutorial/latest/03_Drawing_a_triangle/00_Setup/02_Validation_layers.html#_debugging_instance_creation_and_destruction

spencer-lunarg commented 2 months ago

There is a good chance this is because of something MoltenVK is doing @aitor-lunarg could you help take a quick look at this or know anything around this

aitor-lunarg commented 2 months ago

The PR above should address the issue. I've yet to test the set up locally myself (I will get to it later during the day), but I'm confident that's the issue.

billhollings commented 2 months ago

Environment:

  • OS: macOS Sonoma 14.5
  • GPU and driver version: Apple M2
  • SDK or header version if building from repo: 1.3.290.0
  • Options enabled (synchronization, best practices, etc.): Nothing (I think?)

Describe the Issue

When I use debug utils messenger with vkCreateInstance and vkDestroyInstance, I get a memory leak at the end of the program.

Expected behavior

No memory leak.

Additional context

I'm following the Khronos Vulkan Tutorial (https://docs.vulkan.org/tutorial/latest) and I get a memory leak when I check the app with the command leaks --atExit -- ./vulkan_leak_test.

This is a small test program I wrote to reproduce the issue. This is the makefile I use to compile. This is the output with the debug utils messenger created. And this is the output without the debug utils messenger.

Thanks for submitting such complete info, and a replicable sample! That helps enormously in tracking down issues!

spencer-lunarg commented 2 months ago

@alfux can we close this issue now?

alfux commented 2 months ago

@spencer-lunarg Yes of course ! Thanks for the fix !