You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cancelling the server buries the console under libc370 recovery WTOs. Observed
2026-08-25, a C HTTPD against a running server:
IEE301I HTTPD CANCEL COMMAND ACCEPTED
libc370 @@@try.c failed(): recovery cleanup-only, retry suppressed
libc370 recovery: abend during task termination, cleanup only
libc370 @@@try.c failed(): recovery cleanup-only, retry suppressed
libc370 recovery: abend during task termination, cleanup only
libc370 @@@try.c failed(): recovery cleanup-only, retry suppressed
libc370 recovery: abend during task termination, cleanup only
libc370 @@@try.c failed(): recovery cleanup-only, retry suppressed
libc370 recovery: abend during task termination, cleanup only
libc370 @@@try.c failed(): recovery cleanup-only, retry suppressed
libc370 recovery: abend during task termination, cleanup only
libc370 @@@try.c failed(): recovery cleanup-only, retry suppressed
libc370 recovery: abend during task termination, cleanup only
libc370 recovery: abend during task termination, cleanup only
IEF450I HTTPD HTTPD - ABEND S222 U0000 - TIME=10.22.49
$HASP395 HTTPD ENDED
Six @@@try.c failed() lines, seven recovery: lines, thirteen in total, and
none of them is something an operator can act on. IEE301I and IEF450I … ABEND S222 already say what happened and why. That is exactly the
test CLAUDE.md sets for a WTO, and these lines fail it.
Where they come from
Two sites, both in libc370, both deliberate:
src/clib/@@abrpt.crecovery() — the abendrpt(ESTAE_CREATE, …) exit.
Guarded on SDWAERRD & SDWACLUP: RTM entered only to clean up a terminating
task, so the register/save-area walk is skipped (it would fault or spew "CRT
not found" under a torn-down CRT), one CRT-free WTO is written, SETRP(…,0,0,0).
src/clib/@@@try.cfailed() — the try() / ___try exit. Same guard,
added in libc370 feat: migrate build system to mbt #16 (v1.0.1) after v1.0.0's [HTTPD] HTTP Request Parsing härten #10 had guarded only the
unreachable @@try.c copy. Requesting a retry under a terminating TCB is
invalid, so it suppresses the retry and writes its line.
The guards are correct and must stay. What is in question is only the WTO each
one emits.
httpd registers abendrpt(ESTAE_CREATE, …) in main(), socket_thread() and worker_thread() (src/httpd.c:248, :781, :1015), and calls try() in a handful
of places — the one that matters for a worker is try(serve_client, httpc, work)
at src/httpd.c:1037.
Open question 1: what produces exactly this count?
This is not yet explained, and the issue should not pretend otherwise. The
tempting reading — one recovery: line per task, plus one @@@try.c line per
task that happened to be inside a try() — does not survive a look at the code:
try() creates its ESTAE, calls, and deletes it again before returning
(call() in @@@try.c, cleanup:), so the exit only exists for the duration
of the call.
A worker between requests waits in cthread_worker_wait() (src/httpd.c:1023),
which is outside the try() at :1037. libc370's src/thdmgr/ does not use try() at all. So an idle pool should contribute no @@@try.c lines, and six
of them want accounting for.
So either the server was busier than it looked, or something else holds a try()
ESTAE across the wait, or the exits are driven more than once per task during
termination. Settle this before choosing a fix — the answer decides whether
the burst is bounded by the task count or by something that can be much larger.
What is safe to say without it: the burst grows with the worker pool (MAXTASK
up to 9, and the pool never shrinks back — it is a high-water mark) and with try() nesting depth, since mvsMF's router.c adds its own try()/tryrc()
layer per request.
And this is not a C HTTPD problem. SDWACLUP is set for any termination-time
entry into the exit, so the same burst lands on an S878 or S80A memterm — that
is, precisely when the console is wanted for real diagnosis and not for thirteen
lines of bookkeeping.
The constraint that kills the obvious fix
"Only emit it once per termination burst" is the first idea anyone has, and it
cannot be built where the message is written:
The path is deliberately CRT-free — under a terminating TCB this task's
libc370 CRT may already be gone. No __crtget(), no __wsaget(), no malloc,
no try(). wto() is used because it is SVC 35 and nothing else.
Make it a caller option.@@abrpt.c already has a channel: recovery() reads param->u[1] for the dump option, so a quiet-on-cleanup
flag alongside DUMP_DEFAULT is cheap and per-registration — httpd's three
sites opt in, every other consumer is untouched. try() has no options slot
at all, and its PARAM u[1] is already the register block. So the option is
easy for one of the two messages and not for the other, and what happens to
the @@@try.c line is the second open question of this issue.
Hardcopy-only WTO. Keep the breadcrumb, keep it off the operator console — MCSFLAG=HRDCPY. It matches CLAUDE.md's own division of labour: the console
is for what an operator can act on, the log is the server's diagnostic
channel. Two things to settle before this can be recommended:
Does a hardcopy-only WTO still reach the Master Trace Table?/.dmtt
and cmtt_get_array() are where these lines would have to remain readable.
If it does not, this option collapses into option 1 with extra API surface. This is the one measurement this issue needs.
wto() hardcodes mcsflags = 0 (src/clib/wto.c) and takes no flags
argument, so this means a new entry point in libc370, not an edit.
Not an option: removing the try() wrapper around serve_client. src/httpd.c:1032
records why it is there — it would trade worker recovery for a quieter console.
Scope
The fix is not in httpd. Both sites are libc370, and every consumer shares
them — ftpd, mvsmf, ufsd, rexx370, httplua, httprexx. This issue is the decision;
the deliverable is the chosen shape plus an implementing issue filed in libc370,
referencing libc370#17 (consolidate the two try() wrappers), which touches the
same file and should not be settled twice.
Done when
The count above is explained rather than assumed.
The MTT question is answered by measurement, not assumption.
A shape is chosen for both messages — including the @@@try.c one, which has
no cheap option channel.
An implementing issue exists in libc370, and this one links to it.
Cancelling the server buries the console under libc370 recovery WTOs. Observed
2026-08-25, a
C HTTPDagainst a running server:Six
@@@try.c failed()lines, sevenrecovery:lines, thirteen in total, andnone of them is something an operator can act on.
IEE301IandIEF450I … ABEND S222already say what happened and why. That is exactly thetest
CLAUDE.mdsets for a WTO, and these lines fail it.Where they come from
Two sites, both in libc370, both deliberate:
src/clib/@@abrpt.crecovery()— theabendrpt(ESTAE_CREATE, …)exit.Guarded on
SDWAERRD & SDWACLUP: RTM entered only to clean up a terminatingtask, so the register/save-area walk is skipped (it would fault or spew "CRT
not found" under a torn-down CRT), one CRT-free WTO is written,
SETRP(…,0,0,0).src/clib/@@@try.cfailed()— thetry()/___tryexit. Same guard,added in libc370 feat: migrate build system to mbt #16 (v1.0.1) after v1.0.0's [HTTPD] HTTP Request Parsing härten #10 had guarded only the
unreachable
@@try.ccopy. Requesting a retry under a terminating TCB isinvalid, so it suppresses the retry and writes its line.
The guards are correct and must stay. What is in question is only the WTO each
one emits.
httpd registers
abendrpt(ESTAE_CREATE, …)inmain(),socket_thread()andworker_thread()(src/httpd.c:248, :781, :1015), and callstry()in a handfulof places — the one that matters for a worker is
try(serve_client, httpc, work)at src/httpd.c:1037.
Open question 1: what produces exactly this count?
This is not yet explained, and the issue should not pretend otherwise. The
tempting reading — one
recovery:line per task, plus one@@@try.cline pertask that happened to be inside a
try()— does not survive a look at the code:try()creates its ESTAE, calls, and deletes it again before returning(
call()in@@@try.c,cleanup:), so the exit only exists for the durationof the call.
cthread_worker_wait()(src/httpd.c:1023),which is outside the
try()at :1037. libc370'ssrc/thdmgr/does not usetry()at all. So an idle pool should contribute no@@@try.clines, and sixof them want accounting for.
So either the server was busier than it looked, or something else holds a
try()ESTAE across the wait, or the exits are driven more than once per task during
termination. Settle this before choosing a fix — the answer decides whether
the burst is bounded by the task count or by something that can be much larger.
What is safe to say without it: the burst grows with the worker pool (
MAXTASKup to 9, and the pool never shrinks back — it is a high-water mark) and with
try()nesting depth, since mvsMF'srouter.cadds its owntry()/tryrc()layer per request.
And this is not a
C HTTPDproblem.SDWACLUPis set for any termination-timeentry into the exit, so the same burst lands on an S878 or S80A memterm — that
is, precisely when the console is wanted for real diagnosis and not for thirteen
lines of bookkeeping.
The constraint that kills the obvious fix
"Only emit it once per termination burst" is the first idea anyone has, and it
cannot be built where the message is written:
libc370 CRT may already be gone. No
__crtget(), no__wsaget(), no malloc,no
try().wto()is used because it is SVC 35 and nothing else.staticcounter is module storage. Fetched fromLNKLST or an APF library the load module is key 0 while the code runs problem
state key 8, so the first store is an S0C4 (see stc_identity_restore() stores into module storage in key 8 -- S0C4 on P HTTPD with an APF-authorized LINKLIB #197 and Off-Limits in
CLAUDE.md).Any suppression state therefore has to be supplied by the caller, which makes
this an API question, not a one-line edit.
Options to weigh
scrutiny. Cost: the only evidence that the cleanup-only path was taken at all
disappears — and that evidence is why [HTTPD] HTTP Request Parsing härten #10/feat: migrate build system to mbt #16 exist.
@@abrpt.calready has a channel:recovery()readsparam->u[1]for the dump option, so a quiet-on-cleanupflag alongside
DUMP_DEFAULTis cheap and per-registration — httpd's threesites opt in, every other consumer is untouched.
try()has no options slotat all, and its
PARAMu[1] is already the register block. So the option iseasy for one of the two messages and not for the other, and what happens to
the
@@@try.cline is the second open question of this issue.MCSFLAG=HRDCPY. It matchesCLAUDE.md's own division of labour: the consoleis for what an operator can act on, the log is the server's diagnostic
channel. Two things to settle before this can be recommended:
/.dmttand
cmtt_get_array()are where these lines would have to remain readable.If it does not, this option collapses into option 1 with extra API surface.
This is the one measurement this issue needs.
wto()hardcodesmcsflags = 0(src/clib/wto.c) and takes no flagsargument, so this means a new entry point in libc370, not an edit.
Not an option: removing the
try()wrapper aroundserve_client. src/httpd.c:1032records why it is there — it would trade worker recovery for a quieter console.
Scope
The fix is not in httpd. Both sites are libc370, and every consumer shares
them — ftpd, mvsmf, ufsd, rexx370, httplua, httprexx. This issue is the decision;
the deliverable is the chosen shape plus an implementing issue filed in libc370,
referencing libc370#17 (consolidate the two
try()wrappers), which touches thesame file and should not be settled twice.
Done when
@@@try.cone, which hasno cheap option channel.