diff --git a/.docs/lessons_learned.md b/.docs/lessons_learned.md index 1fb4c2f6..e10965e1 100644 --- a/.docs/lessons_learned.md +++ b/.docs/lessons_learned.md @@ -32,3 +32,10 @@ Root Cause: Two `tests/tests2` fixtures had drifted. `139_arm64_errors.test` dep Solution: Enable `-dt` for `139_arm64_errors.test`, update the stale expected hex value in `138_arm64_encoding.expect`, and replace the obsolete ARM64 inline-asm error expectations with current checks for an invalid operand reference and an invalid clobber register. Prevention: When adding new `tests/tests2` multi-case files, wire `-dt` in `tests/tests2/Makefile` immediately and rerun the specific tests2 targets before trusting a full `make test` failure. If a feature graduates from "not implemented" to supported, audit any negative tests for obsolete expectations. Related Files: [tests/tests2/Makefile, tests/tests2/138_arm64_encoding.expect, tests/tests2/139_arm64_errors.c, tests/tests2/139_arm64_errors.expect] + +Date: 2026-04-04 +Problem: Windows `tcc -run tcc.c ... -run ...` recursion made `tests/test2` and `tests/test3` fail, and once that was fixed the Windows x86_64 runtime still missed `atexit`/`on_exit` callbacks and destructors in `108_constructor` and `128_run_atexit`. +Root Cause: `win32/lib/crt1.c` rebuilt run arguments from the original process command line even though `run_arg_start` is relative to the currently active `-run` argv slice. That reintroduced the previous `-run tcc.c` segment on nested runs. Separately, the newer `runrt.c` callback path was wired directly into `crt1.c` while x86_64 Windows still uses `lib/runmain.c` for `-run`, so normal return and startup cleanup no longer used the same callback/destructor chain on every Windows target. +Solution: Rebuild `-run` argv from the active CRT `__argc`/`__targv` slice first, keep wildcard expansion on that slice, guard `tcc.c`'s `run_arg_start` write behind `TCC_IS_NATIVE`, route `_runtmain` through generic `atexit`/`__run_on_exit`, and keep `_tstart` on `__tcc_exit` so normal executable destructors still run. +Prevention: For Windows runtime changes, rerun both nested `make test` coverage (`tests/test2`, `tests/test3`) and the Windows-specific lifecycle tests (`tests/tests2/108_constructor`, `tests/tests2/128_run_atexit`). Do not assume ARM64's `runmain-arm64.S` shims behave the same as x86_64's `lib/runmain.c`; they exercise different cleanup paths. +Related Files: [win32/lib/crt1.c, tcc.c, lib/runmain.c, win32/lib/runmain-arm64.S, win32/lib/runrt.c, tests/Makefile, tests/tests2/108_constructor.c, tests/tests2/128_run_atexit.c]