c++ 在创建vulkan示例时出现分段错误的原因是什么?

gwbalxhn  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(134)

我正在写一个vulkan驱动的应用程序,我注意到它不工作。我一直在删除代码,直到我达到这个:

#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;                                                                       
}

我使用freebsd 13.2和clang 16.0.6来编译它。我已经安装了vulkan包:
$ 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
在带有调试符号的可执行文件上运行gdb会得到:

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}

我期望成功创建示例。

yruzcnhs

yruzcnhs1#

我认为这是在VkApplicationInfo结构中使用错误宏的简单情况。我不确定VK_VERSION_1_3在您的系统上扩展到什么,因为我只有VK_VERSION_1_2,但只能扩展到1
在我的代码中,我什么也没做,只是用看起来正确的宏替换了那个宏。请注意,我通过运行/usr/bin/vulkaninfo | head并记录输出,获得了要填充宏的正确版本号

Vulkan Instance Version: 1.2.131

你的可能会有所不同。为了完整起见,这是我的代码,它不再segfaults(我在ubuntu上使用的vulkan版本略有不同,因此有额外的头):

#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;
}

编辑注意,似乎你也可以通过执行以下从this answer窃取的操作轻松地以编程方式获得此信息:
通过代码检查(无论是什么语言,只要你有头)可以通过vkGetPhysicalDeviceProperties查询设备属性来完成。VkPhysicalDeviceProperties结构的apiVersion成员包含该设备支持的最高版本。只需移动位或使用来自标题的版本宏来获得humnan可读的版本(major.minor.patch)。

相关问题