1.5 KiB
§93 — set -o pipefail attributes a pipeline failure to the LAST stage, not the failing one (Phase 29 SESSION-21, func_8014D820)
The c-rule is cpp | cc1 | maspsx | [jtbl_rodata_pads] | as under set -o pipefail. When cc1
exits 33, make reports the failure against the object whose recipe ends in as — so the error
reads as an assembler problem. I recorded func_8014D820 as an "assembler-stage failure" on that
basis and left it undiagnosed for hours. It was conflicting types for 'Ent' against
engine_types.h:434, fixed by moving three types to BLOCK scope (byte-neutral, and collision-proof
across all 138 member TUs).
The diagnostic, ~2 minutes: run the stages by hand and print each rc.
cpp … > t.i ; echo "cpp rc=$?"
cc1 … < t.i > t.s ; echo "cc1 rc=$?" # <- the real failure surfaces here
maspsx … < t.s ; echo "maspsx rc=$?"
as … ; echo "as rc=$?"
Then re-run the failing stage alone with stderr visible — cc1 names the file, line and symbol in
one sentence. This turned an opaque Error 33 into a one-line fix twice in one session
(func_8012AAAC's too few arguments, and this).
Corollary (§88e, earned): when handing a stuck function to another agent, pass the failure as what it IS — an undiagnosed observation — not as a named cause. I flagged this one explicitly as "never diagnosed, re-derive," and the agent found the true cause immediately. Had I written "assembler-stage failure" as established fact, it would have inherited my wrong search space.