What it means
Every machine instruction starts with an operation code. When the processor fetches an operation code it doesn't recognize, it raises an operation exception, program interrupt code 1, and z/OS ends the step with system completion code 0C1.
The bytes at the failure point usually aren't code at all, so the useful question is how the program got there.
One cause is different. Compilers such as Enterprise COBOL pick instructions according to the ARCH option, so a program compiled for a newer processor can contain instructions an older machine doesn't have. Those fail with S0C1 even though the code is correct.
Common causes
- A CALL to a subprogram that wasn't resolved at link-edit time. The binder flagged the symbol as unresolved but saved the module as executable anyway, so the CALL branches to address zero.
- An assembler program, or one built by an old compiler, did a GET or PUT on a file that never opened, usually because its DD statement is missing.
- Storage was overwritten. A table that runs past its end, or a move into the wrong area, can destroy a saved return address or a branch table. When the program later branches through it, it lands on data.
- An assembler routine ran off the end of its code into its constants or work areas because a branch or return was missing.
- The program was compiled with an ARCH level higher than the processor it runs on supports.
How to find the problem
- Read the IEA995I symptom dump or the CEE3201S message. Note the PSW address, the instruction length (ILC), and the load module name and offset.
- If the PSW address is very low, such as 00000002, the program branched to zero. Check register 15 in the dump. If it's zero too, a CALL went to a routine that was never resolved, so look for unresolved symbols in the binder listing (IEW2454W or IEW2456E).
- Register 14 usually holds the return address of the last call. Map it back to the calling program's listing to see which CALL led to the failure.
- If the PSW points inside your program, subtract the ILC from the offset and find that spot in the compiler listing made with LIST or OFFSET. If the spot is in the middle of data, look for whatever overwrote the code or the branch address.
- Check that every DD statement the program uses is in the step. The IEF237I messages in the job log show which DD names were allocated.
- If the failing instruction looks valid, compare the ARCH option in the compiler listing with the processor the job ran on.
How to fix it
- Link-edit the program again with the missing subprogram included, or with the right library in SYSLIB, and make the link step fail when a symbol is unresolved.
- Add the missing DD statement, and check the result of every OPEN (the file status in COBOL) so a missing file is reported clearly.
- Find and fix the storage overlay. In COBOL, compiling with SSRANGE in test catches table overruns as they happen.
- Recompile with an ARCH level that matches the oldest processor the program must run on, including the disaster recovery site.
What it looks like
IEA995I SYMPTOM DUMP OUTPUT
SYSTEM COMPLETION CODE=0C1 REASON CODE=00000001
PSW AT TIME OF ERROR 078D1000 80000002 ILC 2 INTC 01
NO ACTIVE MODULE FOUND
CEE3201S The system detected an operation exception (System Completion Code=0C1).
IEF450I INVRUN02 STEP010 - ABEND=S0C1 U0000 REASON=00000001