Repository navigation
fix: official Windows release binary crashed on startup - #115
Merged
Merged
Conversation
The MSVC release build exited immediately after launch with 0xC0000409 (FAST_FAIL_INVALID_ARG, subcode 5) before drawing any frame. MinGW/clang64 builds of the same source were unaffected. Cause: setvbuf(stderr, nullptr, _IOLBF, 0) in the stderr redirect block. With a NULL buffer the UCRT validates size-2 against INT_MAX-2, so size=0 underflows to 0xFFFF...FE and is rejected as an invalid argument. The invalid-parameter handler then calls __fastfail(FAST_FAIL_INVALID_ARG). freopen() had already succeeded, which is why the log file was created but left empty. The C standard permits a NULL buffer with size 0 (size is ignored), but the UCRT does not. This only surfaced in the official binary because it links the MSVC UCRT statically (AGENTTY_STANDALONE + vcpkg x64-windows-static, 0 api-ms-win-crt imports), while a local clang64 build links it dynamically (13 imports) and tolerates the call. Change: pass BUFSIZ instead of 0, which is the conventional value for line-buffered stderr and keeps the intended line-buffering. No behaviour change on the non-crashing platforms.
1ay1
added a commit
that referenced
this pull request
Oct 23, 2026
the windows ci lanes were red since richpaste landed. richpaste marked UNICODE public, so in agentty's http.cpp gai_strerror became gai_strerrorW and std::string + wchar_t* failed on msvc. msys2 also failed on std::strlen without <cstring> in richpaste. both fixed in richpaste 1dece38. #115 (setvbuf size 0, merged as 035b0aa) got through because the msvc lane only compiles. that lane and the release now launch the tui path once with no console and fail on a 0xC... exit. disk_writes also rejects setvbuf(..., _IOFBF/_IOLBF, 0), the exact call that fast-failed.
Collaborator
|
merged, thanks. the root cause checks out: MSVC's UCRT rejects setvbuf with size 0 and the default invalid-parameter handler fast-fails, while mingw installs a do-nothing handler so it just returned -1 there. CI didn't catch it because the msvc lane only compiled, so it now launches the tui path once and fails on a 0xC... exit (1876bf0). that lane was also red for an unrelated reason, richpaste leaking UNICODE into agentty; fixed in the same commit. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The MSVC release build exited immediately after launch with 0xC0000409 (FAST_FAIL_INVALID_ARG, subcode 5) before drawing any frame. MinGW/clang64 builds of the same source were unaffected.
Cause: setvbuf(stderr, nullptr, _IOLBF, 0) in the stderr redirect block. With a NULL buffer the UCRT validates size-2 against INT_MAX-2, so size=0 underflows to 0xFFFF...FE and is rejected as an invalid argument. The invalid-parameter handler then calls __fastfail(FAST_FAIL_INVALID_ARG). freopen() had already succeeded, which is why the log file was created but left empty.
The C standard permits a NULL buffer with size 0 (size is ignored), but the UCRT does not. This only surfaced in the official binary because it links the MSVC UCRT statically (AGENTTY_STANDALONE + vcpkg x64-windows-static, 0 api-ms-win-crt imports), while a local clang64 build links it dynamically (13 imports) and tolerates the call.
Change: pass BUFSIZ instead of 0, which is the conventional value for line-buffered stderr and keeps the intended line-buffering. No behaviour change on the non-crashing platforms.