cmux-next tests: the test process's children start without SWIFT_BACKTRACE (base red from #25857)

TE
8d ago
+41-0

A base red that #25857 caused: the cmux-next swift test job ends with a cut-short shard because an exit test hangs in the Swift backtracer.

What breaks

#25857 made scripts/cmux-next/swift-test-with-hang-sampler.sh export SWIFT_BACKTRACE=enable=yes,…,symbolicate=full, so that a crash of the test process prints its stack. Every child of the test process inherits that variable, and two kinds of children break:

  • Exit tests. The child of #expect(processExitsWith:) traps on purpose. With the variable set, it spawned swift-backtrace to symbolicate the whole test binary, and the parent sat in wait4. In #26809 run 40999753339, shard 6 ended this way: BlockingCheckTests.aCheckedFileManagerCallOnTheMainThreadTraps's child was in handle_fatal_signal → _swift_spawnBacktracer → __wait4. Nothing printed for 300 s, the stuck-test watchdog killed the run (exit 143), and every test after it in the shard never ran.
  • Privileged tools. A privileged tool such as /usr/bin/python3 or tar first writes swift runtime: backtrace-on-crash is not supported for privileged executables. to stderr. A test that reads the child's stderr takes that line for the answer. In the same run, ChromiumRuntimeInstallerTests failed with unsafeEntry("swift runtime: backtrace-on-crash …") and then stalled for 303 s (shard 5, exit 143). #27981 fixed the python daemon bridges this way, one call site at a time.

The fix

The test bundle's load-time constructor (Tests/Support/CmuxNextTestExitTrace, which is already linked into the test bundle) now unsets SWIFT_BACKTRACE. The Swift runtime reads the variable when libswiftCore loads, which is before the bundle loads. So the test process keeps its own backtracer for #25857's crash attribution, and no child gets one. #27981's fakePython helpers still work, and with this change they are no longer needed.

TestProcessExitTests.aChildOfTheTestProcessGetsNoSwiftBacktrace covers it in three checks:

  • the constructor ran;
  • the variable is gone from this process's environment;
  • /usr/bin/env, run as a child, does not list it.

That test only means something under the swift test wrapper, which sets the variable. The fleet's ci-step does not allow SWIFT_BACKTRACE in its env, so the red/green proof is this PR's own cmux-next swift test job.

Risk: test support code only. Product code is unchanged.

Agent session: agent session

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Keeps SWIFT_BACKTRACE for the test process's own crashes while stopping its children from inheriting it, so exit tests no longer hang in the Swift backtracer and privileged tools no longer emit unsupported-backtrace warnings that tests read as answers.

The test bundle's load-time constructor now unsets the variable; since the Swift runtime reads it before the bundle loads, the process itself keeps its backtracer. A new test confirms the constructor ran, the variable is gone from the process's environment, and a child /usr/bin/env doesn't list it. Test support code only; product code is unchanged.