Skip to content

Instantly share code, notes, and snippets.

@andmoos
Last active December 17, 2024 02:30
Show Gist options
  • Select an option

  • Save andmoos/f8ea579b66c621822c945d1659cb7457 to your computer and use it in GitHub Desktop.

Select an option

Save andmoos/f8ea579b66c621822c945d1659cb7457 to your computer and use it in GitHub Desktop.
// A minimal example to reproduce a TSAN crash on calling vkCreateDevice on Linux/NVIDIA:
// [...]
// ThreadSanitizer:DEADLYSIGNAL
// ==73756==ERROR: ThreadSanitizer: SEGV on unknown address 0x000000001048 (pc 0x560233ed6b07 bp 0x000000000010 sp 0x7f3ac37fe580 T73757)
// ==73756==The signal is caused by a READ memory access.
// [...]
//
// github issue: https://github.com/google/sanitizers/issues/1678
// nvidia issue: https://developer.nvidia.com/bugs/4470250
// tested on: Arch Linux 2024-01-19 with NVIDIA driver 545.29.06, clang 16.0.6
//
#include <stdio.h>
#include <assert.h>
#include <vulkan/vulkan.h>
#define VK_CHECK_RESULT(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) \
{ \
printf("Fatal : VkResult is %d in %s at line %d\n", res, __FILE__, __LINE__); \
assert(res == VK_SUCCESS); \
} \
}
int main() {
printf("--- Begin\n");
printf("--- vkCreateInstance ... ");
VkApplicationInfo vkApplicationInfo = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pApplicationName = "TSAN issue reprod",
.pEngineName = "TSAN",
.apiVersion = VK_API_VERSION_1_0,
};
VkInstanceCreateInfo vkInstanceCreateInfo = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pApplicationInfo = &vkApplicationInfo,
// .enabledLayerCount = 1, .ppEnabledLayerNames = (const char *[]){"VK_LAYER_KHRONOS_validation"}, // optional
};
VkInstance vkInstance = NULL;
VK_CHECK_RESULT(vkCreateInstance(&vkInstanceCreateInfo, NULL, &vkInstance));
printf("success!\n");
uint32_t physicalDevicesCount = 0;
printf("--- vkEnumeratePhysicalDevices for device count... ");
VK_CHECK_RESULT(vkEnumeratePhysicalDevices(vkInstance, &physicalDevicesCount, NULL));
assert(physicalDevicesCount > 0);
printf("--- vkEnumeratePhysicalDevices for devices... ");
VkPhysicalDevice vkPhysicalDevice[physicalDevicesCount];
VK_CHECK_RESULT(vkEnumeratePhysicalDevices(vkInstance, &physicalDevicesCount, vkPhysicalDevice));
printf("success!\n");
VkDeviceQueueCreateInfo const vkDeviceQueueCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.queueCount = 1,
.queueFamilyIndex = 0,
.pQueuePriorities = (float[]) {0.0f},
};
VkDeviceCreateInfo vkDeviceCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &vkDeviceQueueCreateInfo,
.enabledLayerCount = 0,
.ppEnabledLayerNames = NULL,
};
VkDevice vkDevice = NULL;
printf("--- vkCreateDevice ... ");
VK_CHECK_RESULT(vkCreateDevice(vkPhysicalDevice[0], &vkDeviceCreateInfo, NULL, &vkDevice));
printf("success!\n");
printf("--- vkDestroyDevice ... ");
vkDestroyDevice(vkDevice, NULL);
printf("success!\n");
printf("--- vkDestroyInstance ... ");
vkDestroyInstance(vkInstance, NULL);
printf("success!\n");
printf("--- End\n");
return 0;
}
#!/bin/bash
# compiler selection
CC=clang
CPP=clang++
# cleanup
rm -f tsanissue1678.c.o tsanissue1678.reference tsanissue1678.tsan
# stop on error
set -e
# be verbose
set -x
# compile
${CC} -v -std=c11 -g -O0 -c tsanissue1678.c -o tsanissue1678.c.o
# link two binaries, one with one without TSAN
${CPP} -v -fsanitize=thread -g -fuse-ld=lld -o tsanissue1678.tsan tsanissue1678.c.o -lvulkan
${CPP} -v -fuse-ld=lld -g -o tsanissue1678.reference tsanissue1678.c.o -lvulkan
# run both binaries
./tsanissue1678.reference
./tsanissue1678.tsan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment