In our CI, we run Valgrind on every commit. In a recent commit, a code modification has triggered a memory leak. We isolate the code that triggers it and it boils down to:
use std::{env, process};
use std::collections::HashMap;
fn main() {
let _map: HashMap<String, String> = env::vars().collect();
process::exit(0);
}
Note that because this function never returns, and that it terminates the process, no
destructors on the current stack or any other thread’s stack will be run. If a clean shutdown
is needed it is recommended to only call this function at a known point where there are no
more destructors left to run; or, preferably, simply return a type implementing Termination (
such as ExitCode or Result) from the main function and avoid this function
What I would like to understand is where could I see the "magic" explaining why/how a main's returning an ExitCode fixes this leak. Basically, what's the difference between fn main() and fn main() -> ExitCode that explains that all resources all well dropped.
Thanks a lot for your crystal clear explanation. Just wondering (sorry if this is obvious), is the compiler creates a kind of real_main function when the user code main has this signature fn main() -> ExitCode? Are there pointers (doc or source code) where I can find more information on how the main function is managed by the compiler?
Thanks a lot once again!!