Skip to content

Commit

Permalink
fix: Only kill main process on dfx stop (#2604)
Browse files Browse the repository at this point in the history
Currently the `dfx stop` command tries to kill every child of the main
`dfx` process. This causes the replica to panic when the
`sandbox_launcher` or `canister_sandbox` processes are killed (since it
never expects them to be killed). Instead the `dfx stop` command should
just kill the main `dfx` process and wait for all the children to stop.

This fixes issue
[RUN-351](https://dfinity.atlassian.net/browse/RUN-351).

Co-authored-by: Linwei Shang <[email protected]>
  • Loading branch information
adambratschikaye and lwshang authored Sep 26, 2022
1 parent a21e11b commit a44adb4
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

## DFX

### fix: Only kill main process on `dfx stop`
Removes misleading panics when running `dfx stop`.

### feat: default to run ic-wasm shrink when build canisters
This behavior applies to Motoko, Rust and Custom canisters.
If you want to disable this behavior, you can config it in dfx.json:
Expand Down
16 changes: 8 additions & 8 deletions src/dfx/src/commands/stop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@ fn list_all_descendants<'a>(system: &'a System, proc: &'a Process) -> Vec<&'a Pr
result
}

/// Recursively kill a process and ALL its children.
fn kill_all(system: &System, proc: &Process) -> Vec<Pid> {
/// Recursively list all descendants of a process.
fn descendant_pids(system: &System, proc: &Process) -> Vec<Pid> {
let processes = list_all_descendants(system, proc);
for proc in &processes {
proc.kill_with(Signal::Term);
}
processes.iter().map(|proc| proc.pid()).collect()
}

Expand Down Expand Up @@ -82,12 +79,15 @@ pub fn exec(env: &dyn Environment, _opts: StopOpts) -> DfxResult {
found = true;
let mut system = System::new();
system.refresh_processes();
let pids_killed = if let Some(proc) = system.process(pid) {
kill_all(&system, proc)
let descendant_pids = if let Some(proc) = system.process(pid) {
let descendants = descendant_pids(&system, proc);
proc.kill_with(Signal::Term);
descendants
} else {
vec![]
};
wait_until_all_exited(system, pids_killed)?;

wait_until_all_exited(system, descendant_pids)?;
}
}
// We ignore errors here because there is no effect for the user. We're just being nice.
Expand Down

0 comments on commit a44adb4

Please sign in to comment.