What is the cause of the segmentation fault during the vulkan instance creation?

454 Views Asked by At

I am writing a vulkan powered app, and I noticed it wasn't working. I kept on removing code until i reached this:

#include <vulkan/vulkan.h>                                                        
#include <iostream>                                                               
                                                                                  
int main()                                                                        
{                                                                                 
  VkApplicationInfo info{};                                                       
  info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;                                
  info.pNext = nullptr;                                                           
  info.apiVersion = VK_VERSION_1_3;                                               
  info.applicationVersion = 1;                                                    
  info.engineVersion = 0;                                                         
  info.pApplicationName = "App";                                                  
  info.pEngineName = nullptr;                                                     
                                                                                  
  VkInstanceCreateInfo instanceInfo{};                                            
  instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;                    
  instanceInfo.pNext = nullptr;                                                   
  instanceInfo.flags = 0;                                                         
  instanceInfo.enabledExtensionCount = 0;                                         
  instanceInfo.enabledLayerCount = 0;                                             
  instanceInfo.ppEnabledExtensionNames = nullptr;                                 
  instanceInfo.ppEnabledLayerNames = nullptr;                                     
  instanceInfo.pApplicationInfo = &info;                                          
                                                                                  
  VkInstance instance;                                                            
  auto code = vkCreateInstance(&instanceInfo, nullptr, &instance);                
                                                                                  
  if (code != VK_SUCCESS)                                                         
  {                                                                               
    std::cout << "failed to create instance" << std::endl;                        
    return -1;                                                                    
  }                                                                               
  else vkDestroyInstance(instance, nullptr);                                      
  return 0;                                                                       
}                                     

I am using freebsd 13.2 with clang 16.0.6 to compile this. I have installed the vulkan packages:

$ pkg info vulkan*
vulkan-caps-viewer-3.31 vulkan-extension-layer-1.3.254 vulkan-headers-1.3.254 vulkan-loader-1.3.254 vulkan-tools-1.3.254 vulkan-validation-layers-1.3.254

Running gdb on the executable with debugging symbols gives:

Program received signal SIGSEGV, Segmentation fault.
Address not mapped to object.
0x0000000800595300 in ?? () from /lib/libc.so.7
(gdb) backtrace
#0  0x0000000800595300 in ?? () from /lib/libc.so.7
#1  0x00000008005a04b6 in vsnprintf () from /lib/libc.so.7
#2  0x00000008002e3dec in ?? () from /usr/local/lib/libvulkan.so.1
#3  0x00000008002c1278 in ?? () from /usr/local/lib/libvulkan.so.1
#4  0x00000008002ded9f in ?? () from /usr/local/lib/libvulkan.so.1
#5  0x00000008002e1579 in ?? () from /usr/local/lib/libvulkan.so.1
#6  0x00000008002e7ca6 in vkCreateInstance () from /usr/local/lib/libvulkan.so.1
#7  0x000000000020b569 in main () at /home/chris/projects/freestick/src/main.cpp:26
(gdb) frame 7
#7  0x000000000020b569 in main () at /home/chris/projects/freestick/src/main.cpp:26
26    auto code = vkCreateInstance(&instanceInfo, nullptr, &instance);
(gdb) p instanceInfo
$1 = {sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, pNext = 0x0, flags = 0, pApplicationInfo = 0x7fffffffe6f8, enabledLayerCount = 0, 
  ppEnabledLayerNames = 0x0, enabledExtensionCount = 0, ppEnabledExtensionNames = 0x0}

I expected the instance to get created successfully.

1

There are 1 best solutions below

2
Douglas B On BEST ANSWER

I think its a simple case of using the wrong macro in your VkApplicationInfo struct. I am not sure what VK_VERSION_1_3 expands to on your system as I only have VK_VERSION_1_2, but that only expands to 1.

In my code here, I have done nothing but replace that macro with the seemingly correct macro. Note that I obtained the correct version numbers to fill the macro with by running /usr/bin/vulkaninfo | head and noting the output

Vulkan Instance Version: 1.2.131

And yours will likely be different. For completeness, this is the code I have which no longer segfaults (I am on ubuntu with a slightly different version of vulkan, hence the extra headers):

#include <iostream>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>
#include <vulkan/vulkan.hpp>

int main(){
  VkApplicationInfo info{};
  info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  info.pNext = nullptr;
  info.apiVersion = VK_MAKE_VERSION(1, 2, 131);
  info.applicationVersion = 1;
  info.engineVersion = 0;
  info.pApplicationName = "App";
  info.pEngineName = nullptr;

  VkInstanceCreateInfo instanceInfo{};
  instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  instanceInfo.pNext = nullptr;
  instanceInfo.flags = 0;
  instanceInfo.enabledExtensionCount = 0;
  instanceInfo.enabledLayerCount = 0;
  instanceInfo.ppEnabledExtensionNames = nullptr;
  instanceInfo.ppEnabledLayerNames = nullptr;
  instanceInfo.pApplicationInfo = &info;

  VkInstance instance;
  auto code = vkCreateInstance(&instanceInfo, nullptr, &instance);

  if (code != VK_SUCCESS){
    std::cout << "failed to create instance" << std::endl;
    return -1;
  } else vkDestroyInstance(instance, nullptr);
  return 0;
}

Editing to note that it seems like you could also easily get this information programatically by doing the following, stolen from this answer:

Checking via code (no matter what language, as long as you got headers) can be done by querying device properties via vkGetPhysicalDeviceProperties. The apiVersion member of the VkPhysicalDeviceProperties struct contains the maximum supported version for that device. Just shift the bits or use the version macros from the headers to get a humnan readable version (major.minor.patch).