Skip to content

Commit 5e7ce33

Browse files
committed
minor: Break out of waiting for debugger on Windows using native debugger check API.
For Windows, this removes the need to add a breakpoint and modify a value to exit the debugger wait loop. As a ridealong, this adds a 100ms sleep for all platforms such that waiting for the debugger doesn't hog the CPU thread.
1 parent 7f45fed commit 5e7ce33

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ vfs.workspace = true
7575
paths.workspace = true
7676

7777
[target.'cfg(windows)'.dependencies]
78-
windows-sys = { version = "0.52", features = ["Win32_System_Threading"] }
78+
windows-sys = { version = "0.52", features = ["Win32_System_Diagnostics_Debug", "Win32_System_Threading"] }
7979

8080
[target.'cfg(not(target_env = "msvc"))'.dependencies]
8181
jemallocator = { version = "0.5.0", package = "tikv-jemallocator", optional = true }

src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern crate rustc_driver as _;
1010

1111
mod rustc_wrapper;
1212

13-
use std::{env, fs, path::PathBuf, process::ExitCode, sync::Arc};
13+
use std::{env, fs, path::PathBuf, process::ExitCode, sync::Arc, thread::sleep};
1414

1515
use anyhow::Context;
1616
use lsp_server::Connection;
@@ -44,11 +44,7 @@ fn actual_main() -> anyhow::Result<ExitCode> {
4444

4545
#[cfg(debug_assertions)]
4646
if flags.wait_dbg || env::var("RA_WAIT_DBG").is_ok() {
47-
#[allow(unused_mut)]
48-
let mut d = 4;
49-
while d == 4 {
50-
d = 4;
51-
}
47+
wait_for_debugger();
5248
}
5349

5450
if let Err(e) = setup_logging(flags.log_file.clone()) {
@@ -96,6 +92,28 @@ fn actual_main() -> anyhow::Result<ExitCode> {
9692
Ok(ExitCode::SUCCESS)
9793
}
9894

95+
#[cfg(debug_assertions)]
96+
fn wait_for_debugger() {
97+
#[cfg(target_os = "windows")]
98+
{
99+
use windows_sys::Win32::System::Diagnostics::Debug::IsDebuggerPresent;
100+
// SAFETY: WinAPI generated code that is defensively marked `unsafe` but
101+
// in practice can not be used in an unsafe way.
102+
while unsafe { IsDebuggerPresent() } == 0 {
103+
sleep(std::time::Duration::from_millis(100));
104+
}
105+
}
106+
#[cfg(not(target_os = "windows"))]
107+
{
108+
#[allow(unused_mut)]
109+
let mut d = 4;
110+
while d == 4 {
111+
d = 4;
112+
sleep(std::time::Duration::from_millis(100));
113+
}
114+
}
115+
}
116+
99117
fn setup_logging(log_file_flag: Option<PathBuf>) -> anyhow::Result<()> {
100118
if cfg!(windows) {
101119
// This is required so that windows finds our pdb that is placed right beside the exe.

0 commit comments

Comments
 (0)