Skip to content

compile driver leaks its perry-objs-<pid>-<nanos>/ staging dir on the --no-link path #7167

Description

@proggeramlug

Split out of #7144, which found it: the temp-hygiene gate added there compiles the
census corpus with TMPDIR pointed at an empty directory, and the directory is not
empty afterwards — but the leftovers are not the clang driver's.

What happens

run_pipeline.rs creates a per-invocation object staging directory:

// crates/perry/src/commands/compile/run_pipeline.rs
let object_output_dir = {
    let dir = std::env::temp_dir().join(format!("perry-objs-{}-{}", std::process::id(), nanos));
    std::fs::create_dir_all(&dir)?;
    dir
};

and removes it on the two link exits (executable, shared library):

if !args.keep_intermediates {
    for obj_path in &obj_cleanup_paths { let _ = fs::remove_file(obj_path); }
    let _ = fs::remove_dir(&object_output_dir);
}

--no-link returns at if args.no_link { before either, so the directory and every
object in it stay. There is no third cleanup site.

Measured

54 --no-link --no-cache compiles of the 27-workload census corpus, with TMPDIR
isolated to a fresh directory:

108 entries left behind — one perry-objs-<pid>-<nanos>/ directory and one .o per compile
    perry-objs-41179-1785566532368471000/fixture_ptr_shape_ts.o
    perry-objs-41180-1785566685697174000/fixture_ptr_shape_sites_ts.o
    …

Unlike #7144 this is unbounded in the number of compiles, not in distinct IR:
the directory name carries pid + wall-clock nanos, so every invocation leaks a fresh
one. Objects are also much larger than the .lls were.

Who hits it

Every --no-link user: perry compile --no-link, the separate-link workflow, and
every harness in scripts/compiler_output_harness/ (the census, knob isolation and
determinism gates all pass --no-link).

Detection already in place

scripts/compiler_output_regression.py census-temp-hygiene (added in #7144) reports
these under "Not this gate's subject" and does not fail on them, deliberately —
a gate that goes red for another module's defect gets muted rather than fixed. When
this is fixed, widen OWNED_PREFIXES in
scripts/compiler_output_harness/repsel_temp_hygiene.py so the gate asserts the
temp directory is empty outright; the comment there says so.

Note

The fix is not "add a third remove_dir" so much as "have one exit that cleans up".
Three call sites that must each remember is how the third one came to be missing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions