mirror of
https://github.com/openharmony/third_party_vulkan-loader.git
synced 2026-07-20 20:15:56 -04:00
Fix crashes from OOM in vkDestroyInstance
Various situations could cause an OOM to turn into a hard crash due to double freeing of memory that was improperly cleaned up. Also fixed memory leaks when layers would report OOM.
This commit is contained in:
committed by
Charles Giessen
parent
4f6ccc2f2f
commit
c129609717
@@ -355,6 +355,14 @@ TEST(Allocation, DeviceButNotInstance) {
|
||||
FrameworkEnvironment env{};
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
|
||||
const char* layer_name = "VkLayerImplicit0";
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name(layer_name)
|
||||
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
|
||||
.set_disable_environment("DISABLE_ENV")),
|
||||
"test_layer.json");
|
||||
env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
|
||||
|
||||
MemoryTracker tracker;
|
||||
{
|
||||
auto& driver = env.get_test_icd();
|
||||
@@ -403,6 +411,14 @@ TEST(Allocation, CreateInstanceIntentionalAllocFail) {
|
||||
FrameworkEnvironment env{};
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
|
||||
const char* layer_name = "VkLayerImplicit0";
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name(layer_name)
|
||||
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
|
||||
.set_disable_environment("DISABLE_ENV")),
|
||||
"test_layer.json");
|
||||
env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
|
||||
|
||||
size_t fail_index = 0;
|
||||
VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
while (result == VK_ERROR_OUT_OF_HOST_MEMORY && fail_index <= 10000) {
|
||||
@@ -433,6 +449,14 @@ TEST(Allocation, CreateDeviceIntentionalAllocFail) {
|
||||
driver.physical_devices.emplace_back("physical_device_1");
|
||||
driver.physical_devices[1].add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false});
|
||||
|
||||
const char* layer_name = "VkLayerImplicit0";
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name(layer_name)
|
||||
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
|
||||
.set_disable_environment("DISABLE_ENV")),
|
||||
"test_layer.json");
|
||||
env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.CheckCreate();
|
||||
|
||||
@@ -488,6 +512,14 @@ TEST(Allocation, CreateInstanceDeviceIntentionalAllocFail) {
|
||||
driver.physical_devices.emplace_back("physical_device_0");
|
||||
driver.physical_devices[0].add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false});
|
||||
|
||||
const char* layer_name = "VkLayerImplicit0";
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name(layer_name)
|
||||
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
|
||||
.set_disable_environment("DISABLE_ENV")),
|
||||
"test_layer.json");
|
||||
env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
|
||||
|
||||
size_t fail_index = 0;
|
||||
VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
while (result == VK_ERROR_OUT_OF_HOST_MEMORY && fail_index <= 10000) {
|
||||
@@ -556,6 +588,15 @@ TEST(TryLoadWrongBinaries, CreateInstanceIntentionalAllocFail) {
|
||||
FrameworkEnvironment env{};
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
env.add_icd(TestICDDetails(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE).set_is_fake(true));
|
||||
|
||||
const char* layer_name = "VkLayerImplicit0";
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name(layer_name)
|
||||
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
|
||||
.set_disable_environment("DISABLE_ENV")),
|
||||
"test_layer.json");
|
||||
env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
|
||||
|
||||
size_t fail_index = 0;
|
||||
VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
while (result == VK_ERROR_OUT_OF_HOST_MEMORY && fail_index <= 10000) {
|
||||
@@ -579,6 +620,14 @@ TEST(Allocation, EnumeratePhysicalDevicesIntentionalAllocFail) {
|
||||
FrameworkEnvironment env{};
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
|
||||
const char* layer_name = "VkLayerImplicit0";
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name(layer_name)
|
||||
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
|
||||
.set_disable_environment("DISABLE_ENV")),
|
||||
"test_layer.json");
|
||||
env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
|
||||
|
||||
size_t fail_index = 0;
|
||||
bool reached_the_end = false;
|
||||
uint32_t starting_physical_dev_count = 3;
|
||||
@@ -612,6 +661,7 @@ TEST(Allocation, EnumeratePhysicalDevicesIntentionalAllocFail) {
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(physical_dev_count));
|
||||
driver.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false});
|
||||
physical_dev_count += 1;
|
||||
}
|
||||
|
||||
@@ -639,7 +689,33 @@ TEST(Allocation, EnumeratePhysicalDevicesIntentionalAllocFail) {
|
||||
}
|
||||
ASSERT_EQ(physical_dev_count, returned_physical_count);
|
||||
|
||||
std::cout << "fail count " << fail_index << "\n";
|
||||
std::array<VkDevice, 3> devices;
|
||||
for (uint32_t i = 0; i < returned_physical_count; i++) {
|
||||
uint32_t family_count = 1;
|
||||
uint32_t returned_family_count = 0;
|
||||
env.vulkan_functions.vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &returned_family_count, nullptr);
|
||||
ASSERT_EQ(returned_family_count, family_count);
|
||||
|
||||
VkQueueFamilyProperties family;
|
||||
env.vulkan_functions.vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &returned_family_count, &family);
|
||||
ASSERT_EQ(returned_family_count, family_count);
|
||||
ASSERT_EQ(family.queueFlags, static_cast<VkQueueFlags>(VK_QUEUE_GRAPHICS_BIT));
|
||||
ASSERT_EQ(family.queueCount, family_count);
|
||||
ASSERT_EQ(family.timestampValidBits, 0U);
|
||||
|
||||
DeviceCreateInfo dev_create_info;
|
||||
DeviceQueueCreateInfo queue_info;
|
||||
queue_info.add_priority(0.0f);
|
||||
dev_create_info.add_device_queue(queue_info);
|
||||
|
||||
result = env.vulkan_functions.vkCreateDevice(physical_devices[i], dev_create_info.get(), tracker.get(), &devices[i]);
|
||||
}
|
||||
for (uint32_t i = 0; i < returned_physical_count; i++) {
|
||||
if (result == VK_SUCCESS) {
|
||||
env.vulkan_functions.vkDestroyDevice(devices[i], tracker.get());
|
||||
}
|
||||
}
|
||||
|
||||
env.vulkan_functions.vkDestroyInstance(instance, tracker.get());
|
||||
ASSERT_TRUE(tracker.empty());
|
||||
reached_the_end = true;
|
||||
@@ -659,6 +735,14 @@ TEST(Allocation, CreateInstanceDeviceWithDXGIDriverIntentionalAllocFail) {
|
||||
driver.physical_devices[0].add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false});
|
||||
}
|
||||
|
||||
const char* layer_name = "VkLayerImplicit0";
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name(layer_name)
|
||||
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
|
||||
.set_disable_environment("DISABLE_ENV")),
|
||||
"test_layer.json");
|
||||
env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
|
||||
|
||||
auto& known_driver = known_driver_list.at(2); // which drive this test pretends to be
|
||||
DXGI_ADAPTER_DESC1 desc1{};
|
||||
desc1.VendorId = known_driver.vendor_id;
|
||||
@@ -721,9 +805,12 @@ TEST(Allocation, CreateInstanceDeviceWithDXGIDriverIntentionalAllocFail) {
|
||||
dev_create_info.add_device_queue(queue_info);
|
||||
|
||||
result = env.vulkan_functions.vkCreateDevice(physical_devices[i], dev_create_info.get(), tracker.get(), &devices[i]);
|
||||
if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
|
||||
devices[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < returned_physical_count; i++) {
|
||||
if (result == VK_SUCCESS) {
|
||||
if (devices[i] != VK_NULL_HANDLE) {
|
||||
env.vulkan_functions.vkDestroyDevice(devices[i], tracker.get());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user