From 18dad5a21ad5e40c0e74009f47379b0f265f1284 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 13 Apr 2026 00:49:37 +0200 Subject: [PATCH 1/5] Error handling for Launcher exits --- crates/libafl/src/events/launcher.rs | 62 +++++++++++++++++++--- fuzzers/forkserver/libafl-fuzz/Cargo.lock | 59 +++++++++++--------- fuzzers/forkserver/libafl-fuzz/src/main.rs | 2 +- 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/crates/libafl/src/events/launcher.rs b/crates/libafl/src/events/launcher.rs index 8bbefd90a99..5b5fd2bb099 100644 --- a/crates/libafl/src/events/launcher.rs +++ b/crates/libafl/src/events/launcher.rs @@ -762,7 +762,7 @@ where } } - Self::wait_for_pids(&handles, self.spawn_broker); + Self::wait_for_pids(&handles, self.spawn_broker)?; } // This is the fork part for unix #[cfg(not(unix))] @@ -892,13 +892,16 @@ where spawn_mgr(&self, None, monitor)?; } - Self::wait_for_child_processes(&mut handles, self.spawn_broker); + Self::wait_for_child_processes(&mut handles, self.spawn_broker)?; } - Ok(()) + Err(Error::shutting_down()) } #[cfg(unix)] - fn wait_for_pids(handles: &[i32], spawn_broker: bool) { + fn wait_for_pids(handles: &[i32], spawn_broker: bool) -> Result<(), Error> { + let mut crash_count = 0; + let mut reasons = vec![]; + if spawn_broker { // Broker exited. kill all clients and wait for them to avoid zombies. for handle in handles { @@ -927,13 +930,29 @@ where ); } else { log::info!("Client with pid {handle} exited with status {status}"); + crash_count += 1; + reasons.push(format!("Exited with status {status}")); } } } } + + if crash_count > 0 { + return Err(Error::unknown(format!( + "{} child processes crashed. Reasons: {:?}", + crash_count, reasons + ))); + } + Ok(()) } - fn wait_for_child_processes(handles: &mut [std::process::Child], spawn_broker: bool) { + fn wait_for_child_processes( + handles: &mut [std::process::Child], + spawn_broker: bool, + ) -> Result<(), Error> { + let mut crash_count = 0; + let mut reasons = vec![]; + if spawn_broker { for handle in &mut *handles { let _ = handle.kill(); @@ -941,12 +960,39 @@ where } } else { for handle in &mut *handles { - let ecode = handle.wait(); - if ecode.as_ref().is_ok_and(|e| !e.success()) { - log::info!("Client with handle {handle:?} exited with {ecode:?}"); + let ecode = handle.wait()?; + if !ecode.success() { + #[cfg(unix)] + { + use std::os::unix::process::ExitStatusExt; + if let Some(sig) = ecode.signal() { + if sig != libc::SIGINT && sig != libc::SIGTERM { + crash_count += 1; + reasons.push(format!("Killed by signal {sig}")); + } + } else if let Some(code) = ecode.code() { + crash_count += 1; + reasons.push(format!("Exited with code {code}")); + } + } + #[cfg(not(unix))] + { + if let Some(code) = ecode.code() { + crash_count += 1; + reasons.push(format!("Exited with code {code}")); + } + } } } } + + if crash_count > 0 { + return Err(Error::unknown(format!( + "{} child processes crashed. Reasons: {:?}", + crash_count, reasons + ))); + } + Ok(()) } /// Launch the common broker logic diff --git a/fuzzers/forkserver/libafl-fuzz/Cargo.lock b/fuzzers/forkserver/libafl-fuzz/Cargo.lock index ebce377b3d5..01dc2847526 100644 --- a/fuzzers/forkserver/libafl-fuzz/Cargo.lock +++ b/fuzzers/forkserver/libafl-fuzz/Cargo.lock @@ -257,9 +257,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.59" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "jobserver", @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e" +checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" dependencies = [ "ctor-proc-macro", "dtor", @@ -452,9 +452,9 @@ checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" [[package]] name = "dtor" -version = "0.1.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" +checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" dependencies = [ "dtor-proc-macro", ] @@ -558,20 +558,21 @@ dependencies = [ [[package]] name = "fastbloom" -version = "0.14.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" +checksum = "ef975e30683b2d965054bb0a836f8973857c4ebf6acf274fe46617cd285060d8" dependencies = [ - "getrandom 0.3.4", + "foldhash 0.2.0", "libm", + "portable-atomic", "siphasher", ] [[package]] name = "fastrand" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a043dc74da1e37d6afe657061213aa6f425f855399a11d3463c6ecccc4dfda1f" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "find-msvc-tools" @@ -681,6 +682,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "heck" version = "0.4.1" @@ -712,12 +719,12 @@ checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "indexmap" -version = "2.13.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "serde", "serde_core", ] @@ -779,9 +786,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.94" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ "once_cell", "wasm-bindgen", @@ -2109,9 +2116,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", @@ -2122,9 +2129,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2132,9 +2139,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", @@ -2145,9 +2152,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] @@ -2188,9 +2195,9 @@ dependencies = [ [[package]] name = "wide" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198f6abc41fab83526d10880fa5c17e2b4ee44e763949b4bb34e2fd1e8ca48e4" +checksum = "c9479f84a757f819cfab37295955906479181395de83add28f74975fde083141" dependencies = [ "bytemuck", "safe_arch", diff --git a/fuzzers/forkserver/libafl-fuzz/src/main.rs b/fuzzers/forkserver/libafl-fuzz/src/main.rs index 534d4f70f82..6c4e3e5728d 100644 --- a/fuzzers/forkserver/libafl-fuzz/src/main.rs +++ b/fuzzers/forkserver/libafl-fuzz/src/main.rs @@ -198,7 +198,7 @@ fn main() { res }; match res { - Ok(()) => unreachable!(), + Ok(()) => (), Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), Err(err) => panic!("Failed to run launcher: {err:?}"), } From 41ec6b111c42195caa9c0cae33c819267b56e088 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 13 Apr 2026 00:56:30 +0200 Subject: [PATCH 2/5] clip --- crates/libafl/src/events/launcher.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/libafl/src/events/launcher.rs b/crates/libafl/src/events/launcher.rs index 5b5fd2bb099..1c325460f81 100644 --- a/crates/libafl/src/events/launcher.rs +++ b/crates/libafl/src/events/launcher.rs @@ -939,8 +939,7 @@ where if crash_count > 0 { return Err(Error::unknown(format!( - "{} child processes crashed. Reasons: {:?}", - crash_count, reasons + "{crash_count} child processes crashed. Reasons: {reasons:?}" ))); } Ok(()) @@ -988,8 +987,7 @@ where if crash_count > 0 { return Err(Error::unknown(format!( - "{} child processes crashed. Reasons: {:?}", - crash_count, reasons + "{crash_count} child processes crashed. Reasons: {reasons:?}" ))); } Ok(()) From 2312e44ee7f9d913121c7df5d910747638279a6a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 14 May 2026 19:05:09 +0200 Subject: [PATCH 3/5] AI-address comments --- crates/libafl/src/events/launcher.rs | 48 ++++++++++------------ fuzzers/forkserver/libafl-fuzz/src/main.rs | 2 +- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/crates/libafl/src/events/launcher.rs b/crates/libafl/src/events/launcher.rs index 1c325460f81..a7d07c37d6e 100644 --- a/crates/libafl/src/events/launcher.rs +++ b/crates/libafl/src/events/launcher.rs @@ -68,6 +68,15 @@ const _AFL_LAUNCHER_CLIENT: &str = "AFL_LAUNCHER_CLIENT"; #[cfg(unix)] const LIBAFL_DEBUG_OUTPUT: &str = "LIBAFL_DEBUG_OUTPUT"; +/// Reasons why a child process exited/crashed +#[derive(Debug, Clone, Copy)] +pub enum LauncherExitReason { + /// Exited with status code + Exited(i32), + /// Killed by signal + Killed(i32), +} + /// Information about this client from the launcher #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ClientDescription { @@ -172,7 +181,6 @@ pub struct Launcher<'a, CF, MT, SP> { /// Tell the manager to serialize or not the state on restart serialize_state: ShouldSaveState, /// If this launcher should use `fork` to spawn a new instance. Otherwise it will try to re-launch the current process with exactly the same parameters. - #[cfg(unix)] fork: bool, } @@ -204,7 +212,6 @@ pub struct LauncherBuilder<'a, CF, MT, SP> { multi_machine_node_descriptor: Option>, spawn_broker: bool, serialize_state: ShouldSaveState, - #[cfg(unix)] fork: bool, } @@ -232,7 +239,6 @@ impl LauncherBuilder<'_, (), (), ()> { ), spawn_broker: true, serialize_state: ShouldSaveState::OnRestart, - #[cfg(unix)] fork: true, } } @@ -269,7 +275,6 @@ impl<'a, CF, MT, SP> LauncherBuilder<'a, CF, MT, SP> { multi_machine_node_descriptor: self.multi_machine_node_descriptor, spawn_broker: self.spawn_broker, serialize_state: self.serialize_state, - #[cfg(unix)] fork: self.fork, } } @@ -295,7 +300,6 @@ impl<'a, CF, MT, SP> LauncherBuilder<'a, CF, MT, SP> { multi_machine_node_descriptor: self.multi_machine_node_descriptor, spawn_broker: self.spawn_broker, serialize_state: self.serialize_state, - #[cfg(unix)] fork: self.fork, } } @@ -328,7 +332,6 @@ impl<'a, CF, MT, SP> LauncherBuilder<'a, CF, MT, SP> { multi_machine_node_descriptor: self.multi_machine_node_descriptor, spawn_broker: self.spawn_broker, serialize_state: self.serialize_state, - #[cfg(unix)] fork: self.fork, } } @@ -412,7 +415,6 @@ impl<'a, CF, MT, SP> LauncherBuilder<'a, CF, MT, SP> { } /// If this launcher should use `fork` to spawn a new instance. Otherwise it will try to re-launch the current process with exactly the same parameters. - #[cfg(unix)] #[must_use] pub fn fork(mut self, fork: bool) -> Self { self.fork = fork; @@ -445,7 +447,6 @@ impl<'a, CF, MT, SP> LauncherBuilder<'a, CF, MT, SP> { .expect("multi_machine_node_descriptor not set"), spawn_broker: self.spawn_broker, serialize_state: self.serialize_state, - #[cfg(unix)] fork: self.fork, } } @@ -527,7 +528,6 @@ where multi_machine_node_descriptor: self.multi_machine_node_descriptor, spawn_broker: self.spawn_broker, serialize_state: self.serialize_state, - #[cfg(unix)] fork: self.fork, } } @@ -652,12 +652,7 @@ where F: FnMut(&Self, Option, Option) -> Result<(Option, EM), Error>, CF: FnOnce(Option, EM, ClientDescription) -> Result<(), Error>, { - #[cfg(unix)] - let use_fork = self.fork; - #[cfg(not(unix))] - let use_fork = false; - - if use_fork { + if cfg!(unix) && self.fork { #[cfg(unix)] { if self.cores.ids.is_empty() { @@ -762,12 +757,9 @@ where } } - Self::wait_for_pids(&handles, self.spawn_broker)?; - } - // This is the fork part for unix - #[cfg(not(unix))] - { - unreachable!("Forking not supported"); + if let Err(err) = Self::wait_for_pids(&handles, self.spawn_broker) { + log::error!("Error waiting for client PIDs: {err:?}"); + } } } else { // spawn logic @@ -892,9 +884,11 @@ where spawn_mgr(&self, None, monitor)?; } - Self::wait_for_child_processes(&mut handles, self.spawn_broker)?; + if let Err(err) = Self::wait_for_child_processes(&mut handles, self.spawn_broker) { + log::error!("Error waiting for child processes: {err:?}"); + } } - Err(Error::shutting_down()) + Ok(()) } #[cfg(unix)] @@ -931,7 +925,7 @@ where } else { log::info!("Client with pid {handle} exited with status {status}"); crash_count += 1; - reasons.push(format!("Exited with status {status}")); + reasons.push(LauncherExitReason::Exited(status)); } } } @@ -967,18 +961,18 @@ where if let Some(sig) = ecode.signal() { if sig != libc::SIGINT && sig != libc::SIGTERM { crash_count += 1; - reasons.push(format!("Killed by signal {sig}")); + reasons.push(LauncherExitReason::Killed(sig)); } } else if let Some(code) = ecode.code() { crash_count += 1; - reasons.push(format!("Exited with code {code}")); + reasons.push(LauncherExitReason::Exited(code)); } } #[cfg(not(unix))] { if let Some(code) = ecode.code() { crash_count += 1; - reasons.push(format!("Exited with code {code}")); + reasons.push(LauncherExitReason::Exited(code)); } } } diff --git a/fuzzers/forkserver/libafl-fuzz/src/main.rs b/fuzzers/forkserver/libafl-fuzz/src/main.rs index 6c4e3e5728d..534d4f70f82 100644 --- a/fuzzers/forkserver/libafl-fuzz/src/main.rs +++ b/fuzzers/forkserver/libafl-fuzz/src/main.rs @@ -198,7 +198,7 @@ fn main() { res }; match res { - Ok(()) => (), + Ok(()) => unreachable!(), Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), Err(err) => panic!("Failed to run launcher: {err:?}"), } From d97109990145af4e2fb0c135d483efa6d9e657a0 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 14 May 2026 19:16:32 +0200 Subject: [PATCH 4/5] fix --- .github/workflows/qemu-fuzzer-tester-prepare/action.yml | 2 +- .github/workflows/ubuntu-prepare/action.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/qemu-fuzzer-tester-prepare/action.yml b/.github/workflows/qemu-fuzzer-tester-prepare/action.yml index c5a09f11143..1f1fbc34e19 100644 --- a/.github/workflows/qemu-fuzzer-tester-prepare/action.yml +++ b/.github/workflows/qemu-fuzzer-tester-prepare/action.yml @@ -11,7 +11,7 @@ runs: gcc-arm-linux-gnueabi g++-arm-linux-gnueabi cmake - name: Remove old rust shell: bash - run: sudo apt purge -y 'rust*' 'cargo*' + run: sudo apt purge -y 'rust*' 'cargo*' 'rustup*' - uses: dtolnay/rust-toolchain@stable - name: enable mult-thread for `make` shell: bash diff --git a/.github/workflows/ubuntu-prepare/action.yml b/.github/workflows/ubuntu-prepare/action.yml index 0c2aa831dea..24906c625d5 100644 --- a/.github/workflows/ubuntu-prepare/action.yml +++ b/.github/workflows/ubuntu-prepare/action.yml @@ -15,7 +15,7 @@ runs: - name: Uninstall all currently installed Rust shell: bash run: | - sudo apt purge -y 'cargo*' 'rust*' + sudo apt purge -y 'cargo*' 'rust*' 'rustup*' - name: Install and cache deps shell: bash From 98df92341f47a4644eb2fde4e13996e499499c1a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 15 May 2026 12:12:34 +0200 Subject: [PATCH 5/5] Does this help? --- .github/workflows/build_and_test.yml | 22 +++++++++++++++++++ .github/workflows/ubuntu-prepare/action.yml | 4 ++++ .../windows-tester-prepare/action.yml | 3 +++ 3 files changed, 29 insertions(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4a160e0a023..662b0db97b0 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -48,6 +48,10 @@ jobs: uses: ./.github/workflows/ubuntu-prepare - if: runner.os != 'Linux' uses: dtolnay/rust-toolchain@stable + - name: Fix PATH for Cargo (non-Linux) + if: runner.os != 'Linux' + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Install LLVM if: runner.os == 'MacOS' run: brew install llvm@${{env.MAIN_LLVM_VERSION}} @@ -267,6 +271,9 @@ jobs: - uses: actions/checkout@v4 - uses: extractions/setup-just@v3 - uses: dtolnay/rust-toolchain@stable + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - uses: taiki-e/install-action@cargo-hack # Note: We currently only specify minimum rust versions for the default workspace members - run: just msrv @@ -761,6 +768,9 @@ jobs: - uses: dtolnay/rust-toolchain@nightly with: components: rust-src + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Add targets run: rustup target add arm-linux-androideabi && rustup target add thumbv6m-none-eabi - uses: actions/checkout@v4 @@ -780,6 +790,9 @@ jobs: - uses: dtolnay/rust-toolchain@nightly with: components: rust-src + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: add x86 i686 target run: rustup target add i686-unknown-linux-gnu - name: Install x86 build dependencies / multilib @@ -798,6 +811,9 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: components: clippy, rust-src + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Add targets run: rustup target add arm-linux-androideabi && rustup target add thumbv6m-none-eabi - uses: actions/checkout@v4 @@ -976,6 +992,9 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: components: clippy + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Install nightly run: rustup toolchain install nightly --component clippy - name: Install deps @@ -997,6 +1016,9 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: dtolnay/rust-toolchain@stable + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - uses: nttld/setup-ndk@v1 with: ndk-version: r25b diff --git a/.github/workflows/ubuntu-prepare/action.yml b/.github/workflows/ubuntu-prepare/action.yml index 24906c625d5..914eb88116c 100644 --- a/.github/workflows/ubuntu-prepare/action.yml +++ b/.github/workflows/ubuntu-prepare/action.yml @@ -39,6 +39,10 @@ runs: components: clippy, rustfmt # ----------------------------------------- + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH + - name: Install just uses: extractions/setup-just@v3 diff --git a/.github/workflows/windows-tester-prepare/action.yml b/.github/workflows/windows-tester-prepare/action.yml index 03716a1b1be..ad0bb171c04 100644 --- a/.github/workflows/windows-tester-prepare/action.yml +++ b/.github/workflows/windows-tester-prepare/action.yml @@ -6,6 +6,9 @@ runs: - uses: dtolnay/rust-toolchain@stable with: components: llvm-tools, clippy, rustfmt + - name: Fix PATH for Cargo + shell: bash + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - uses: actions/checkout@v4 - uses: Swatinem/rust-cache@v2 - name: Build docs