Skip to content

[DNM] Add windows logging to find the source of 0xDEAD - #4062

Closed
smalis-msft wants to merge 5 commits into
microsoft:mainfrom
smalis-msft:win-logs
Closed

[DNM] Add windows logging to find the source of 0xDEAD#4062
smalis-msft wants to merge 5 commits into
microsoft:mainfrom
smalis-msft:win-logs

Conversation

@smalis-msft

@smalis-msft smalis-msft commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Adding logging and rerunning CI repeatedly to figure out the source of #71.

Copilot AI review requested due to automatic review settings July 28, 2026 20:17
@smalis-msft
smalis-msft requested a review from a team as a code owner July 28, 2026 20:17
@github-actions github-actions Bot added the unsafe Related to unsafe code label Jul 28, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Unsafe Code Detected

This PR modifies files containing unsafe Rust code. Extra scrutiny is required during review.

For more on why we check whole files, instead of just diffs, check out the Rustonomicon

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds Windows-specific unhandled SEH exception logging so that unexpected process terminations (previously only visible as an exit code) emit minimal diagnostics to stderr, improving debuggability of rare crash scenarios (e.g., issue #71).

Changes:

  • Add pal::windows::log_unhandled_exceptions() that installs a top-level exception filter and writes exception code/address/thread-id to stderr via WriteFile.
  • Call the new logging setup from openvmm_entry::do_main() alongside the existing disable_hard_error_dialog() Windows setup.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
support/pal/src/windows.rs Adds the unhandled exception filter implementation and low-level stderr write.
openvmm/openvmm_entry/src/lib.rs Installs the exception filter early in Windows startup so it applies to the process lifetime.

Comment thread support/pal/src/windows.rs Outdated
Comment thread support/pal/src/windows.rs Outdated
@jstarks

jstarks commented Jul 28, 2026

Copy link
Copy Markdown
Member

I don't think this is a good idea. If there's an unhandled exception then want to stop running code in the process ASAP to minimize the possibility of it turning into an EOP. If we want to get more information about crashes in CI, we should configure the system to save crash dumps.

@smalis-msft

Copy link
Copy Markdown
Contributor Author

I've tried to configure crash dumps in CI before without much success. Maybe I'll just let this spin in CI a few times to see if it catches anything.

@smalis-msft smalis-msft changed the title pal: Add windows unhandled exception logging DNM pal: Add windows unhandled exception logging Jul 28, 2026
@smalis-msft smalis-msft changed the title DNM pal: Add windows unhandled exception logging [DNM] pal: Add windows unhandled exception logging Jul 28, 2026
@github-actions

Copy link
Copy Markdown

@smalis-msft smalis-msft added the release-ci-required Add to a PR to trigger PR gates in release mode label Jul 29, 2026
@github-actions

Copy link
Copy Markdown

@smalis-msft smalis-msft changed the title [DNM] pal: Add windows unhandled exception logging [DNM] Add windows logging to find the source of 0xDEAD Jul 29, 2026
Copilot AI review requested due to automatic review settings July 29, 2026 19:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

support/pal/src/windows.rs:1248

  • log_unexpected_exceptions() registers a vectored exception handler every time it’s called, which can lead to duplicate logging (and extra overhead) if it’s invoked more than once in-process. Consider guarding the registration with Once so the function is idempotent.
    // SAFETY: This Win32 API has no safety requirements.
    unsafe {
        AddVectoredExceptionHandler(1, Some(handler));
    }

support/pal/src/windows.rs:1189

  • The doc comment says “any configured error reporting still runs”, but SetUnhandledExceptionFilter replaces any previously-installed top-level exception filter. That can change crash-reporting behavior for code that had already registered its own filter; consider clarifying this in the docs (or chaining to the previous filter if that’s intended).
/// The filter returns `EXCEPTION_CONTINUE_SEARCH`, so the process still dies
/// exactly as it would have, with the same exit code, and any configured error
/// reporting still runs.

support/pal/src/windows.rs:1206

  • log_unhandled_exceptions() installs a process-global unhandled-exception filter every time it’s called. Since re-installing (and potentially overwriting) global handlers is easy to do accidentally, it’s safer to make this initialization idempotent via Once.

This issue also appears on line 1245 of the same file.

    // SAFETY: This Win32 API has no safety requirements.
    unsafe {
        SetUnhandledExceptionFilter(Some(filter));
    }

Copilot AI review requested due to automatic review settings July 29, 2026 19:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

support/pal/src/windows.rs:1291

  • The WriteFile call passes a *const u8 (out.buf.as_ptr()) where the Win32 binding expects *const c_void. Other WriteFile call sites in the repo use .cast() for this. As written, this is likely a type mismatch that won’t compile (or is inconsistent with the expected signature).
        WriteFile(
            GetStdHandle(STD_ERROR_HANDLE),
            out.buf.as_ptr(),
            out.len as u32,

petri/src/vm/hyperv/powershell.rs:1732

  • host_failure_events queries Application and System with only a StartTime filter and no upper bound. On long-running tests (or chatty hosts), this can produce extremely large outputs and slow post-test hook execution, and Petri currently does not enforce any log size limits. Consider truncating the collected list to a reasonable maximum (keeping the most recent events) to avoid ballooning CI artifacts/timeouts.
/// Get the host event log entries written since `start_time` that could
/// explain a VMM process disappearing without leaving anything in its own
/// logs, such as a fault report or a hypervisor error.
pub async fn host_failure_events(start_time: &Timestamp) -> Vec<WinEvent> {
    let mut events = Vec::new();
    // Query each channel separately so that one missing or inaccessible
    // channel does not suppress the rest.
    for table in [
        APPLICATION_TABLE,
        SYSTEM_TABLE,
        HYPERV_HYPERVISOR_TABLE,
        HYPERV_WORKER_TABLE,
        HYPERV_VMMS_TABLE,
    ] {
        match run_get_winevent(&[table], Some(start_time), None, &[]).await {
            Ok(e) => events.extend(e),
            Err(err) => tracing::warn!(
                table,
                error = err.as_ref() as &dyn std::error::Error,
                "failed to read host event log"
            ),
        }
    }
    events.sort_by_key(|e| e.time_created);
    events
}

@github-actions

Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings July 29, 2026 21:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

support/pal/src/windows.rs:1294

  • WriteFile expects a *const c_void buffer pointer; passing out.buf.as_ptr() without a cast doesn’t match how other Win32 calls in the repo are written and can fail to compile depending on the windows-sys signature. Cast the pointer to c_void (e.g. via .cast()).
        WriteFile(
            GetStdHandle(STD_ERROR_HANDLE),
            out.buf.as_ptr(),
            out.len as u32,
            &mut written,
            null_mut(),
        );

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings July 30, 2026 16:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

support/pal/src/windows.rs:1248

  • log_unexpected_exceptions() installs a new vectored handler every time it’s called and ignores AddVectoredExceptionHandler failure (null return). Since this is a public helper, accidental double-installation can cause duplicate logging and makes diagnostics unreliable if the install fails silently. Consider guarding with Once and asserting (or otherwise surfacing) install failure.
    // SAFETY: This Win32 API has no safety requirements.
    unsafe {
        AddVectoredExceptionHandler(1, Some(handler));
    }

@smalis-msft

Copy link
Copy Markdown
Contributor Author

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

Labels

release-ci-required Add to a PR to trigger PR gates in release mode unsafe Related to unsafe code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants