Skip to content

Fix steam.exe crash (Access Violation 0xc0000005) during SteamVR exit#3331

Open
Roboct424 wants to merge 7 commits into
alvr-org:masterfrom
Roboct424:patch-3
Open

Fix steam.exe crash (Access Violation 0xc0000005) during SteamVR exit#3331
Roboct424 wants to merge 7 commits into
alvr-org:masterfrom
Roboct424:patch-3

Conversation

@Roboct424

@Roboct424 Roboct424 commented Jul 2, 2026

Copy link
Copy Markdown

Fix steam.exe crash (Access Violation 0xc0000005) during SteamVR exit

Description

This PR addresses a severe race condition during the driver shutdown sequence on Windows environments. When SteamVR exits, it calls shutdown_driver() and immediately unloads driver_alvr_server.dll via FreeLibrary. However, background worker threads (specifically from the Tokio execution pool and asynchronous telemetry routines) often remain active for a few milliseconds longer. When they awake into unmapped memory addresses, a hard crash occurs inside steam.exe.

Changes made:

  • Fixed Clippy nested if warnings in alvr/server_openvr/src/lib.rs.
  • Wrapped raw pointer dereferencing (*return_code = 101) into an explicit unsafe block.
  • Fixed formatting to satisfy cargo fmt --check.
  • Documented code modifications in English.

⚠️ AI Disclaimer / Note to Reviewers

Please review this PR with extra care. This patch was authored with the assistance of Gemini LLM. I (the submitter) am not an expert in the ALVR codebase, but this solution successfully passes both compilation (cargo clippy --ci) and code formatting (cargo fmt).

Roboct424 added 5 commits July 2, 2026 14:08
О, классика! Ошибки синтаксиса в коде не дают Clippy (линтеру Rust) завершить проверку. Флаг `--ci` заставляет сборщик паниковать (`thread 'main' panicked...`) при наличии абсолютно любых предупреждений, расценивая их как критические ошибки сборки. Это стандартная практика на GitHub Actions, чтобы в репозиторий не попадал «грязный» код.

Смотри, сборка падает из-за трех предупреждений в файле `alvr\server_openvr\src\lib.rs`. Давай разберем каждое и починим их.

---

### Шаг 1: Неиспользуемый импорт (`unused_imports`)

В строке 34 импортируется `c_char`, который дальше нигде в коде не вызывается.
**Как исправить:** Открой файл `alvr\server_openvr\src\lib.rs`, найди строку 34 и просто удали `c_char` из списка импорта:

```rust
// Было:
ffi::{CString, OsStr, c_char, c_void},

// Стало:
ffi::{CString, OsStr, c_void},

```

---

### Шаг 2: Разыменование сырого указателя (`unsafe_op_in_unsafe_fn`)

В редакции Rust 2024 (и соответствующих свежих версиях компилятора) правила ужесточились: то, что функция помечена как `unsafe`, больше не делает её тело автоматически безопасным для работы с сырыми указателями. Разыменование `*return_code` в строке 678 обязано быть внутри явного блока `unsafe {}`.

**Как исправить:** Найди функцию `HmdDriverFactory` (примерно строка 669) и оберни разыменование в `unsafe`:

```rust
// Было:
if !return_code.is_null() {
    *return_code = 101; 
}

// Стало:
if !return_code.is_null() {
    unsafe {
        *return_code = 101; // Переносим под строгий контроль компилятора
    }
}

```

---

### Шаг 3: Схлопывание вложенных `if` (`collapsible_if`)

Линтер ругается на «лесенку» из `if let` и `if`. Их можно (и нужно для красоты) объединить в один логический блок с помощью оператора `&&`.

**Как исправить:** Замени конструкцию со строки 674 по 683 на лаконичный вариант:

```rust
// Было:
if let Ok(exe_path) = std::env::current_exe() {
    if let Some(file_name) = exe_path.file_name() {
        if file_name.to_string_lossy().to_lowercase() == "steam.exe" {
            // ...
        }
    }
}

// Стало:
if let Ok(exe_path) = std::env::current_exe()
    && let Some(file_name) = exe_path.file_name()
    && file_name.to_string_lossy().to_lowercase() == "steam.exe"
{
    if !return_code.is_null() {
        unsafe { *return_code = 101; }
    }
    return std::ptr::null_mut();
}

```

*(Примечание: Если компилятор начнет ругаться на то, что `&& let` в выражениях еще не стабилизирован в твоей версии Rust, можно использовать классический синтаксис `match` или вытащить условия через промежуточные переменные).*

---

Как только ты поправишь эти три места в `alvr\server_openvr\src\lib.rs` и перезапустишь `cargo xtask clippy --ci`, проверка должна успешно пройти зелёным цветом как на Windows, так и на Linux!
…Rust 2024 standards

NOTICE / DISCLAIMER:
This specific block of code was modified/generated with the assistance of an AI (Gemini LLM model). The human author contributor does not deeply understand the inner workings of this specific codebase and relies on the AI's patch to fix the underlying issue. Please review carefully during PR.
@Roboct424 Roboct424 changed the title Update lib.rs Fix steam.exe crash (Access Violation 0xc0000005) during SteamVR exit Jul 2, 2026
@Roboct424

Copy link
Copy Markdown
Author

I tested the branch on my system, and it launched without any issues. Steam no longer crashes when exiting SteamVR. As you can probably tell, I’m a complete novice at this kind of programming; I had help from an AI, and I’m hugely grateful to it. Unfortunately, though, the Desktop+ add-on still isn't working—its interface simply won't appear no matter what I do, yet it doesn't throw any errors. So, there's that...

@Roboct424

Copy link
Copy Markdown
Author

If you want to try out what I've built, here is a link to the dev versions for this branch: https://drive.google.com/drive/folders/19eZmMOXpU0NlYh6I9c--kzd3fGCWvKSw?usp=sharing

@zmerp

zmerp commented Jul 6, 2026

Copy link
Copy Markdown
Member

The fix is being addressed more extensively in #3333 and I'm inclined to accept that one as the fix. this PR though removes the conditional webserver_runtime destruction on linux. ideally we don't want to keep the cfg gate, but have you tested on linux?

@Roboct424

Copy link
Copy Markdown
Author

At the moment, I don't have the ability to test the build on Linux; I'll ask my colleagues to check it when they have time.

@besauce

besauce commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

The fix is being addressed more extensively in #3333 and I'm inclined to accept that one as the fix. this PR though removes the conditional webserver_runtime destruction on linux. ideally we don't want to keep the cfg gate, but have you tested on linux?

I think runtime.shutdown_timeout(Duration::from_secs(1)) instead of a plain drop would bound the wait and probably allow the gate removal. if anyone on linux hits the hang while testing the gate removal, sudo gdb -p $(pidof vrserver) -batch -ex "thread apply all bt" while it's hung should show the real cause. I can put up a PR with the shutdown_timeout approach if that's useful.

@zmerp

zmerp commented Jul 9, 2026

Copy link
Copy Markdown
Member

Sure thank you

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