COBOL主程序静态调用COBOL/DB2子程序返回CEE3204S错误
问题根因定位
出现CEE3204S(0C4存储保护异常)的核心原因是主程序传参与子程序接收的参数数量、结构不匹配,COBOL静态调用按参数位置传递内存地址,地址偏移错误导致子程序访问了非法内存区域:
- 主程序
CALL语句共传递7个参数,第三个位置开始是拆分开的WS-REGN-CODE、WS-BRANCH-CODE、WS-ACCOUNT-NO三个独立参数 - 子程序
PROCEDURE DIVISION USING只定义了5个接收参数,第三个位置是长度16字节的组合项LS-ACCT-NO
两者参数地址映射完全错位,子程序访问LS-PRT-REGION-NAME、LS-PRT-BRANCH-NAME时实际指向主程序中长度只有4字节/8字节的短字段,写入操作直接越界触发存储保护异常。
解决方案
两种修复方案二选一即可:
方案1:调整主程序传参(更推荐,符合参数封装逻辑)
修改主程序的CALL语句,第三个参数直接传递组合项WS-ACCT-NO,和子程序的接收结构匹配,传参数量调整为5个:
0810-GET-REGION-AND-BRANCH. MOVE 'GET REGION BRANCH' TO WS-DB-QUERY CALL 'ABCDBQUE' USING WS-DB-QUERY WS-DB-QUERY-STATUS WS-ACCT-NO WS-PRT-REGION-NAME WS-PRT-BRANCH-NAME.
方案2:调整子程序参数定义
修改子程序的LINKAGE SECTION和PROCEDURE DIVISION USING,拆分组合项LS-ACCT-NO为三个独立参数,和主程序传参数量匹配:
LINKAGE SECTION. 01 LS-DB-QUERY PIC X(20). 88 DB-SELECT-ACCT VALUE 'INQUIRE DEPTABLE'. 88 DB-SELECT-REG-BRANCH VALUE 'GET REGION BRANCH'. 88 DB-UPDATE VALUE 'ACCT STATUS UPDATE'. 01 LS-DB-QUERY-STATUS PIC X(01). 88 DB-QUERY-SUCCEEDED VALUE 'S'. 88 DB-QUERY-FAILED VALUE 'F'. 01 LS-REGN-CODE PIC X(04). 01 LS-BRANCH-CODE PIC X(04). 01 LS-ACCOUNT-NO PIC X(08). 01 LS-PRT-REGION-NAME PIC X(70). 01 LS-PRT-BRANCH-NAME PIC X(70). * PROCEDURE DIVISION USING LS-DB-QUERY, LS-DB-QUERY-STATUS, LS-REGN-CODE, LS-BRANCH-CODE, LS-ACCOUNT-NO, LS-PRT-REGION-NAME, LS-PRT-BRANCH-NAME.
后续验证
修改完成后按以下步骤验证:
- 重新编译主程序、子程序,确保返回码为0,静态调用场景下主程序编译需开启
NODYNAM编译选项 - 链接编辑(Link Edit)阶段确保将子程序
ABCDBQUE的目标模块和主程序绑定为同一个加载模块(Load Module) - 重新绑定DB2对应的Package和Plan,运行测试验证功能正常
内容的提问来源于stack exchange,提问作者Roger Strycova
相关产品推荐
相关产品推荐

