Troubleshooting
Problem
Why does an IBM i job running an application fail with MCH3402
Symptom
Why does an IBM i job running an application fail with MCH3402.
Message . . . . : Tried to refer to all or part of an object that no longer exists.
Message ID . . . . . . : MCH3402 Severity . . . . . . . : 40
Date sent . . . . . . : 03/11/21 Time sent . . . . . . : 12:58:37
Message type . . . . . : Escape
From . . . . . . . . . : BIMBRA CCSID . . . . . . . . : 65535
From program . . . . . . . . . : QRNXIO
From library . . . . . . . . : QSYS
From module . . . . . . . . : QRNXDBIO
From procedure . . . . . . . : _QRNX_DB_SETPOSN
From statement . . . . . . . : 7
To program . . . . . . . . . . : QRNXIO
To library . . . . . . . . . : QSYS
To module . . . . . . . . . : QRNXDBIO
To procedure . . . . . . . . : _QRNX_DB_SETPOSN
To statement . . . . . . . . : 7
Date sent . . . . . . : 03/11/21 Time sent . . . . . . : 12:58:37
Message type . . . . . : Escape
From . . . . . . . . . : BIMBRA CCSID . . . . . . . . : 65535
From program . . . . . . . . . : QRNXIO
From library . . . . . . . . : QSYS
From module . . . . . . . . : QRNXDBIO
From procedure . . . . . . . : _QRNX_DB_SETPOSN
From statement . . . . . . . : 7
To program . . . . . . . . . . : QRNXIO
To library . . . . . . . . . : QSYS
To module . . . . . . . . . : QRNXDBIO
To procedure . . . . . . . . : _QRNX_DB_SETPOSN
To statement . . . . . . . . : 7
The From/To modules and procedure names seen above, might be different depending on the file operation that was in use by the application.
Cause
The following prelude is credited to Jon Paris and Susan Gantner who published a document in 2004 titled The Seven Deadly Sins of ILE.
The link to the full article is https://authory.com/JonParisAndSusanGantner/The-Seven-Deadly-Sins-of-ILE
First deadly sin: Allowing "real" ILE programs to run in the default activation group.
What do we mean by "real" ILE programs? These are programs that are created either via the CRTxxxMOD and CRTPGM commands or by specifying DFTACTGRP(*NO) to one of the CRTBNDxxx commands (where xxx is RPG or CL). Note that for the purposes of this discussion, programs created with the CRTBNDxxx default of DFTACTGRP(*YES) arent considered to be ILE programs; they are instead original program model (OPM)-compatible programs, and therefore arent bound by any of our ILE rules.
The default activation group (sometimes called DAG) is designed specifically for OPM programs and is the only activation group where these programs can run. You cannot directly request that your ILE programs run in the DAG, but if you specify *CALLER for the activation group parameter and subsequently call the program from an OPM program, your ILE program will run in the DAG. This is contrary to ILEs design (IBMs original intent was that ILE programs not be permitted to run in the DAG at all) and will eventually cause problems of some sort.
Second deadly sin: Using service programs in the DAG.
The default activation group (sometimes called DAG) is designed specifically for OPM programs and is the only activation group where these programs can run. You cannot directly request that your ILE programs run in the DAG, but if you specify *CALLER for the activation group parameter and subsequently call the program from an OPM program, your ILE program will run in the DAG. This is contrary to ILEs design (IBMs original intent was that ILE programs not be permitted to run in the DAG at all) and will eventually cause problems of some sort.
Second deadly sin: Using service programs in the DAG.
Many shops commit the first deadly sin and run their ILE programs in the DAG. If you happen to work in one of these shops, you can avoid some of the most serious problems by running your service programs in their own named activation group(s). Service programs are more prone to problems when running in the DAG, particularly if the Reclaim Resource (RCLRSC) command is run while the service program is active with files open. While RCLRSC is often used specifically to close open files, the command doesnt notify the service program logic that the files are closed. This leaves the application in a Catch 22 situation: The files are closed, but the procedures in the service program believe they are still open.
Diagnosing The Problem
This document presents a prototype to help illustrate how the MCH3402 message can surface.
The prototype consists of ILE RPG program TESTPGM1 and an ILE RPG service program TESTSRV1.
Both are compiled in the *CALLER activation group. When called from the command line, they will then run in the OPM default activation group.
Both are compiled in the *CALLER activation group. When called from the command line, they will then run in the OPM default activation group.
The program invokes a function named myfile, which resides in the service program.
The function simply reads the file, if a record is found, it updates a field with the current timestamp.
NOTE: The service program is not using LR to close the file. The program is using RETURN.
This is a common technique in large scale applications. It saves the expense of closing and opening files and re-initializing program storage every time a function in the service program is invoked.
Use SQL to setup the library and database file
- CREATE COLLECTION TESTLIB1
- CREATE TABLE TESTLIB1/SOMEFILE (CLASS CHAR ( 5), STATUS NUMERIC ( 1,0), EFFDATE TIMESTAMP)
- INSERT INTO TESTLIB1/SOMEFILE (CLASS, STATUS, EFFDATE) VALUES('FIRST', '1', current date) WITH NC
The database file is named SOMEFILE:
CLASS | STATUS | EFFDATE |
FIRST | 1 | 2021-03-11 12:58:16.867210 |
Create a source file in library TESTLIB1
CRTSRCPF FILE(TESTLIB1/MYSOURCE) RCDLEN(112)
CRTSRCPF FILE(TESTLIB1/MYSOURCE) RCDLEN(112)
Add source member TESTSRV1
Ctl-Opt nomain;
Dcl-F SOMEFILE DISK(*EXT) Usage(*input:*UPDATE)
rename(SOMEFILE:SOMERCD);
Dcl-PR myfile Char(1);
myflg Char(1);
End-PR;
Dcl-Proc myfile export;
Dcl-PI myfile Char(1);
myflg Char(1);
End-PI;
Dcl-S rtnflg Char(1);
setll *start somefile;
Read SOMERCD;
If not %eof;
EFFDATE = %timestamp(*sys);
dsply (%timestamp(EFFDATE));
Update SOMERCD;
rtnflg = 'Y';
elseif %eof;
rtnflg = 'N';
EndIf;
Return rtnflg;
End-Proc myfile;
- addlible testlib1
- CRTRPGMOD MODULE(TESTLIB1/TESTSRV1) SRCFILE(TESTLIB1/MYSOURCE) SRCMBR(TESTSRV1)
- CRTSRVPGM SRVPGM(TESTLIB1/TESTSRV1) EXPORT(*ALL) ACTGRP(*CALLER)
Add source member TESTPGM1
Dcl-PR myfile Char(1);
myflg Char(1);
End-PR;
Dcl-S myflg Char(1);
myflg = myfile(myflg);
Dsply ('File updated? ' + myflg);
Return;
- CRTRPGMOD MODULE(TESTLIB1/TESTPGM1) SRCFILE(TESTLIB1/MYSOURCE) SRCMBR(TESTPGM1)
- CRTPGM PGM(TESTLIB1/TESTPGM1) BNDSRVPGM((TESTLIB1/TESTSRV1)) ACTGRP(*CALLER)
Run the program:
> call testpgm1
DSPLY 2021-03-11-14.58.27.695666
DSPLY File updated? Y
Use DSPJOB option 14. Display open files, if active.
The database file SOMEFILE is open.
Member/ Record File I/O ----Open--- Relative
File Library Device Format Type Count Opt Shr-Nbr Record
QDUI132 QSYS QPADEV000H USRRCD DSP 15 IO NO
SOMEFILE TESTLIB1 SOMEFILE SOMEFILE PHY 3 IO NO 1
QDDSPEXT QSYS QPADEV000H INFFMT DSP 15 IO NO
QDDSPOF QSYS QPADEV000H DETAIL2 DSP 12 IO NO
Now issue Reclaim Resource (RCLRSC) command. While RCLRSC is often used specifically to close open files, the command does not notify the service program logic that the files are closed. This leaves the application in a Catch 22 situation: The files are closed, but the procedures in the service program believe they are still open.
When the program is called again following a RCLRSC , the result will be an MCH3402.
> call testpgm1
Tried to refer to all or part of an object that no longer exists.
Call stack entry not found.
Exception recursion detected.
Application error. *N unmonitored by *N at statement *N, instruction X'4000'.
Joblog shows the message details:-
Tried to refer to all or part of an object that no longer exists.
Call stack entry not found.
Exception recursion detected.
Application error. *N unmonitored by *N at statement *N, instruction X'4000'.
Joblog shows the message details:-
*NONE Request 03/11/21 15:07:50.665771 QMHGSD QSYS 07CF QCMD QSYS 0195
Message . . . . : -rclrsc
*NONE Request 03/11/21 15:10:58.474699 QMHGSD QSYS 07CF QCMD QSYS 0195
Message . . . . : -call testpgm1
MCH3402 Escape 40 03/11/21 15:10:58.474898 QRNXIO QSYS *STMT QRNXIO QSYS *STMT
From module . . . . . . . . : QRNXDBIO
From procedure . . . . . . : _QRNX_DB_SETPOSN
Statement . . . . . . . . . : 7
To module . . . . . . . . . : QRNXDBIO
To procedure . . . . . . . : _QRNX_DB_SETPOSN
Statement . . . . . . . . . : 7
Message . . . . : Tried to refer to all or part of an object that no longer
exists.
Cause . . . . . : The most common cause is that a stored address to an
object is no longer correct because that object was deleted or part of the
object was deleted.
CPF2479 Escape 40 03/11/21 15:10:58.475047 QMHSNDPM QSYS 0C9E QRNXIE QSYS *STMT
To module . . . . . . . . . : QRNXMSG
To procedure . . . . . . . : SignalException
Statement . . . . . . . . . : 20
Message . . . . : Call stack entry not found.
Cause . . . . . : Call stack entry _QRNI_NOMAIN, specified for the send,
receive, move or delete message operation, could not be found in the call
stack. Recovery . . . : Change the call stack entry name or be sure the
specified entry is in the call stack when doing the requested operation.
CEE3201 Diagnostic 10 03/11/21 15:10:58.475163 QLEAWI QSYS *STMT QRNXIE QSYS *STMT
From module . . . . . . . . : QLEDEH
From procedure . . . . . . : Q LE leDefaultEh2
Statement . . . . . . . . . : 72
To module . . . . . . . . . : QRNXERR
To procedure . . . . . . . : _QRNX_UNEXP
Statement . . . . . . . . . : 11
Message . . . . : Exception recursion detected.
Cause . . . . . : An unhandled exception occurred in an exception handler.
Recovery . . . : Do not let an exception that occurs in your exception
handler go unhandled.
CEE9901 Escape 30 03/11/21 15:10:58.475218 QLEAWI QSYS *STMT QCMD QSYS 01C8
From module . . . . . . . . : QLETOOL
From procedure . . . . . . : Q LE AWIRaise
Statement . . . . . . . . . : 176
Message . . . . : Application error. *N unmonitored by *N at statement *N,
instruction X'4000'.
Cause . . . . . : The application ended abnormally because an exception
occurred and was not handled. The name of the program to which the
unhandled exception is sent is *N *N . The program was stopped at the
high-level language statement number(s) *N at the time the message was sent.
If more than one statement number is shown, the program is an optimized ILE
program. Optimization does not allow a single statement number to be
determined. If *N is shown as a value, it means the real value was not
available. Recovery . . . : See the low level messages previously listed
to locate the cause of the exception. Correct any errors, and then try the
request again.
Resolving The Problem
To resolve the issue there are three options:
1: Remove the RCLRSC command call.
1: Remove the RCLRSC command call.
2: Close files every time you exit a program or service program, or modify the program so that when called with (say) no parameters it will close its files. This is actually quite a common technique when the other alternatives are not an option and a hard close on exit each time is too costly. The program would be called in this way prior to the RCLRSC.
3: Run the programs and service programs in named activation groups.
Document Location
Worldwide
[{"Line of Business":{"code":"LOB57","label":"Power"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG60","label":"IBM i"},"ARM Category":[{"code":"a8m0z0000000CHtAAM","label":"Programming ILE Languages"}],"ARM Case Number":"TS005105587","Platform":[{"code":"PF012","label":"IBM i"}],"Version":"All Version(s)"}]
Was this topic helpful?
Document Information
Modified date:
08 March 2024
UID
ibm16428061