Chapter 3 Quiz: Language Environment Internals
Section 1: Multiple Choice
1. When a COBOL batch program's load module is loaded into memory, what is the first LE component that receives control?
a) The COBOL PROCEDURE DIVISION entry point b) CEEMAIN/CEESTART — the LE main entry point stub c) The z/OS dispatcher's TCB initialization routine d) The COBOL FILE SECTION initialization code
Answer: b) CEEMAIN/CEESTART — the LE main entry point stub
Explanation: The load module's entry point is the LE stub, not the COBOL program's PROCEDURE DIVISION. When the z/OS program loader transfers control to the load module, it branches to CEEMAIN (or CEESTART), which is LE's initialization entry point. CEEMAIN then performs the complete LE initialization sequence — establishing the enclave, creating the thread, allocating heap and stack, allocating and initializing working storage, setting up condition handling — before finally transferring control to the COBOL PROCEDURE DIVISION via the CEEENTRY macro embedded in the compiled COBOL code. This is why LE initialization failures (U4038, U4039) occur before your first COBOL statement executes.
2. What is the correct priority order for LE runtime options, from highest to lowest?
a) PARM → CEEUOPT → CEEDOPT → LE defaults b) CEEUOPT → PARM → CEEDOPT/CEECOPT → LE defaults c) CEEDOPT → CEEUOPT → PARM → LE defaults d) LE defaults → CEEDOPT → PARM → CEEUOPT
Answer: b) CEEUOPT → PARM → CEEDOPT/CEECOPT → LE defaults
Explanation: CEEUOPT has the highest priority because it is assembled and linked directly with the COBOL load module — it represents the program developer's or architect's explicit intent. PARM (from the JCL EXEC statement) is next — it allows operators or schedulers to override installation defaults. CEEDOPT (batch) or CEECOPT (CICS) is the installation-wide default — it provides a baseline. LE's internal hardcoded defaults have the lowest priority and are used only for options not specified anywhere else. Understanding this priority chain is essential for diagnosing option conflicts — if RPTOPTS(ON) shows a setting you didn't expect, the priority chain tells you where to look.
3. In LE terminology, what is an "enclave"?
a) A physical partition of the z/OS address space b) LE's unit of program execution — a main program and all its called subprograms c) A CICS region that is isolated from other regions d) A hardware isolation mechanism enforced by DAT
Answer: b) LE's unit of program execution — a main program and all its called subprograms
Explanation: An enclave is LE's logical boundary around a unit of work. It owns the runtime options, the heap, the condition handling environment, and all open LE-managed files. In batch, one enclave typically corresponds to one job step. In CICS, one enclave corresponds to one task. When an enclave terminates, all of its resources are freed — this is the mechanism that cleans up dynamically called subprograms' working storage, heap allocations, and stack frames. The enclave concept is fundamental to understanding why CALL/CANCEL behavior and storage management work the way they do.
4. What abend code indicates an LE version compatibility failure?
a) S80A b) U4038 c) S0C4 d) U4093
Answer: b) U4038
Explanation: U4038 is LE's "incompatible runtime environment" abend. It occurs during LE initialization when the compiled program's expected LE level does not match the installed LE runtime library. This most commonly happens when a load module compiled with an old Enterprise COBOL compiler is run on a system with a newer LE level (typically after a z/OS upgrade), or when a program compiled for a newer LE is run on a system with an older LE. The fix is always recompilation with the current compiler. At CNB, annual recompilation of all production load modules prevents U4038 abends.
5. Why are LE HEAP and STACK runtime options irrelevant in CICS?
a) CICS doesn't use LE for COBOL programs b) CICS manages per-task storage through its own Dynamic Storage Areas (DSAs) c) CICS programs don't use heap or stack storage d) CICS always uses the LE defaults, which cannot be overridden
Answer: b) CICS manages per-task storage through its own Dynamic Storage Areas (DSAs)
Explanation: In CICS, storage for COBOL programs is allocated from CICS's Dynamic Storage Areas (CDSA, ECDSA, etc.), not from LE-managed heap/stack segments. CICS's preinitialized LE environment bypasses the normal heap/stack allocation that LE would perform in batch. Instead, CICS allocates working storage from its DSA pools and manages the per-task storage lifecycle directly. This is why HEAP and STACK options in CEECOPT or CEEUOPT for CICS programs are ignored — CICS has already taken over that responsibility. The ECDSA size (configured in the CICS SIT) is the equivalent control point.
6. What does TERMTHDACT=TRACE produce when a program abends?
a) A full system dump (SYSUDUMP) b) A CEEDUMP with only the traceback (call chain and statement numbers), without a full storage dump c) No output — TRACE mode suppresses all error messages d) An LE trace file showing every LE function call during the program's execution
Answer: b) A CEEDUMP with only the traceback (call chain and statement numbers), without a full storage dump
Explanation: TERMTHDACT controls the level of diagnostic output when a thread terminates abnormally. TRACE produces the traceback (the call chain showing DSA, Entry, Offset, Statement, and Status for each call level) and the condition information (error type, severity), but does not produce the full storage dump section. This is the recommended production setting because it provides the information needed for initial diagnosis (statement number, call chain, error type) without the overhead and output volume of a full dump. DUMP includes the full storage contents — useful for development. QUIET suppresses all output. MSG produces just the error message.
7. What information does the RPTOPTS(ON) runtime option produce?
a) A report showing which runtime option values are in effect and which source (CEEUOPT, PARM, CEEDOPT) each came from b) A performance report showing CPU time per COBOL paragraph c) A storage report showing heap and stack usage d) A trace of all LE callable service invocations
Answer: a) A report showing which runtime option values are in effect and which source (CEEUOPT, PARM, CEEDOPT) each came from
Explanation: RPTOPTS (Report Options) produces a table listing every active runtime option, its current value, and the source that set it (CEEUOPT, PARM, CEEDOPT/CEECOPT, or LE default). This is invaluable during deployment verification — it confirms that the intended options are actually in effect and identifies any unexpected overrides. For example, if CEEUOPT specifies STORAGE(00,FE,00) but RPTOPTS shows STORAGE(NONE,NONE,NONE), something is wrong with the CEEUOPT link-edit. CNB runs RPTOPTS(ON) on the first production run of every newly deployed program.
8. When a COBOL program in CICS encounters an S0C4, what transaction abend code does CICS issue?
a) AICA b) ASRA c) AEI0 d) AEIO
Answer: b) ASRA
Explanation: ASRA is CICS's transaction abend code for program check conditions (S0C1, S0C4, S0C7, etc.). The sequence is: the hardware generates a program interrupt → z/OS invokes the ESPIE exit → LE's condition handler (if TRAP(ON)) processes the condition and produces a CEEDUMP → LE percolates the condition to CICS → CICS issues ASRA as the transaction abend code. The distinction matters because ASRA tells you the root cause is a program check (not a CICS error), and the CEEDUMP tells you the specific program, statement, and data involved.
Section 2: True/False
9. True or False: A COBOL program compiled with Enterprise COBOL V6.3 can execute without Language Environment on z/OS.
Answer: False
Explanation: Enterprise COBOL generates code that requires LE. The compiled program contains calls to LE routines for working storage initialization, file I/O management, PERFORM stack management, STRING/UNSTRING operations, decimal arithmetic overflow handling, and program termination. Without the LE runtime libraries (SCEERUN/SCEELKED), these calls would branch to non-existent routines and the program would immediately abend. LE is not optional for Enterprise COBOL.
10. True or False: In CICS, each task creates a new LE enclave through the full LE initialization sequence (CEEMAIN → option resolution → heap/stack allocation).
Answer: False
Explanation: CICS uses preinitialized LE environments. At CICS region startup, LE creates a template environment. Each task's enclave is created from this preinitialized template — a much faster process than full initialization. This is essential for performance: CICS may process hundreds or thousands of transactions per second, and full LE initialization (500+ microseconds) for each would consume significant overhead. The preinitialized environment can create an enclave in roughly 10-50 microseconds — a 10x improvement.
11. True or False: CEEUOPT options can be changed without recompiling the COBOL program (only re-linking is needed).
Answer: True
Explanation: CEEUOPT is a separate assembler module that is assembled independently and linked with the COBOL object module. To change CEEUOPT options, you assemble the updated CEEUOPT source and re-link (re-bind) the load module using the linkage editor (IEWL). The COBOL source code does not change, and the COBOL compilation step is not needed. This is why CEEUOPT is a practical configuration mechanism — architects can change runtime options without touching the application source code.
12. True or False: The LE STORAGE(00,FE,00) option initializes all working storage fields to binary zeros, overriding COBOL VALUE clauses.
Answer: False
Explanation: STORAGE(00,FE,00) initializes heap and stack storage to binary zeros BEFORE COBOL VALUE clauses are applied. LE first fills the allocated storage with X'00', then the COBOL initialization code runs and applies all VALUE clauses. Fields with VALUE clauses get their declared values; fields without VALUE clauses remain at X'00'. The VALUE clause always takes precedence. The STORAGE option's value is primarily for fields that do NOT have VALUE clauses — it ensures they contain a predictable value (X'00') rather than whatever happened to be in that storage location previously.
13. True or False: If CEEUOPT specifies TRAP(ON) and the JCL PARM specifies TRAP(OFF), the effective setting is TRAP(OFF) because PARM is more recent.
Answer: False
Explanation: CEEUOPT has higher priority than PARM — not the other way around. The priority order is: CEEUOPT (highest) → PARM → CEECOPT/CEEDOPT → LE defaults (lowest). If CEEUOPT says TRAP(ON), the PARM's TRAP(OFF) is overridden. This is by design: CEEUOPT is linked with the program and represents the architect's intent. PARM is set in JCL and could be changed by anyone who edits the JCL. However, CEEUOPT options can be marked as "overridable" — if an option is specified as overridable in CEEUOPT, then PARM can override it. The default for most options in CEEUOPT is non-overridable.
14. True or False: A CEEDUMP's traceback section should be read from top to bottom to trace the call chain.
Answer: False
Explanation: The traceback should be read from bottom to top. The bottom entry (highest DSA number) is CEEMAIN — the LE entry point. The entries above it represent the call chain in reverse order: the main program called by LE, then subprograms called by the main program, and so on. The top entry (DSA 1 or 2, typically the entry with "Exception" status) is where the failure occurred. Reading bottom-to-top traces the execution path from program start to failure point. The DSA (Dynamic Save Area) numbers increase with call depth.
Section 3: Short Answer
15. In three sentences, explain why CNB recompiles all production COBOL load modules annually, even when the source code has not changed.
Answer: Annual recompilation ensures that all production load modules are compatible with the current LE runtime level, preventing U4038 (LE incompatibility) abends after z/OS upgrades. Each z/OS release includes an updated LE with potential changes to the runtime interface, and old compiled modules may eventually exceed LE's backward-compatibility tolerance. Recompiling with the current compiler produces load modules that match the installed LE level, eliminating the most common preventable LE failure mode.
16. Explain the difference between CEEDUMP and SYSUDUMP. When would you need each?
Answer: CEEDUMP is produced by LE's condition handler (when TRAP(ON) and CEEDUMP=ON) and contains LE-level diagnostic information: the traceback (call chain with statement numbers), condition information (error type and severity), working storage contents in a formatted layout, heap and stack summaries, and register contents mapped to program variables. SYSUDUMP is produced by z/OS when a program abends and contains a raw hexadecimal dump of the address space's storage — useful for very low-level diagnosis but difficult to read without tools like IPCS. You need CEEDUMP for routine COBOL program diagnosis (it gives you the statement number and working storage values directly). You need SYSUDUMP for complex problems like storage overlays where the CEEDUMP's formatted output doesn't show the corruption pattern, or when LE's condition handler itself fails.
17. A developer puts a 5 MB table in LOCAL-STORAGE SECTION instead of WORKING-STORAGE SECTION. Explain the difference in storage behavior and why this matters in CICS.
Answer: LOCAL-STORAGE items are allocated on the LE stack at every invocation and deallocated when the program returns (GOBACK). WORKING-STORAGE items are allocated once per enclave from the heap (reentrant) or user region (non-reentrant) and persist across invocations within the enclave. In CICS, every task invocation allocates a fresh LOCAL-STORAGE copy on the stack. A 5 MB LOCAL-STORAGE table in a program with 200 concurrent CICS tasks consumes 1 GB of stack/DSA storage — and this storage is allocated and freed with every task, creating massive overhead. In WORKING-STORAGE, the same table would be 5 MB × 200 tasks = 1 GB from ECDSA, but allocated once per task rather than once per invocation, and without the stack allocation overhead.
18. What is a preinitialized LE environment, and why does CICS use it?
Answer: A preinitialized LE environment is a template LE execution environment created once at CICS region startup, from which individual task enclaves are quickly instantiated. Without preinitialization, every CICS transaction would require full LE initialization — CEEMAIN, option resolution, heap allocation, stack allocation, condition handler registration — which takes 500+ microseconds. At 500 transactions per second, that's 250,000 microseconds (250ms) per second consumed just by LE initialization. With preinitialization, enclave creation from the template takes only 10-50 microseconds, reducing the overhead by 10x or more. This is essential for CICS's ability to handle high transaction volumes with low latency.
Section 4: Applied Scenario
19. Sandra Chen at Federal Benefits Administration discovers that 23 of her 340 production COBOL programs were compiled with VS COBOL II — a compiler that predates Language Environment. These programs use IGZOPT (the pre-LE runtime option module) instead of CEEUOPT. A z/OS 3.1 upgrade is planned in 6 months.
a) What risk do these 23 programs face during the z/OS upgrade? b) Can IGZOPT-based programs run under the current LE? Under what conditions? c) What is the recommended remediation for each program? d) Marcus Whitfield is retiring in 4 months. How does his departure affect the risk assessment? e) Propose a project plan with milestones for addressing these 23 programs before the z/OS upgrade.
Answer: a) VS COBOL II programs rely on backward compatibility in LE's pre-LE compatibility layer. Each z/OS upgrade reduces this backward compatibility, and z/OS 3.1 may drop support for some VS COBOL II runtime interfaces. The risk is U4038 or S806 (module not found) abends after the upgrade. b) IGZOPT-based programs can run under current LE through LE's compatibility support, which translates old runtime interfaces to current LE equivalents. However, this compatibility layer adds overhead and may have reduced functionality (no CEEDUMP, limited diagnostics). c) The recommended remediation is recompilation with Enterprise COBOL V6.3+, which replaces IGZOPT with CEEUOPT and fully integrates with current LE. For programs without source code, LE's compatibility mode is the only option — but these must be tested against the z/OS 3.1 LE level. d) Marcus Whitfield's departure is critical: he likely knows which of the 23 programs have source code available, which have hidden dependencies (below-the-line storage, OS macros, non-standard CALLs), and which can be safely recompiled without regression risk. His knowledge must be documented before his departure. e) Project plan: Month 1: Marcus documents all 23 programs (source availability, dependencies, risk). Month 2: Recompile the 10 lowest-risk programs; test against z/OS 3.1 LE in a test LPAR. Month 3: Recompile the next 8 programs with Marcus's guidance. Month 4 (Marcus's last month): Address the 5 highest-risk programs; Marcus reviews all recompiled modules. Month 5: Full regression testing of all 23 programs on z/OS 3.1 test environment. Month 6: z/OS upgrade proceeds with all 23 programs verified.
20. Yuki Nakamura at SecureFirst Retail Bank has deployed a new COBOL program that handles mobile banking API calls via z/OS Connect. The program is called 5,000 times per second at peak. After deployment, the z/OS Connect server's JVM heap is growing at 2 MB per minute and eventually causes an OutOfMemoryError.
a) The COBOL program uses dynamic CALL to invoke a subprogram. Could this be related to the memory growth? How? b) The COBOL program has ABTERMENC=RETCODE. Could this mask a problem that contributes to memory growth? c) What LE diagnostic options would you enable to investigate? d) If the problem is an LE storage leak in the COBOL enclave, how would the enclave lifecycle (creation and destruction per API call) normally prevent leaks? e) Under what circumstance would LE enclave termination NOT clean up all storage?
Answer: a) Dynamic CALL in an API-invoked COBOL program creates an LE enclave for each invocation. If the subprogram is loaded but not properly released (e.g., no CANCEL, and the enclave terminates without proper cleanup), LE should still clean up at enclave termination. However, if the z/OS Connect server reuses LE enclaves (persistent connection mode), the subprogram's working storage may accumulate across invocations. The 2 MB/minute growth suggests storage is being allocated but not freed within the enclave. b) ABTERMENC=RETCODE means errors return a non-zero return code instead of abending. If the COBOL program encounters errors but continues processing (returning RC=0 to z/OS Connect), LE condition handling may allocate diagnostic storage internally without freeing it — especially if conditions are being handled and resumed rather than terminating the enclave. c) Enable RPTSTG(ON) for a limited sample of requests; enable HEAPCHK(ON) to detect heap corruption; enable STORAGE(00,FE,00) to track freed storage usage. d) Normal enclave termination frees all heap segments, stack segments, and LE-managed allocations. Each API call creates and destroys an enclave, so storage should not accumulate between calls. This is LE's primary cleanup mechanism. e) Enclave termination would NOT clean up storage allocated outside of LE's management — for example, storage obtained via direct GETMAIN (bypassing LE), storage in the z/OS Connect server's JVM heap allocated by the COBOL-to-Java interface, or coupling facility structures. The 2 MB/minute growth in the JVM heap suggests the leak is on the Java side of the z/OS Connect interface, not in the COBOL/LE enclave — possibly a JSON conversion buffer that isn't being freed after each API response is sent.