Skip to content

Commit

Permalink
minor: Break out of waiting for debugger on Windows using native debu…
Browse files Browse the repository at this point in the history
…gger 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.
  • Loading branch information
PrototypeNM1 committed Dec 23, 2024
1 parent 7f45fed commit 5e7ce33
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
30 changes: 24 additions & 6 deletions src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -44,11 +44,7 @@ fn actual_main() -> anyhow::Result<ExitCode> {

#[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()) {
Expand Down Expand Up @@ -96,6 +92,28 @@ fn actual_main() -> anyhow::Result<ExitCode> {
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<PathBuf>) -> anyhow::Result<()> {
if cfg!(windows) {
// This is required so that windows finds our pdb that is placed right beside the exe.
Expand Down

0 comments on commit 5e7ce33

Please sign in to comment.