有没有办法在调用堆栈中识别程序名称?即,我有一个链接到 PGM B 的 PGM X,而这个链接到 PGM C,然后,在 C 中,我想知道哪个程序发起呼叫(PGM X)?
3 回答
你可以这样做,但需要一点汇编程序。本质上,您需要查找保存区域并在返回地址上执行 CSVQUERY,这将为您提供拥有该保存区域的模块的名称。
有一些怪癖,您需要注意 Cobol 运行时模块(以 IGZ 为前缀)和/或语言环境模块(以 CEE 为前缀)。当您执行 Cobol 调用时,它会调用一个运行时模块,然后调用您调用的程序。
此外,这不会识别执行 EC LINK 或 EC XCTL 的程序,只会识别使用 OS 保存区域约定的 Cobol 调用调用。
例子:
CSVQUERY SEARCH=JPALPA,INADDR=<R14_from_savearea>,OUTEPNM=<module_name_output>,MF=(E,PLIST)
对保存区域链上的每个返回地址重复执行此操作,您将知道所有调用者。
没有支持的方式来做到这一点。有些人尝试追逐保存区域并遍历可执行代码以确定其名称,但我怀疑一切都以眼泪告终。
一个问题是您无法保证 LINK 或 XCTL 是如何实现的。在动态调用的情况下,您可能能够遵循保存区域链,但是您需要弄清楚如何识别模块。不是您仅使用 COBOL 就可以做到的事情。
如果您在 CICS 中,您可以执行 EXEC CICS ASSIGN 并使用 PROGRAM 选项获取当前程序的名称,以及使用 INVOKINGPROG 链接到它的程序的名称。在这种情况下,这将为您提供程序 C 和程序 B。
要获得原始的最高级别程序是比较困难的。您可以查询当前事务 (EIBTRNID) 以获取运行的程序,但如果您已被路由到某个地方,那么它将不是程序 X,而是 DFHMIRS。