Repository navigation
fix(shell): name a DLL-initialisation exit as EXECUTOR_UNAVAILABLE - #563
tietoumiao wants to merge 1 commit into
Conversation
Exit code 3221225794 (0xC0000142 STATUS_DLL_INIT_FAILED, signed -1073741502) means the child died while loading its own DLLs: the command text never ran and both output streams stay empty. Classifying it as an ordinary EXIT_CODE told the caller to correct a command that never executed and to retry, which cannot help (T-Auto#417). Treat a bare loader exit code as EXECUTOR_UNAVAILABLE with retry never and advice that names the condition, for both spellings of the NTSTATUS. Keep every more specific classification (error, restriction, permission, signal, timeout, cancellation) ahead of it. Assert it in the shell-host suite for the unsigned fixture exit code and the signed host value, document the symptom in both troubleshooting guides, and record the change in the changelog.
Haoming9527
left a comment
There was a problem hiding this comment.
The diagnostic goal is useful, and the local build plus all 24 shells-host checks pass at 1afbf1f. There is one correctness issue that should block merging this version.
[P1] A numeric exit status cannot establish that no command ran (src/shells/failure.ts, the new message and nextAction branches). I reproduced this with an actual Windows Node child that writes a marker and then exits with 0xC0000142:
require('node:fs').writeFileSync(process.argv[1], 'command definitely ran')
process.exit(0xC0000142)The parent observes exit code 3221225794, empty stdout/stderr, and the marker on disk. Passing that result through this PR's bashFailure(value, 'unknown') produces both effectState: 'unknown' and “no command ran.” A second control with nonempty stdout/stderr produces the same incorrect claim. Thus adding an empty-output check would not establish absence of effects. The existing fixture also returns stdout: 'ok' / stderr: 'warning', so the new test does not represent the empty-stream case described in the body.
Please keep the useful status name and no-blind-retry guidance, but preserve uncertainty about initialization stage, command execution, and prior effects. The troubleshooting paragraphs need the same correction; this status alone also does not prove a restricted-token cause or that reinstalling the payload is the remedy. A regression should execute a child that writes a marker before returning this code and verify the diagnostic tells the caller to inspect prior effects.
Related work: #543 already handles both signed/unsigned spellings with that conservative diagnostic and is included in integration PR #557. Its comparison result for the same real child retains effectState: 'unknown', names STATUS_DLL_INIT_FAILED, and says to inspect prior effects without rerunning. These overlapping implementations should not both be applied; please coordinate any revision against #543/#557. This review leaves your PR open for revision and does not change the reported host-runtime root causes in #409/#480.
CI run 41338348125 is still awaiting approval; local checks above are not a replacement for repository CI.
Nicholas023
left a comment
There was a problem hiding this comment.
审查结论:REQUEST_CHANGES — 建议关闭
我独立在本机复现了核心问题,其中包括一条会直接误导调用方的错误断言。
1. 「no command ran」是错误的、可被证伪的断言(阻断)
用真实 Windows 子进程:先写 marker 文件,再 process.exit(0xC0000142):
js require('node:fs').writeFileSync(marker, 'command definitely ran') process.exit(0xC0000142)
父进程观察到 exitCode: 3221225794、stdout/stderr 均为 0 字节、marker 在磁盘上。把这个结果喂给本 PR 的 bashFailure():
json { "code": "EXECUTOR_UNAVAILABLE", "message": "… so no command ran.", "effectState": "unknown", "retry": "never", "nextAction": "… no command ran, so editing the command or its arguments cannot change it …" }
同一个 payload 一边说副作用未知,一边说没有命令运行。dllInitExitCode() 只看 exit code,完全不看 stdout/stderr,所以「加空流检查」也补救不了:命令可以在产生输出之前就完成副作用。
2. 新测试没有覆盖它声称的场景
fixture 固定返回 stdout:'ok' / stderr:'warning',而 PR body 描述的是「空输出」场景。
3. 与 #543 重复且补丁级冲突
两 PR 改同一 hunk;git apply --check 实测 #543 的补丁打在 #563 树上 exit 1。
4. 缺少 win32 门禁
POSIX 上 bash 退出码是 8-bit,该 NTSTATUS 分支不可达,属死分支。
已核实为真的部分
- 0.5.0 基线确实把该码报成
EXIT_CODE+ 「correct the command」(问题本身真实存在) node test/run.mjs shells-host→ 24/24 passed- revert-red(只撤
src/shells/failure.ts)→ 1/24 failed,与 PR 声明一致
处置建议
关闭。 由 #543 承接(它保留了 effectState:'unknown',要求先检查既有副作用、不宣称命令未运行)。若要保留 EXECUTOR_UNAVAILABLE 这个码名,那是独立的 taxonomy 决策,不能沿用本 PR 的错误文案。
|
Closing as advised — #543 is the single taxonomy source ( |
Closes #417
What was wrong
On Windows,
ops_bashcan die before any command runs and report exit code3221225794(
0xC0000142,STATUS_DLL_INIT_FAILED) with completely empty stdout/stderr. Nothing insrc/mapped that code, so
src/shells/failure.tsclassified it by stderr text and producedEXIT_CODEwith the advice "correct the command or its inputs before retrying" — advice that cannot work,
because no command was ever executed. The caller then edits a command that was never the problem,
or retries the same failing shell.
Minimal repro: a shell executor that exits with
3221225794and writes nothing to either stream.Observed on Windows 11 x64 against dsh-ops 0.5.0-alpha3 (main
065cd7f); the same family isdescribed in #409/#480 (their sandbox root cause is out of scope here).
The change
src/shells/failure.ts— recognise the loader-failure exit codes (unsigned3221225794andsigned
-1073741502), settle them asEXECUTOR_UNAVAILABLEwithretry: never, and say whatactually happened ("the process died during DLL initialisation; no command ran, so editing the
command cannot change it — repair the shell runtime or the DSH sandbox"). Every more specific
class (error / restriction / permission / signal / timeout / cancel) still wins, and the raw exit
code stays on the result.
test/shells-host.test.mjs— a case driven byfixture({ exitCode: 3221225794 })plus thesigned spelling through
hostForeground({ exitCode: -1073741502 }).docs/troubleshooting.md+docs/常见问题.md+docs/CHANGELOG.md— bilingual entry and the newfailure class.
Deliberately not done: no change to
native/, toprojectResult's sandbox handling, or to therestricted-token root cause of #409/#480; the message-collapsing behaviour of #512 is untouched.
Validation
shells-host的a child that dies in DLL initialisation is named…docs/CHANGELOG.md## [Unreleased]:已加(EN+ZH 成对)pull_request事件触发;fork 首跑可能停在action_required,届时回填
CI required的 run URL(本机无法生成该 run)Environment
065cd7fnpm ci --ignore-scripts,cargo build --release --locked自行 stage workernode test/run.mjs= 4 of 167 failed,与 pristine main 同口径的失败集合一致(
bash-ipc、bash-ipc-roots、linux-paths、permissions,均为本机受限 bash 抖动,见正文)未验证 / 风险披露
0xC0000142现场(受限 MSYS 场景),断言直接喂两个拼写的退出码。hostForeground→bashFailure,但没有套件真的驱动一个 job 以该码退出。CI