A missing file is an error, not a core dump

Naming a pad file that is not there printed the error and then said the
machine had STARTED. MACHINE_OK is nought and the code returned nought, so
the front end ran a machine whose clock had never been set up and divided
by it: a typo in a path came out as a floating point exception and a core
dump.

The trap is two functions in one file with opposite conventions -
machineStart returns MACHINE_OK for worked, machineRestart thirty lines up
returns 1 for worked - and this copied the nearer one. Both of the returns
I added last week had it.

Checked now for all three files the replay suite is about, because the
same mistake fits all of them, and re-broken to be sure: the check comes
back exit 136, which is a signal 8, which is the crash.

Found by somebody typing a path that was not there, which is the fourth
thing this week that no test would have reached.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-03 15:50:40 -04:00
co-authored by Claude Opus 5
parent 60e0196fe2
commit 4b1c3d8e3f
2 changed files with 35 additions and 2 deletions
+11 -2
View File
@@ -225,6 +225,15 @@ uint8_t machineStart(Machine *m, const EmulatorOptions *options, const char *pro
}
// ---- The pads, from files ----
//
// MACHINE_ERROR and not nought. Nought is MACHINE_OK here, so returning it after printing
// an error said the machine had started - and the front end then ran a machine whose
// clock had never been set up and divided by it. A missing file came out as a floating
// point exception and a core dump.
//
// The trap is that machineRestart, thirty lines up, returns 1 for worked and 0 for did
// not. Two functions in one file with opposite conventions, and this copied the nearer
// one.
//
// Opened here beside the keyboard because they are the same kind of thing: a recording
// standing in for a person, so that what a person would exercise is reachable from a
// suite. They are never closed, for the same reason the keyboard is not - the machine
@@ -233,7 +242,7 @@ uint8_t machineStart(Machine *m, const EmulatorOptions *options, const char *pro
FILE *pad = fopen(options->pads[n], "rb");
if (pad == NULL) {
fprintf(stderr, "Error: Couldn't open pad file: %s\n", options->pads[n]);
return 0;
return MACHINE_ERROR;
}
padFromFile(n, pad);
}
@@ -242,7 +251,7 @@ uint8_t machineStart(Machine *m, const EmulatorOptions *options, const char *pro
FILE *pad = fopen(options->padRecord, "wb");
if (pad == NULL) {
fprintf(stderr, "Error: Couldn't write pad file: %s\n", options->padRecord);
return 0;
return MACHINE_ERROR;
}
padRecordTo(pad);
}
+24
View File
@@ -114,6 +114,30 @@ print('yes' if set(data) <= {0} else 'no')
&& result ok "and nothing held is written as nothing" "no buttons nobody pressed" \
|| result no "and nothing held is written as nothing" "the recording holds something"
# ---- A file that is not there is an error, not a crash ----
#
# Naming a pad file that does not exist used to print the error and then say the machine had
# STARTED: MACHINE_OK is nought, and the code returned nought. The front end then ran a
# machine whose clock had never been set up and divided by it, so a typo in a path came out as
# a floating point exception and a core dump.
#
# The trap was two functions in one file with opposite conventions - machineRestart returns 1
# for worked - and the wrong neighbour being copied. Checked here for all three files this
# suite is about, because the same mistake fits all of them.
for missing in "--pad" "--keyboard" "--record-pad"; do
case "$missing" in
--record-pad) where="/nowhere/at/all.pad" ;;
*) where="$BUILD/there-is-no-such-file" ;;
esac
"$EMU" $missing "$where" "$BUILD/padTest.bin" > "$BUILD/missing.out" 2>&1
status=$?
if [ "$status" = "1" ] && grep -q "Error:" "$BUILD/missing.out"; then
result ok "$missing with no file stops cleanly" "an error and a status, not a signal"
else
result no "$missing with no file stops cleanly" "exit $status"
fi
done
echo
if [ "$FAIL" -eq 0 ]; then
echo "All $PASS replay checks passed."