Skip to content

FreeWilly 1.0.14

Choose a tag to compare

@alegauss alegauss released this 05 Sep 01:29
· 19 commits to main since this release

Shutting the machine down with FreeWilly running left the engine's ext4 filesystem torn off
mid-write, on three evenings running, and none of the three left a journal that said why.

Windows was refusing to start wsl.exe, and the refusal was a modal box

Between 29 and 31 August 2026 Windows logged the same application popup at every shutdown:
wsl.exe failing with 0xC0000142, STATUS_DLL_INIT_FAILED, in the same second the engine host and
the tray both took SessionEnding. It is not a WSL fault and not a fault in how this tool spells the
command. Adobe's LogTransport2.exe took the same code in the same second on 30 August, so the
condition belongs to the session: under Fast Startup, which is on by default, Windows logs the user
off before it hibernates, and process creation in that session stops working part way through.

What made that worse than a failed launch is that the popup is a hard error. The child sat on a
modal box nobody could click, so the runner waited out its whole budget on a process that had
already failed. Every failing teardown in the journal ends at exactly the four seconds Windows
allows; the one that worked, on 30 August at 10:08, finished in two.

FreeWilly now sets SEM_FAILCRITICALERRORS in its entry point, before anything can reach for
wsl.exe, and every child inherits it. The launch still fails, because nothing here can make
Windows start a process it has decided not to start. It fails immediately and silently instead,
which returns the budget to the steps that can still run and takes the dialog off the screen.

A hurried stop unmounts before it does anything else

The stop did four things in order: drop the relay, ask whether the distribution is running, send
dockerd a SIGTERM and wait for it, and only then run wsl --terminate. Three of those four reach
for wsl.exe, and the terminate, which is the step that unmounts ext4, was last. With four seconds
to spend and one launch able to consume all of them, the sessions of 29, 30 and 31 August all end
at "still tearing down after 4s" with no "terminated freewilly" line behind them.

Containers stopping themselves is worth having, but not ahead of the unmount, because a container
reaped by WSL2 recovers on the next start and a root filesystem torn off mid-write may not. A
hurried stop now terminates first
and does the rest with whatever budget is left. A patient stop
keeps the order it had, where the SIGTERM has twenty seconds and nothing is racing it.

A quiet pipe is not a stopped distribution

The tray runs a backstop for the case where the engine host does not handle the teardown, and it
decided the host had by pinging the engine and finding nothing there. Dropping the relay is the
first thing the stop does, so the pipe goes quiet at the start of a teardown rather than at the
end. On 31 August the tray wrote "the engine host took it down" at 21:51:46, and two seconds later
the host itself wrote "still tearing down after 4s". Both lines are about the same teardown and the
second one is the true one.

The backstop now asks whether the distribution is registered and running, which stays true
right up to the terminate. That question needs wsl.exe, the launch that may not work, so a failed
launch reads as unknown and terminates anyway: terminating a distribution that is already down
costs one wasted call, and not terminating one that is up costs the ext4.

Nothing in a hurried teardown outlasts the budget

Two waits were longer than the whole shutdown. Every wsl.exe call carried the fifteen seconds
written for a preflight at a prompt, and the relay's dispose joined its accept thread for five
seconds. Both now take two seconds when the stop is hurried, half of the four the session has, so
one call that hangs gives up in time for the steps behind it rather than spending the shutdown
alone.

The journal says how far a teardown got

The stop collected its steps and turned them into one line when it returned, so a teardown Windows
killed part way through left no trace that it had run at all. Read the next morning, the last three
shutdowns said only that the teardown had not finished, which the four-second line above them had
already said. Finding out which step it died in took the Windows System log, which is the wrong
place to have to go.

  • A hurried stop writes each step as it finishes, flushed there and then, so what got done
    survives the kill. The patient path keeps its single aggregate line.
  • The exit codes a session ending produces are named. 0xC0000142 reads as Windows refusing to
    initialise the process and 0x40010004 as Windows killing it, rather than arriving as 1073807364.
    The rest keep their number and gain the hex, because a reader who has to convert one by hand
    before they can search for it will not.
  • Each teardown line carries the process that wrote it, so the host's stop and the tray's
    backstop are told apart in a file they both append to.
  • A wsl call that exited non-zero and said nothing names its exit code, in all six places that
    used to spell their own version of that message.
  • A terminate that finds nothing registered says so, so a logoff on a machine that never
    provisioned an engine stops writing a failure about one.

Install

Download FreeWilly-Setup-1.0.14.exe and check it against SHA256SUMS.txt. Upgrading keeps the
distribution and everything in it.