COBOL Troubleshooting
Reference modification length error
Troubleshooting guide for Reference modification length error. "Works in test, fails in production" is an environment problem, not a code problem — the code is identical, so something around it differs.
What it means
- Test and production differ in data volume, data content, compiler options, load libraries, and JCL — any of these can change behavior.
- Compiler options like SSRANGE, NUMPROC, and TRUNC change runtime semantics; a program compiled differently is a different program.
- Language Environment condition handling can swallow the real abend and report a secondary one, sending diagnosis down the wrong path.
Common causes
- Production input contains data values never seen in test (bad signs, extreme values, unexpected characters).
- Different compiler options between test and production builds: e.g. TRUNC(BIN) vs TRUNC(OPT) changes binary arithmetic results.
- NUMPROC(PFD) vs NUMPROC(NOPFD): with PFD, invalid sign nibbles are tolerated; with NOPFD the same data abends S0C7.
- LE condition handler (CEEHDLR) or an ESTAE routine catches the abend, logs something vague, and continues — hiding the original offset.
- Production runs a stale load module: the source was fixed and tested, but the production load library still has the old build.
- JCL differences: different DSNs, DISP, or DCB between test and production JCL for the "same" job.
- Data volume: a table that fits in memory in test overflows in production, or a loop that is fast on 1,000 records never ends on 10 million.
How to diagnose
- Compare the compiler listings: check the options line (SSRANGE, NUMPROC, TRUNC, OPT) on both builds — they must match.
- Verify the production load module date (ISPF 3.4 or AMBLIST) against the last compile — a stale module is the classic cause.
- Diff the test JCL against the production JCL: every DD name, DSN, DISP, and DCB parameter.
- Get the real abend offset from SYSUDUMP/SYSABEND, not from the LE handler message — map the offset in the compiler listing.
- Reproduce with production data (sanitized) in test; if it fails there too, it is a data problem, not an environment problem.
How to fix it
- Standardize compiler options in one PROC used for every environment; never hand-compile production modules.
- Rebuild and promote the load module through the change process so test and production run the identical binary.
- Register the LE condition handler to log the original abend code and PSW offset before doing anything else.
- Align test JCL with production JCL via shared PROCs and symbolic parameters instead of two maintained copies.
- Add production-like data volumes and edge-case data to the test bed.
Example: LE condition handler that preserves the real abend
CALL "CEEHDLR" USING WS-HANDLER-TOKEN WS-FEEDBACK
ON EXCEPTION DISPLAY "NO LE HANDLER"
END-CALL.
*
* In the handler, FIRST capture the original condition:
* CEE3SRP -> signal information (abend code)
* then log it before any recovery action.
Log the original abend code and offset first — a handler that recovers silently destroys the evidence.
Interview tip
- Q: A program passes all tests but abends S0C7 on its first production run. The code is identical. What is your first suspect?
- A: The data or the build. I check whether production input contains values test never had, then verify the production load module is the freshly compiled one and that compiler options like NUMPROC match — NUMPROC(PFD) in test can hide bad sign nibbles that abend under NOPFD in production.
Prevention checklist
- One build PROC with fixed compiler options for all environments.
- Promote the tested binary; never recompile separately for production.
- Keep test data that mirrors production edge cases, refreshed regularly.
- Log original abend codes in every LE handler before recovery.
