如果我在JZOS启动程序中设置了一个环境变量
导出JZOS_ABEND_EXIT=50
然后在Java代码中调用System.exit(51)
,程序将按如下方式终止:
IEF450I MYPROG JAVAJVM创建- ABEND=S000 U3333 REASON=00000010
是否可以指定abend代码,例如使其为U999而不是U3333。我在如何触发用户ABEND?中找到了一个关于LE abend例程‘如何触发用户ABEND?’的神秘引用,但是如果有人能指出如何从如何触发用户ABEND?调用这个例程,我会很感激。我需要编写JNI代码并从C语言调用它吗?还是有更简单的方法?
发布于 2020-04-17 09:52:29
我玩了一下,发现对于31位JZOS,您还可以通过LE-运行时选项注册用户编写的条件处理程序,并使用它捕获U3333 abend并将其更改为其他东西。
不幸的是,似乎(在z/OS2.3中)没有办法通过64位LE中的运行时选项注册条件处理程序。
在JCL中,可以通过CEEOPTS DD-语句添加选项:
//CEEOPTS DD *
ENVAR("JZOS_ABEND_EXIT=50")
USRHDLR(MYHDLR)
/*
在处理程序中,您可以分析消息CEE3250 (用户发起的abend)的LE-stattion.Token。在本例中,您可以调用CEEGQDT来获取包含abend代码和原因代码的特定于abend的q_data,这样就可以识别U3333。
如果您想发出不同的ABEND,则可以调用CEE3ABD。请注意,我只有通过调用CEE3ABD和CLEANUP = 0
来禁用任何进一步的LE条件处理才能使其工作。我想,否则会出现问题,因为在当前处理程序尚未退出的情况下,会引发另一个条件。
下面是我用PL/I编写的示例-hanlder,但也可以用COBOL或C(或者汇编程序,如果您喜欢.)来完成。
MYHDLR: PROC(P1,P2,P3,P4) OPTIONS(BYVALUE FETCHABLE);
DCL(P1,P2,P3,P4) POINTER;
/* DCL CUR_COND CHAR(12); */ /*P1->*/
DCL TOKEN BIN FIXED(31) BASED(P2);
DCL RESULT BIN FIXED(31) BASED(P3);
/* DCL NEW_COND CHAR(12); */ /*P4->*/
DCL COND_PTR POINTER;
DCL 1 COND_STRU BASED(COND_PTR),
2 SEVERITY BIN FIXED(15),
2 MESSAGE BIN FIXED(15),
2 FLAGS BIT(8),
2 FACILITY CHAR(3),
2 ISI BIN FIXED(31);
DCL QDATA_PTR POINTER;
DCL 1 QDATA BASED(QDATA_PTR),
2 QCOUNT_PTR POINTER,
2 ABCODE_PTR POINTER,
2 REASON_PTR POINTER;
DCL ABCODE BIN FIXED(31) BASED(ABCODE_PTR);
DCL REASON BIN FIXED(31) BASED(REASON_PTR);
DCL MYABCODE BIN FIXED(31);
DCL CLEANUP BIN FIXED(31);
DCL FEEDBACK CHAR(12);
DCL SYSPRINT FILE;
DCL (CEEGQDT,CEE3ABD) ENTRY OPTIONS(ASM);
PUT SKIP LIST('HANDLER CALLED');
/* ANALYZE CONDITION */
COND_PTR = P1;
PUT SKIP EDIT(FACILITY,MESSAGE,SEVERITY)(A,F(4),F(4));
IF FACILITY = 'CEE' & MESSAGE = 3250 THEN DO;
PUT SKIP LIST('ABEND ISSUED');
CALL CEEGQDT(COND_STRU,QDATA_PTR,FEEDBACK);
COND_PTR = ADDR(FEEDBACK); /* REUSE TOKEN STRUCTURE */
PUT SKIP EDIT(SEVERITY,ABCODE)(F(6),F(6));
IF SEVERITY = 0 & /* CEEGQDT CALL SUCCESSFUL */
ABCODE = 3333 /* ONLY HANDLE USER-ABEND U3333 */
THEN DO;
CLEANUP = 0; /* NO LE-CLEANUP */
MYABCODE = 100;
IF REASON = 51 THEN MYABCODE = 999;
CALL CEE3ABD(MYABCODE,CLEANUP);
END;
END;
ELSE DO;
PUT SKIP LIST('NO ABEND');
RESULT = 20; /* PERCOLATE CONDITION */
END;
END;
发布于 2020-05-01 15:59:05
我用JNI电话解决了这个问题。我不依赖用户编写的退出处理程序,而是直接从Java调用方法Abend.abend。
public class Abend {
public static native void abend(int abcode, int reasoncode, int cleanup);
}
和C执行情况:
#include <stdio.h>
#include <ctest.h>
#include "Abend.h"
#define _POSIX_SOURCE
#include <unistd.h>
JNIEXPORT void JNICALL Java_Abend_abend
(JNIEnv * end, jclass class, jint code, jint reasoncode, jint timing) {
/* fprintf(stderr, "values %d %d %d\n", code, reasoncode, timing);*/
__cabend(code, reasoncode, timing);
}
https://stackoverflow.com/questions/61263154
复制相似问题