diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 7c8610280b..fb1f0b683d 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -75,7 +75,7 @@ vfs.workspace = true paths.workspace = true [target.'cfg(windows)'.dependencies] -windows-sys = { version = "0.52", features = ["Win32_System_Threading"] } +windows-sys = { version = "0.52", features = ["Win32_System_Diagnostics_Debug", "Win32_System_Threading"] } [target.'cfg(not(target_env = "msvc"))'.dependencies] jemallocator = { version = "0.5.0", package = "tikv-jemallocator", optional = true } diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index a753621eca..caa42dd62c 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -10,7 +10,7 @@ extern crate rustc_driver as _; mod rustc_wrapper; -use std::{env, fs, path::PathBuf, process::ExitCode, sync::Arc}; +use std::{env, fs, path::PathBuf, process::ExitCode, sync::Arc, thread::sleep}; use anyhow::Context; use lsp_server::Connection; @@ -44,11 +44,7 @@ fn actual_main() -> anyhow::Result { #[cfg(debug_assertions)] if flags.wait_dbg || env::var("RA_WAIT_DBG").is_ok() { - #[allow(unused_mut)] - let mut d = 4; - while d == 4 { - d = 4; - } + wait_for_debugger(); } if let Err(e) = setup_logging(flags.log_file.clone()) { @@ -96,6 +92,28 @@ fn actual_main() -> anyhow::Result { Ok(ExitCode::SUCCESS) } +#[cfg(debug_assertions)] +fn wait_for_debugger() { + #[cfg(target_os = "windows")] + { + use windows_sys::Win32::System::Diagnostics::Debug::IsDebuggerPresent; + // SAFETY: WinAPI generated code that is defensively marked `unsafe` but + // in practice can not be used in an unsafe way. + while unsafe { IsDebuggerPresent() } == 0 { + sleep(std::time::Duration::from_millis(100)); + } + } + #[cfg(not(target_os = "windows"))] + { + #[allow(unused_mut)] + let mut d = 4; + while d == 4 { + d = 4; + sleep(std::time::Duration::from_millis(100)); + } + } +} + fn setup_logging(log_file_flag: Option) -> anyhow::Result<()> { if cfg!(windows) { // This is required so that windows finds our pdb that is placed right beside the exe.