From 7959d600c16850c13c343f693fce42b811128f15 Mon Sep 17 00:00:00 2001 From: G36maid Date: Fri, 1 May 2026 12:21:13 +0800 Subject: [PATCH 1/5] Add FreeBSD support for remote_server Gate crash-handler and minidumper behind cfg(not(target_os = "freebsd")) since neither crate supports FreeBSD. Provide no-op stubs in the crashes crate so remote_server compiles and links without them. Add target_os = "freebsd" to gpui queue module cfg gates (same POSIX APIs as Linux). Fix MaybeUninit usage in fs::current_path() for FreeBSD: use zeroed() and assume_init_mut() instead of uninit() + as_mut_ptr() which is UB when accessing fields of uninitialized memory. Release Notes: - N/A --- Cargo.lock | 4 +++ crates/crashes/Cargo.toml | 14 +++++--- crates/crashes/src/crashes_freebsd.rs | 33 +++++++++++++++++++ .../src/{crashes.rs => crashes_full.rs} | 0 crates/crashes/src/lib.rs | 11 +++++++ crates/fs/src/fs.rs | 9 ++--- crates/gpui/src/gpui.rs | 4 +-- crates/remote_server/Cargo.toml | 6 ++-- 8 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 crates/crashes/src/crashes_freebsd.rs rename crates/crashes/src/{crashes.rs => crashes_full.rs} (100%) create mode 100644 crates/crashes/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ea316675240..1ebe585c4cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4144,11 +4144,15 @@ name = "crashes" version = "0.1.0" dependencies = [ "async-process", + "cfg-if", "crash-handler", + "futures 0.3.32", "log", "mach2 0.5.0", "minidumper", "parking_lot", + "paths", + "release_channel", "serde", "serde_json", "system_specs", diff --git a/crates/crashes/Cargo.toml b/crates/crashes/Cargo.toml index f8b898112c1..c652d34d484 100644 --- a/crates/crashes/Cargo.toml +++ b/crates/crashes/Cargo.toml @@ -6,13 +6,19 @@ edition.workspace = true license = "GPL-3.0-or-later" [dependencies] -async-process.workspace = true -crash-handler.workspace = true +cfg-if.workspace = true +futures.workspace = true log.workspace = true -minidumper.workspace = true parking_lot.workspace = true +release_channel.workspace = true serde.workspace = true serde_json.workspace = true + +[target.'cfg(not(target_os = "freebsd"))'.dependencies] +async-process.workspace = true +crash-handler.workspace = true +minidumper.workspace = true +paths.workspace = true system_specs.workspace = true zstd.workspace = true @@ -26,4 +32,4 @@ windows.workspace = true workspace = true [lib] -path = "src/crashes.rs" +path = "src/lib.rs" diff --git a/crates/crashes/src/crashes_freebsd.rs b/crates/crashes/src/crashes_freebsd.rs new file mode 100644 index 00000000000..907d26550df --- /dev/null +++ b/crates/crashes/src/crashes_freebsd.rs @@ -0,0 +1,33 @@ +use std::future::Future; +use std::path::Path; + +use futures::future::BoxFuture; +use serde::{Deserialize, Serialize}; + +pub static REQUESTED_MINIDUMP: std::sync::atomic::AtomicBool = + std::sync::atomic::AtomicBool::new(false); + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct InitCrashHandler { + pub session_id: String, + pub zed_version: String, + pub binary: String, + pub release_channel: String, + pub commit_sha: String, +} + +pub fn init + Send + Sync + 'static>( + _crash_init: InitCrashHandler, + _spawn: impl FnOnce(BoxFuture<'static, ()>), + _wait_timer: impl (Fn(std::time::Duration) -> F) + Send + Sync + 'static, +) { + log::info!("crash handler disabled on FreeBSD"); +} + +pub fn crash_server(_socket: &Path) { + log::info!("crash server disabled on FreeBSD"); +} + +pub fn set_gpu_info(_specs: ()) {} + +pub fn set_user_info(_info: ()) {} diff --git a/crates/crashes/src/crashes.rs b/crates/crashes/src/crashes_full.rs similarity index 100% rename from crates/crashes/src/crashes.rs rename to crates/crashes/src/crashes_full.rs diff --git a/crates/crashes/src/lib.rs b/crates/crashes/src/lib.rs new file mode 100644 index 00000000000..e3e359ac1ae --- /dev/null +++ b/crates/crashes/src/lib.rs @@ -0,0 +1,11 @@ +#[cfg(not(target_os = "freebsd"))] +mod crashes_full; + +#[cfg(not(target_os = "freebsd"))] +pub use crashes_full::*; + +#[cfg(target_os = "freebsd")] +mod crashes_freebsd; + +#[cfg(target_os = "freebsd")] +pub use crashes_freebsd::*; diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index 2d716f8e519..8325a38c8a7 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -576,14 +576,15 @@ impl FileHandle for std::fs::File { }; let fd = self.as_fd(); - let mut kif = MaybeUninit::::uninit(); + let mut kif = MaybeUninit::::zeroed(); + // SAFETY: zeroed memory is a valid initial state for kinfo_file. + let kif = unsafe { kif.assume_init_mut() }; kif.kf_structsize = libc::KINFO_FILE_SIZE; - let result = unsafe { libc::fcntl(fd.as_raw_fd(), libc::F_KINFO, kif.as_mut_ptr()) }; + let result = unsafe { libc::fcntl(fd.as_raw_fd(), libc::F_KINFO, kif as *mut _) }; anyhow::ensure!(result != -1, "fcntl returned -1"); - // SAFETY: `fcntl` will initialize the kif. - let c_str = unsafe { CStr::from_ptr(kif.assume_init().kf_path.as_ptr()) }; + let c_str = unsafe { CStr::from_ptr(kif.kf_path.as_ptr()) }; anyhow::ensure!(!c_str.is_empty(), "Could find a path for the file handle"); let path = PathBuf::from(OsStr::from_bytes(c_str.to_bytes())); Ok(path) diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 5f1e9a95bcb..4e3efcfd22a 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -35,7 +35,7 @@ mod platform; pub mod prelude; /// Profiling utilities for task timing and thread performance tracking. pub mod profiler; -#[cfg(any(target_os = "windows", target_os = "linux", target_family = "wasm"))] +#[cfg(any(target_os = "windows", target_os = "linux", target_os = "freebsd", target_family = "wasm"))] #[expect(missing_docs)] pub mod queue; mod scene; @@ -102,7 +102,7 @@ pub use keymap::*; pub use path_builder::*; pub use platform::*; pub use profiler::*; -#[cfg(any(target_os = "windows", target_os = "linux", target_family = "wasm"))] +#[cfg(any(target_os = "windows", target_os = "linux", target_os = "freebsd", target_family = "wasm"))] pub use queue::{PriorityQueueReceiver, PriorityQueueSender}; pub use refineable::*; pub use scene::*; diff --git a/crates/remote_server/Cargo.toml b/crates/remote_server/Cargo.toml index 48c047252fe..268ae59d5bb 100644 --- a/crates/remote_server/Cargo.toml +++ b/crates/remote_server/Cargo.toml @@ -75,11 +75,13 @@ thiserror.workspace = true rayon.workspace = true uuid = { workspace = true, features = ["v4"] } -[target.'cfg(not(windows))'.dependencies] +[target.'cfg(not(any(target_os = "windows", target_os = "freebsd")))'.dependencies] crash-handler.workspace = true +minidumper.workspace = true + +[target.'cfg(not(windows))'.dependencies] fork.workspace = true libc.workspace = true -minidumper.workspace = true [target.'cfg(windows)'.dependencies] windows.workspace = true From ac1fe538df64b643ae487524496538717a44edcb Mon Sep 17 00:00:00 2001 From: G36maid Date: Thu, 14 May 2026 22:05:09 +0800 Subject: [PATCH 2/5] Rename crashes_full.rs back to crashes.rs Per review feedback, the original name is clearer since it's the default (non-FreeBSD) implementation. --- crates/crashes/src/{crashes_full.rs => crashes.rs} | 0 crates/crashes/src/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename crates/crashes/src/{crashes_full.rs => crashes.rs} (100%) diff --git a/crates/crashes/src/crashes_full.rs b/crates/crashes/src/crashes.rs similarity index 100% rename from crates/crashes/src/crashes_full.rs rename to crates/crashes/src/crashes.rs diff --git a/crates/crashes/src/lib.rs b/crates/crashes/src/lib.rs index e3e359ac1ae..4be5fafcdcb 100644 --- a/crates/crashes/src/lib.rs +++ b/crates/crashes/src/lib.rs @@ -1,8 +1,8 @@ #[cfg(not(target_os = "freebsd"))] -mod crashes_full; +mod crashes; #[cfg(not(target_os = "freebsd"))] -pub use crashes_full::*; +pub use crashes::*; #[cfg(target_os = "freebsd")] mod crashes_freebsd; From e722eaa4e46180ffafaab0a8f518abb0e812fa88 Mon Sep 17 00:00:00 2001 From: G36maid Date: Fri, 1 May 2026 14:11:51 +0800 Subject: [PATCH 3/5] remote: Add FreeBSD to RemoteOs enum and platform detection Add FreeBSD as a recognized remote OS so the Zed client can connect to FreeBSD hosts without requiring a uname wrapper workaround. - Add RemoteOs::FreeBSD variant with "freebsd" identifier - Add "FreeBSD" to parse_platform() uname parsing - Add "unknown-freebsd" target triple mapping - FreeBSD uses PathStyle::Posix (already covered by wildcard arms) --- crates/remote/src/remote_client.rs | 2 ++ crates/remote/src/transport.rs | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/crates/remote/src/remote_client.rs b/crates/remote/src/remote_client.rs index 85e07aee0b4..1a6800e3cb6 100644 --- a/crates/remote/src/remote_client.rs +++ b/crates/remote/src/remote_client.rs @@ -57,6 +57,7 @@ pub enum RemoteOs { Linux, MacOs, Windows, + FreeBSD, } impl RemoteOs { @@ -65,6 +66,7 @@ impl RemoteOs { RemoteOs::Linux => "linux", RemoteOs::MacOs => "macos", RemoteOs::Windows => "windows", + RemoteOs::FreeBSD => "freebsd", } } diff --git a/crates/remote/src/transport.rs b/crates/remote/src/transport.rs index 1794a68839a..b307235b04d 100644 --- a/crates/remote/src/transport.rs +++ b/crates/remote/src/transport.rs @@ -32,6 +32,7 @@ fn parse_platform(output: &str) -> Result { let os = match os { "Darwin" => RemoteOs::MacOs, "Linux" => RemoteOs::Linux, + "FreeBSD" => RemoteOs::FreeBSD, _ => anyhow::bail!( "Prebuilt remote servers are not yet available for {os:?}. See https://zed.dev/docs/remote-development" ), @@ -244,6 +245,7 @@ async fn build_remote_server_from_source( "unknown-linux-gnu" }, RemoteOs::MacOs => "apple-darwin", + RemoteOs::FreeBSD => "unknown-freebsd", RemoteOs::Windows if cfg!(windows) => "pc-windows-msvc", RemoteOs::Windows => "pc-windows-gnu", } @@ -444,6 +446,10 @@ mod tests { assert!(parse_platform("Windows x86_64\n").is_err()); assert!(parse_platform("Linux armv7l\n").is_err()); + + let result = parse_platform("FreeBSD x86_64\n").unwrap(); + assert_eq!(result.os, RemoteOs::FreeBSD); + assert_eq!(result.arch, RemoteArch::X86_64); } #[test] From cbacd2e2a920586e474c1ce371e680768088037d Mon Sep 17 00:00:00 2001 From: G36maid Date: Fri, 8 May 2026 15:58:21 +0800 Subject: [PATCH 4/5] Update libz-sys to 1.1.28 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ebe585c4cb..85f6ddf1cdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10014,9 +10014,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.22" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" dependencies = [ "cc", "libc", From 487ea9ff0d62651bff6eeb390e631eb302f6b1e4 Mon Sep 17 00:00:00 2001 From: G36maid Date: Thu, 14 May 2026 17:45:11 +0800 Subject: [PATCH 5/5] run cargo fmt Remove unused cfg-if and release_channel deps from crashes crate Update Cargo.lock --- Cargo.lock | 2 -- crates/crashes/Cargo.toml | 2 -- crates/gpui/src/gpui.rs | 14 ++++++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85f6ddf1cdf..d7f105a2512 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4144,7 +4144,6 @@ name = "crashes" version = "0.1.0" dependencies = [ "async-process", - "cfg-if", "crash-handler", "futures 0.3.32", "log", @@ -4152,7 +4151,6 @@ dependencies = [ "minidumper", "parking_lot", "paths", - "release_channel", "serde", "serde_json", "system_specs", diff --git a/crates/crashes/Cargo.toml b/crates/crashes/Cargo.toml index c652d34d484..8c3526f4c94 100644 --- a/crates/crashes/Cargo.toml +++ b/crates/crashes/Cargo.toml @@ -6,11 +6,9 @@ edition.workspace = true license = "GPL-3.0-or-later" [dependencies] -cfg-if.workspace = true futures.workspace = true log.workspace = true parking_lot.workspace = true -release_channel.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 4e3efcfd22a..dc0233839d6 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -35,7 +35,12 @@ mod platform; pub mod prelude; /// Profiling utilities for task timing and thread performance tracking. pub mod profiler; -#[cfg(any(target_os = "windows", target_os = "linux", target_os = "freebsd", target_family = "wasm"))] +#[cfg(any( + target_os = "windows", + target_os = "linux", + target_os = "freebsd", + target_family = "wasm" +))] #[expect(missing_docs)] pub mod queue; mod scene; @@ -102,7 +107,12 @@ pub use keymap::*; pub use path_builder::*; pub use platform::*; pub use profiler::*; -#[cfg(any(target_os = "windows", target_os = "linux", target_os = "freebsd", target_family = "wasm"))] +#[cfg(any( + target_os = "windows", + target_os = "linux", + target_os = "freebsd", + target_family = "wasm" +))] pub use queue::{PriorityQueueReceiver, PriorityQueueSender}; pub use refineable::*; pub use scene::*;