Cobol 如何在一个简单的程序中修复U4038

Cobol 如何在一个简单的程序中修复U4038,cobol,mainframe,zos,Cobol,Mainframe,Zos,我正在尝试在z/OS大型机系统上执行一个简单的COBOL程序。该程序只打开和关闭一个文件。它编译时没有错误,但当我运行它时,我得到一个U4038abend 这是程序的代码: ----+-*A-1-B--+----2----+----3----+----4----+----5----+----6----+----7-|--+----8 IDENTIFICATION DIVISION. PROGRAM-ID. LISTKSDS AUTHOR. Test

我正在尝试在z/OS大型机系统上执行一个简单的COBOL程序。该程序只打开和关闭一个文件。它编译时没有错误,但当我运行它时,我得到一个
U4038
abend

这是程序的代码:

----+-*A-1-B--+----2----+----3----+----4----+----5----+----6----+----7-|--+----8
        IDENTIFICATION DIVISION.
        PROGRAM-ID. LISTKSDS
        AUTHOR. TestingUser

        ENVIRONMENT DIVISION.
        CONFIGURATION SECTION.
        INPUT-OUTPUT SECTION.
        FILE-CONTROL.
           SELECT INFILE ASSIGN TO DATAIN
             ORGANIZATION IS INDEXED
             ACCESS MODE IS SEQUENTIAL
             RECORD KEY EST-KEY
             FILE STATUS IS WS-FILE-STATUS.

        DATA DIVISION.
        FILE SECTION.
        FD INFILE.
        COPY EST01.

        WORKING-STORAGE SECTION.
        01 VARIABLES.
           05 WS-FILE-STATUS    PIC X(2).

        LINKAGE SECTION.

        PROCEDURE DIVISION.
             DISPLAY "STARTING PROGRAM.."
             PERFORM INITIALIZATION
             PERFORM TERMINATION
             GOBACK.

        INITIALIZATION.
             DISPLAY "OPENING FILE.."
             OPEN INPUT INFILE
             IF WS-FILE-STATUS IS NOT EQUAL TO '00'
             THEN
             GO TO ERROR-EXIT
             END-IF.

        TERMINATION.
             CLOSE INFILE.

        ERROR-EXIT.
要编译的作业:

//TESTUSEC  JOB NERT4587,CLASS=C,MSGCLASS=X,NOTIFY=&SYSUID
//*
//STEP1   EXEC IGYWCL,PARM=(LIB)
//SYSLIB DD DSN=TES.COPIES.TEST,DISP=SHR
//COBOL.SYSIN DD DSN=TES.SOFT.SRC(SRC04),DISP=SHR
//LKED.SYSLMOD DD DISP=SHR,DSN=TES.SOFT.LIB
//LKED.SYSIN   DD *
   ENTRY LISTKSDS
   NAME  LISTKSDS(R)
/*
//*
要提交的作业:

//TESTUSEC  JOB NERT4587,CLASS=C,MSGCLASS=X,NOTIFY=&SYSUID
//*
//JOBLIB  DD DSN=TES.SOFT.LIB,DISP=SHR
//*
//STEP1   EXEC PGM=LISTKSDS,REGION=2M
//DATAIN  DD DSN=TES.VS.TEST,DISP=SHR
//*

A
U4038
abend是一种来自语言环境的用户abend,它是大型机程序的“运行时”(它支持多种大型机语言)

你有更多关于这方面的信息。如果您查看滑阀输出,我希望您能够找到更多信息

您已在SELECT上为文件指定了一个FILE STATUS子句,因此U4038不太可能与文件相关

但是,很可能是文件问题导致了此程序问题

这可能就是问题所在。如果不是问题,那就是问题:

我怀疑您在WS-FILE-STATUS中得到的是非零。包含此内容的段落是
PERFORM
ed,而
转到
则超出了PERFORM的范围。测试非零值文件状态时,最好显示遇到的非零值

在表演范围之外使用GO TO尤其糟糕。您的程序将从GO TO的目标段落继续,并继续按顺序进入下一个代码

您没有“下一个代码”。所以这个节目“从结尾掉下来”。这不是一个有效的做法,所以你会得到一个异常终止

虽然我们看不到copybook的内容,但给出假定的非零文件状态的东西可能介于文件定义和您在DATAIN DD语句中指定的文件之间

很可能是程序中定义的数据大小与JCL中指定的文件不匹配,或者程序中定义的键与JCL中的文件不匹配

您需要在假脱机输出中找到附加消息。这通常会有很大帮助。如果无法从中获得,请粘贴步骤中的整个SYSOUT输出

您使用的是最少数量的句号/句点,但最好将它们放在第12列中自己的一行,这样它们就不会附加到任何代码中。这样,您就无法复制代码,并意外地在错误的地方出现句号/句号

您还将收到编译器诊断,因为您的错误退出不包含任何代码。始终查看您的邮件并相应地更正代码

还要注意压痕。它对编译器没有意义,但是您为人类读者格式化了代码,因此请注意,因为您永远不知道稍后什么时候会是您,或者凌晨2点是您的队友。或者你的导师/导师在回顾你的工作


在linkedit/bind上指定了DISP=SHR。请把它改成DISP=OLD。如果您设法同时运行两个LinkedIt,您可能会丢弃您的库。

还注意到您没有
//SYSOUT DD SYSOUT=?
在哪里?是您应该用于输出的内容(站点定义)。这意味着您的作业有两个假脱机条目(具有相同的作业编号),您的显示输出可能在第一个条目中,也可能在语言环境消息中。谢谢Bill。我取消了GO-TO并更改了WS-FILE-STATUS的显示值。它给出的是数字35而不是0。注意:我举的例子来自:它似乎有相同的错误吗?我在寻找错误编号35,但该文件存在,并且JCL中的DD语句看起来很好:S。@Nico是的,你的例子不走运。如果您查看该错误段落中的注释,您应该查看另一个程序。我将进一步解释为什么在企业COBOL中使用GO to out of PERFORM仍然是一件坏事。对于为什么要使用35,我们必须查看实际运行的JCL,它位于spool输出的文件2、文件3输出(消息)和您收到的SYSOUT中。将这些输出粘贴到您的问题中。还要检查您的DSN是否是VSAM数据集,并确认这一点。我在一些MVS论坛上找到了答案。如果vsam存在,但它是空的(如我的情况),则文件状态仍然等于35。我把一些记录放进了,现在可以正常工作了:)。但这让我提出了一个新的问题,什么是文件是空的,我想在我的程序中放一些记录?我会在测试的时候发现的。
         IF WS-FILE-STATUS IS NOT EQUAL TO '00'
         THEN
         GO TO ERROR-EXIT
         END-IF.