System abend

S0C2: Privileged operation exception

An S0C2 abend means a program running in problem state tried to execute an instruction that only supervisor-state code may use. In an application program it almost always means the program branched into data or into damaged code.

Other names for this code

Also written as 0C2, SOC2, abend 0C2, system abend 0C2, S0C2-2, privileged operation exception, privileged-operation exception.

What it means

The processor runs every program in one of two states. Supervisor state is for the operating system and for authorized code that needs it. Problem state is for everything else, including ordinary batch and online programs. Some instructions are privileged, such as the ones that load a whole new PSW or set storage keys, and the processor refuses to run them in problem state. When a problem-state program tries one, the processor raises a privileged-operation exception, program interruption code 2. z/OS ends the task with system completion code 0C2 and reason code 2.

A few instructions are semiprivileged. Problem-state code may use them only when control bits in the PSW or the control registers allow it. Breaking that rule raises the same exception.

Compilers for COBOL, PL/I and C don't put privileged instructions into application code. So when one of these programs gets an S0C2, the bytes the processor tried to run were almost never meant as an instruction. The program branched to an address that holds data, or into code that had been overwritten, and the processor decoded those bytes as a privileged instruction.

Common causes

  • A branch to a bad address. A return address in a save area was overwritten, a called program's entry address was wrong, or the program called through a procedure pointer or entry variable that was never set.
  • The caller and the called program disagree about the parameter list, so the called program treats a data field as an address and branches through it.
  • A table overrun or other storage overlay wrote over a save area, register save slot or non-reentrant code.
  • An assembler routine issues a privileged instruction while in problem state, for example after switching back with MODESET MODE=PROB.
  • Code written to run authorized was run from a library or environment where it doesn't get that authority.

How to find the problem

  1. Find CEE3202S (Language Environment) or the IEA995I symptom dump in the job log. Note the PSW address, the instruction length code (ILC), and the load module name and offset if one is shown.
  2. Check whether the failing address lies inside a program at all. If the dump can't place it in any load module, or it lands in a data area of your program, the program branched somewhere it shouldn't have.
  3. Read registers 14 and 15 in the dump. Under the standard linkage they hold the return address and the entry address of the last call, which often show where the bad branch came from. The Language Environment traceback in CEEDUMP lists the calling sequence.
  4. Display the bytes just before the PSW address. If they look like character data, a table or a record, you're looking at a wild branch, not a real instruction.

How to fix it

  • Fix the source of the bad address. Set every procedure pointer before calling through it, and make the caller's CALL USING list match the called program's PROCEDURE DIVISION USING list.
  • Recompile and relink every program that shares a changed copybook or parameter layout, so no caller passes an old layout.
  • Add range checks to subscripts, or compile with SSRANGE in test, so a table overrun can't overwrite save areas.
  • In assembler, issue privileged instructions only in supervisor state, and keep register 14 and the save area chain intact across calls.
  • If the failing code belongs to IBM or a vendor product, search for a fix (APAR or PTF) and send the dump with your problem report.

What it looks like

IEA995I SYMPTOM DUMP OUTPUT
  SYSTEM COMPLETION CODE=0C2  REASON CODE=00000002
IEF450I ORDENTRY STEP010 - ABEND=S0C2 U0000 REASON=00000002

IBM documentation

IBM z/OS: 0Cx program interruptions. Use the documentation for your installed release.

Report a correction to WND Software.

Questions

Can a COBOL program contain a privileged instruction?

No. The compiler doesn't generate privileged instructions for application code. An S0C2 in a COBOL program means it branched into data or into code that was overwritten.

What is the difference between S0C1 and S0C2?

S0C1 means the bytes aren't a valid instruction for this processor. S0C2 means they are a valid instruction that problem-state code may not use. Both usually come from the same kind of wild branch.

How does S0C2 show up in CICS?

As the transaction abend ASRA. The CICS transaction dump shows the program check with interrupt code 2.