Skip to content

Fix SIGSEGV on Android startup from null Vulkan surface handle - #221

Merged
winnerspiros merged 1 commit into
masterfrom
copilot/fix-apk-crash-on-start
Apr 20, 2026
Merged

Fix SIGSEGV on Android startup from null Vulkan surface handle#221
winnerspiros merged 1 commit into
masterfrom
copilot/fix-apk-crash-on-start

Conversation

Copilot AI commented Apr 20, 2026

Copy link
Copy Markdown

Android native SurfaceView isn't guaranteed to exist when the SDL thread starts the game loop. AndroidGameWindow.SurfaceHandle returns IntPtr.Zero, which propagates through VeldridDeviceVkSurfaceUtil.createAndroidSurfaceANativeWindow_fromSurface(null) → SIGSEGV at pc=0x0 inside the Vulkan driver.

Changes

Three-layer defense, all in the osu-framework submodule:

  • VeldridDevice.cs — Poll-wait up to 5s for the Android surface handle to become non-zero before creating the swapchain. This is the primary fix; the surface is typically ready within a few hundred ms.
  • VkSurfaceUtil.cs — Null-check ANativeWindow after ANativeWindow_fromSurface and throw a descriptive VeldridException instead of letting the driver SIGSEGV.
  • DrawThread.cs — Wrap initial BeginFrame/FinishFrame in try-catch so the draw loop can defer gracefully if the surface still isn't ready.
// VeldridDevice.cs — core fix
IntPtr surfaceHandle = androidGraphics.SurfaceHandle;

const int max_wait_ms = 5000;
const int poll_interval_ms = 50;
int waited = 0;

while (surfaceHandle == IntPtr.Zero && waited < max_wait_ms)
{
    Thread.Sleep(poll_interval_ms);
    waited += poll_interval_ms;
    surfaceHandle = androidGraphics.SurfaceHandle;
}

if (surfaceHandle == IntPtr.Zero)
    throw new InvalidOperationException("Android surface handle was not available within the timeout period.");

Three-layer defense against null pointer dereference (SIGSEGV at pc=0x0)
when the Android native surface is not yet ready during Vulkan initialization:

1. VeldridDevice.cs: Poll-wait up to 5s for Android surface handle to become
   non-zero before creating Vulkan swapchain
2. VkSurfaceUtil.cs: Guard against null ANativeWindow from ANativeWindow_fromSurface
3. DrawThread.cs: Wrap initial BeginFrame/FinishFrame in try-catch

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
@gitar-bot

gitar-bot Bot commented Apr 20, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

@winnerspiros
winnerspiros marked this pull request as ready for review April 20, 2026 18:10
Copilot AI review requested due to automatic review settings April 20, 2026 18:10
@winnerspiros
winnerspiros merged commit 17bb88f into master Apr 20, 2026
4 of 19 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the osu-framework submodule to incorporate upstream fixes that prevent an Android startup SIGSEGV caused by a null/zero Vulkan surface handle during early window/surface initialization.

Changes:

  • Bump submodules/osu-framework to a commit containing a three-layer mitigation (poll/wait in swapchain creation, native surface null-guard with a managed exception, and draw-thread BeginFrame deferral).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants