🌋

[Vulkan] Crash Diagnostic Layerを使ってどのCommandでクラッシュしているのかを見る

に公開

はじめに

Vulkan 1.4で追加されたCrash Diagnostic Layerの導入とやってみるとどうなったかの備忘録的なメモです。

Crash Diagnostic Layer

変なシェーダーなどを走らせてしまった結果、Command実行時にクラッシュすることがしばしばありますが、Validation LayerだけではどのCommandがクラッシュしたのかは検知することができません(WarningやErrorはあるかもしれません)。最悪の場合、Device Lostしましたという程度の情報しか出てこないなんてことがあります。

この原因を探すとなるとどのCommandがいけないのか総当たり的に調べる羽目になったりと、中々にキツいことになりがちです。そこでVulkanはversion 1.4から、クラッシュ時にその原因となったCommandの内容とそれらに関係する情報をログとして書き出してくれるCrash Diagnostic Layer(CDL)が追加されました。

CDLの導入

導入自体はシンプルです。Validation layerと同様にInstance生成時にLayerの名前を指定して、有効かするだけです。

m_layers.push_back("VK_LAYER_LUNARG_crash_diagnostic");
~~
vk::InstanceCreateInfo createInfo{};
createInfo.enabledLayerCount = m_layers.size();
createInfo.ppEnabledLayerNames = m_layers.data();

CDLの設定についてはVulkan SDKのbin/vkconfig-gui.exeから見ることができます。もし、Layerを追加してもダメだった場合はこちらで有効になっているかチェックしてみるといいかもしれません。

クラッシュすると

実際にクラッシュすると%USERPROFILE%/cdlにクラッシュログが保存されます。実際にユーザーのところを見るとcdlというフォルダがあり、その中にクラッシュした日時でログが保存されています。

CDLのlogは.yamlファイル形式で書き出されており、中身はこんな感じです。丁度レイトレーシングのシェーダーでクラッシュした事例があったので、それの内容がこれになります。この事例ではレイトレーシングのCommandでクラッシュしており、ログでもそこで止まっている(state: INCOMPLETE)ことが確認できます。

# ----------------------------------------------------------------
# -                    CRASH DIAGNOSTIC LAYER                    -
# ----------------------------------------------------------------

version: 1.4.309
startTime: 2025-04-28 00:34:39
timeSinceStart: 00:00:03.425
Settings:
  output_path: ""
  trace_on: false
  dump_queue_submits: running
  dump_command_buffers: running
  dump_commands: running
  dump_shaders: on_crash
  watchdog_timeout_ms: 30000
  track_semaphores: true
  trace_all_semaphores: false
  instrument_all_commands: false
  sync_after_commands: false
SystemInfo:
  osName: Windows 10 Home
  osVersion: 26100
  osBitdepth: 64-bit
  osAdditional:
    build: ge_release
  cpuName: x64
  numCpus: 28
  totalRam: 31 GB
  totalDiskSpace: 951 GB
  availDiskSpace: 49 GB
Instance:
  handle: 0x0000025C4D155330 []
  applicationInfo:
    application: Hello Triangle
    applicationVersion: 4202496
    engine: No Engine
    engineVersion: 4202496
    apiVersion: 1.4.0 (0x00404000)
  extensions:
    - VK_KHR_surface
    - VK_KHR_win32_surface
    - VK_EXT_debug_utils
    - VK_KHR_portability_enumeration
