Skip to content

Structured Exception Handling in WinUI apps #10635

@jpnurmi

Description

@jpnurmi

Describe the bug

The main WinUI thread interferes with Structured Exception Handling.

A top-level unhandled exception filter doesn't get called, no matter whether it's set as early as possible (on startup in App constructor or DllMain), or as late as possible (immediately before triggering a test crash).

LONG WINAPI HandleGlobalException(EXCEPTION_POINTERS* exceptionInfo) {
    OutputDebugString(L"HandleGlobalException\n");
    return EXCEPTION_CONTINUE_SEARCH;
}

void TriggerCrash()
{
    volatile int* pInt = 0x00000000;
    *pInt = 20;
}

void winrt::BlankApp::implementation::MainWindow::OnButtonClick(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
    LPTOP_LEVEL_EXCEPTION_FILTER lpOldFilter = SetUnhandledExceptionFilter(&HandleGlobalException);

    TriggerCrash(); // HandleGlobalException does not get called

    SetUnhandledExceptionFilter(lpOldFilter);
}

Steps to reproduce the bug

  1. Create a new Visual Studio C++ project: WinUI Blank App
  2. Install a top-level Unhandled Exception Filter
  3. Start without debugging
  4. Trigger a crash

Expected behavior

The Unhandled Exception Filter gets called.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.7.3: 1.7.250606001

Windows version

Windows 11 (24H2): Build 26100

Additional context

Originates from:

Additional notes:

  • Manually wrapping TriggerCrash() with __try and __except does work, but does not help a generic crash handler much :)
    __try {
        TriggerCrash(); // HandleLocalException does get called
    }
    __except (HandleLocalException(GetExceptionInformation())) {
    }
  • The filter does get called if a crash is triggered from a worker thread:
    std::thread([]() {
        LPTOP_LEVEL_EXCEPTION_FILTER lpOldFilter = SetUnhandledExceptionFilter(&HandleGlobalException);
    
        TriggerCrash(); // HandleGlobalException does get called
    
        SetUnhandledExceptionFilter(lpOldFilter);
    }).join();

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds-triageIssue needs to be triaged by the area owners

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions