CEE3201S: Operation exception (0C1) under Language Environment
CEE3201S means Language Environment caught an operation exception, system completion code 0C1. The processor tried to run something that isn't a valid instruction, usually because the program branched to the wrong place.
Other names for this code
Also written as CEE3201, CEE3201S 0C1, CEE3201S operation exception, CEE3201S S0C1, LE 0C1, CEE341.
What it means
When a COBOL, PL/I or C program running under Language Environment (LE) hits a program check, LE traps it and writes a message for it. CEE3201S is the one for an operation exception. The message says the system detected an operation exception and gives system completion code 0C1. The line under it names the compile unit, the entry point and the offset.
An operation exception means the bytes the processor tried to run as an instruction have an operation code it doesn't know. Either the code is unassigned, or the instruction isn't available on this machine. In practice the program has almost always jumped somewhere it shouldn't, such as address zero or the middle of a data area. Less often, the program really does contain an instruction the processor doesn't have.
IBM's advice starts with registers 14 and 15. If register 15 is zero, the program most likely called a routine that wasn't there and branched to location zero. Register 14 holds the return address, so it shows where the call was made from. LE ends the thread unless a handler deals with the condition. The symbolic feedback code is CEE341.
Common causes
- A static CALL to a subprogram that was never resolved at link-edit or bind time. The address of the missing routine is zero, so the CALL branches to location 0.
- A program was compiled with an ARCH level higher than the machine it runs on, so it uses instructions this processor doesn't support. This often shows up when a load module built on a new machine is run at a disaster recovery site with older hardware.
- A storage overlay wrote data over the program's code or over a saved return address, and a later branch went into that data.
- A procedure pointer or an entry variable held a bad value when the program called through it.
- A caller and called program disagree on addressing mode, so an address is cut short and the branch lands in the wrong place.
How to find the problem
- Read the line under CEE3201S for the compile unit and offset. If LE can't name a compile unit, the program probably branched outside any known code, often to location 0.
- Look at registers 14 and 15 in the CEEDUMP or in the IEA995I symptom dump. Register 15 at zero, with register 14 pointing into a program, means that program called something that wasn't there.
- Check the linkage editor or binder map for the load module. Look for unresolved external references (the IEW messages flag them), and for the name the failing CALL used.
- If the module is resolved, compare the program's ARCH compile option with the processor model it ran on.
- Use the traceback in the CEEDUMP to see which routine was active and which one called it.
How to fix it
- Relink or rebind the load module with the missing subprogram included, or make the call dynamic so the routine is loaded at run time. Treat unresolved-reference warnings in the bind as errors.
- Recompile with an ARCH level that matches the oldest machine the program has to run on, including any recovery site.
- If the cause is an overlay, find the statement that wrote past its field, usually a subscript or a MOVE into a LINKAGE SECTION item that is longer than what the caller passed.
- Check that procedure pointers are set before use and that every program in the call chain runs in a compatible AMODE.
What it looks like
CEE3201S The system detected an operation exception (System Completion Code=0C1).
From compile unit PAYCALC at entry point PAYCALC at compile unit offset +00000B2C
IEF450I PAYRUN01 STEP020 - ABEND=S0C1 U0000 REASON=00000001IBM documentation
IBM documentation: CEE3201S. Use the documentation for your installed release.
Related codes
Questions
What does it mean when register 15 is zero?
The program most likely called a routine that wasn't there and branched to location zero. That usually means a CALL to a subprogram that wasn't linked into the load module.
Is CEE3201S the same as S0C1?
Yes. S0C1 is the system completion code for the operation exception. CEE3201S is how Language Environment reports it, with the program name and offset added.
Why did a program that works in production fail at our recovery site?
Check the ARCH compile option. Code built for a newer processor can contain instructions an older machine doesn't have, and those raise an operation exception.