Device:
  handle: 0x0000025C4FAD1270[]
  deviceName: NVIDIA GeForce RTX 4070 SUPER
  apiVersion: 1.3.280 (0x00403118)
  driverVersion: 0x8C178000 (2350350336)
  vendorID: 0x000010DE
  deviceID: 0x00002783
  extensions:
    - VK_KHR_swapchain
    - VK_KHR_pipeline_library
    - VK_KHR_ray_tracing_pipeline
    - VK_KHR_acceleration_structure
    - VK_KHR_deferred_host_operations
    - VK_KHR_buffer_device_address
  Queues:
    -  # Queue
      handle: 0x0000025C58968960[]
      queueFamilyIndex: 0
      index: 0
      flags:
        - graphics
        - compute
        - transfer
        - sparse
      completedSeq: 21
      submittedSeq: 24
      IncompleteSubmits:
        - type: vkQueueSubmit
          startSeq: 21
          endSeq: 24
          SubmitInfos:
            - startSeq: 21
              endSeq: 24
              state: INCOMPLETE
              CommandBuffers:
                - 0x0000025C5D4F79D0[] INCOMPLETE 23
              WaitSemaphores:
                - handle: 0xCA0B160000000085[]
                  type: Binary
              SignalSemaphores:
                - handle: 0xC079B30000000088[]
                  type: Binary
  CommandBuffers:
    -  # CommandBuffer
      state: INCOMPLETE
      handle: 0x0000025C5D4F79D0[]
      commandPool: 0xCFEF35000000000A[]
      queue: 0x0000025C58968960[]
      fence: 0x0000000000000000[]
      queueSeq: 23
      level: Primary
      simultaneousUse: false
      beginValue: 0x00000001
      endValue: 0x0000FFFF
      topCheckpointValue: 0x00000005
      bottomCheckpointValue: 0x00000003
      lastStartedCommand: 4
      lastCompletedCommand: 2
      Commands:
        -  # Command:
          id: 2
          checkpointValue: 0x00000003
          name: vkCmdBindPipeline
          state: COMPLETED
          parameters:
            pipelineBindPoint: VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR
            pipeline: 0xA182620000000079[]
          message: "'>>>>>>>>>>>>>> LAST COMPLETE COMMAND <<<<<<<<<<<<<<'"
        -  # Command:
          id: 3
          checkpointValue: 0x00000004
          name: vkCmdBindDescriptorSets
          state: INCOMPLETE
          parameters:
            pipelineBindPoint: VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR
            layout: 0x3F36830000000078[]
            firstSet: 0
            descriptorSetCount: 1
            pDescriptorSets:  # VkDescriptorSet
              - 0x5EB05E000000003B[]
            dynamicOffsetCount: 0
            pDynamicOffsets: nullptr
        -  # Command:
          id: 4
          checkpointValue: 0x00000005
          name: vkCmdTraceRaysKHR
          state: INCOMPLETE
          parameters:
            pRaygenShaderBindingTable:
              deviceAddress: 0x00000000193F4000
              stride: 64
              size: 64
            pMissShaderBindingTable:
              deviceAddress: 0x00000000193F4040
              stride: 32
              size: 64
            pHitShaderBindingTable:
              deviceAddress: 0x00000000193F4080
              stride: 32
              size: 64
            pCallableShaderBindingTable:
              deviceAddress: 0x0000000000000000
              stride: 0
              size: 0
            width: 800
            height: 600
            depth: 1
          internalState:
            pipeline:
              {}
            descriptorSets:
              -  # descriptorSet
                index: 0
                set: 0x5EB05E000000003B[]
          message: "'^^^^^^^^^^^^^^ LAST STARTED COMMAND ^^^^^^^^^^^^^^'"

嬉しいことに直接Crashに関係ないResourceの内容だとかCommandの詳細だとかも出してくれるので純粋にValidation Checkにも使えそうです。SBTの内容も書いてあるのは中々にうれしいところです。

終わり

実際にやってみるとCDLはかなりCommand周りの情報を出してくれるのでなかなかに有用な感じがあります。GPUデバッグは本当に大変なのでこうしたデバックの手段が増えてくれるのはありがたい限りです。

ただしCDLは具体的にShaderのinvocationまでは見れないみたいなのでちょっとそこは厳しさを感じます(configにそれっぽいのがあったんですがうまく設定できなかった)。とはいえCommandの特定は直ぐにできそうなので今後とも使っていきたいですね。

Reference

Discussion