hgcommands: avoid forked processes to override trace output

Summary:
The environment variable `EDENSCM_TRACE_OUTPUT` specifies where to write the
tracing output for the current command. Environment variables are inherited
by subprocesses by default. That is undesirable because another hg command
(triggered by hook, or background maintaince) will rewrite the trace output.

Avoid it by unsetting EDENSCM_TRACE_OUTPUT for subprocesses.

Reviewed By: xavierd

Differential Revision: D18892973

fbshipit-source-id: 575b6c0df2e7a0775172893e4aa72ca33fa4658c
This commit is contained in:
Jun Wu 2019-12-09 13:06:41 -08:00 committed by Facebook Github Bot
parent 60ce49ea9e
commit 6da344eee2

View File

@ -49,6 +49,15 @@ pub fn run_command(args: Vec<String>, io: &mut clidispatch::io::IO) -> i32 {
// accurately, at least for non-chg cases.
log_start(args.clone(), now);
// Ad-hoc environment variable: EDENSCM_TRACE_OUTPUT. A more standard way
// to access the data is via the blackbox interface.
let trace_output_path = std::env::var("EDENSCM_TRACE_OUTPUT").ok();
if trace_output_path.is_some() {
// Unset environment variable so processes forked by this command
// wouldn't rewrite the trace.
std::env::remove_var("EDENSCM_TRACE_OUTPUT");
}
let cwd = match current_dir(io) {
Err(e) => {
let _ = io.write_err(format!("abort: cannot get current directory: {}\n", e));
@ -101,7 +110,7 @@ pub fn run_command(args: Vec<String>, io: &mut clidispatch::io::IO) -> i32 {
span.record("exitcode", &exit_code);
let _ = maybe_write_trace(io, &tracing_data);
let _ = maybe_write_trace(io, &tracing_data, trace_output_path);
log_end(exit_code as u8, now, tracing_data);
@ -163,11 +172,10 @@ fn setup_tracing() -> (Level, Arc<Mutex<TracingData>>) {
fn maybe_write_trace(
io: &mut clidispatch::io::IO,
tracing_data: &Arc<Mutex<TracingData>>,
path: Option<String>,
) -> Result<()> {
// Ad-hoc environment variable: EDENSCM_TRACE_OUTPUT. A more standard way
// to access the data is via the blackbox interface.
// Write ASCII or TraceEvent JSON (or gzipped JSON) to the specified path.
if let Ok(path) = std::env::var("EDENSCM_TRACE_OUTPUT") {
if let Some(path) = path {
// A hardcoded minimal duration (in microseconds).
let data = tracing_data.lock();
match write_trace(io, &path, &data) {