您的位置:首页 > 大数据 > 人工智能

大型机汇编(mainframe assembler/HLASM)之线程工作栈

2012-11-15 13:54 190 查看
如果在一个可装载模块中,一个程序被多个程序或者被另一个程序多次调用,而恰巧本程序又在运行时出错了,我们怎么快速锁定其实被谁(父程序)调用的呢?(JAVA中有线程工作栈可以很容易找到,而COBOL或者HLASM就有点犯难了),甚至是更上层的程序;或者如果它被一个程序多次调用,我们怎么确定是在哪次被调用时出了问题?

 

一般情况下,我们可以加DISPLAY来跟踪,不过这样太费时,很多情况下,我们需要加的地方可能是很多处,很有可能是在多个程序中的多个地方同时加DISPLAY来锁定到底是哪里出了问题,等最后问题解决了,还要逐个删除...

 

这里有个极其简单的方法,什么都不需要做,只要稍微能读懂点dump即可。

 

很多时候程序出错我们都可以在S.ST里看到有个SYSPRINT这么一个文件,这里面就包含了程序出错时相当多的有用信息,下面我们来针对上面的问题稍加解读(读者还可参考我的另一篇文章“大型机汇编(mainframe
assembler/HLASM)之DUMP解读”)。

 

一般情况下,我们应该能从里面找到下面两者(红字与蓝字显示)其中之一:

 

SA   0002BDC0  WD1 00001001   HSA 00029228   LSA 0002BEC0   RET 9432145E  EPA 942F7B70   R0  0002BFB8

               R1  157078C8   R2  00029AD8   R3  00000001   R4  157078C8  R5  00019588   R6  0001C7FC

               R7  14321FFF   R8  0001CA80   R9  00000004   R10 0DA8B2EC  R11 94321000   R12 0001AA50

SA   00029228  WD1 0808CEE1   HSA 000089A4   LSA 0002BDC0   RET 8DA8A428  EPA 0DA961B0   R0  00000000

               R1  00029644   R2  0002966C   R3  00000004   R4  00000000  R5  00000718   R6  15707888

               R7  00000010   R8  8DA8A2E8   R9  0002A227   R10 0DA8B2EC  R11 0DA86AA0   R12 0001AA50

先解析下上面各个缩写的含义:

SA : current save area(R13)

WD1:word 1(NOT useful)

HSA: high save area

LSA:low save area

RET: return address(R14)

EPA: entry pointer address(R15)

由此可以看出dump里的这段数据,就是显示各个程序保护区里的内容;当然了,如果能在dump里看到类似下面的数据那更好了(它们可能出现在一起,也可能零散地分布在dump里)。

Save area at 0000BC64 for procedure at 2401ADE0 CKRMAIN CKRCARLA 1.10.0 05/06/09 14.58 (not returned yet) R14 offset 0F14

WD1 00000000 HSA 0000AD9C LSA 00037458 R14 A401BCF4 R15 24202AD8 R0  0001AE4E

R1  0001ADB1 R2  2401D5EB R3  0000B7B0 R4  2401ADE0 R5  2401BDE0 R6  2401CDE0

R7  000FB770 R8  00F8D200 R9  000FB770 R10 00000000 R11 007FF350 R12 0000A1C8

 

Save area at 00037458
for procedure at 24202AD8 CKRDATAB CKRCARLA 1.10.0 10/15/08 00.39 (not returned yet) R14 offset 0226

WD1 00000000 HSA 0000BC64 LSA 00055B90 R14 A4202CFE R15 24340880 R0  0000A6C0

R1  00037450 R2  00000000 R3  00037450 R4  24202AD8 R5  2401BDE0 R6  2401CDE0

R7  000FB770 R8  00F8D200 R9  000FB770 R10 00000000 R11 007FF350 R12 00000000

 

Save area at 00055B90 for procedure at 24340880 CKRPPROF CKRCARLA 1.10.0 10/15/08 02.07 (not returned yet) R14 offset 0474

WD1 00000000 HSA 00037458 LSA 0005D5A0 R14 A4340CF4 R15 24396AF8 R0  0000A6C0

R1  00037450 R2  00000000 R3  00055B90 R4  24340880 R5  2401BDE0 R6  2401CDE0

R7  000FB770 R8  00F8D200 R9  000FB770 R10 00000000 R11 007FF350 R12 00000000

现在我们再附加稍微解释下上面这段数据的含义(依第一句为例):

Save area at 0000BC64 for procedure at 2401ADE0 CKRMAIN CKRCARLA 1.10.0 05/06/09 14.58 (not returned yet) R14 offset 0F14

它的意思是说程序CKRMAIN(隶属于模块CKRCARLA)的载入地址是2401ADE0,保护区地址是0000BC64,并且程序是在偏移量0F14处调用其他程序的。

 

接下来我们先解释红字部分,它一共列出了两个保护区的数据,其中第一个保护区中的‘HSA 00029228’是说本程序的父程序的保护区地址是00029228,而00029228又正好是第二个保护区的首地址,依此我们也可以推断出是第二个程序调用了第一个程序,至于说第一个和第二个程序的名称,红字部分没有体现,不过只要稍微在dump里搜下就可以找到。(当然反过来也可以证明是第二个程序调用了第一个,那就是在第二个保护区里有‘LSA
0002BDC0’,这就是说本程序的子程序的保护区地址是0002BDC0,而0002BDC0又正好是第一个保护区的首地址)。

 

上文只是讲解了两个程序之间的调用,其实我们通过分析保护区可以提炼出一条多个程序之间调用的list来,接下来请看蓝字部分。

 

其实蓝字部分是红字部分的整合或者说另外一种写法,只是它更清楚明了了,它直接告诉你了调用程序list的程序名(CKRMAIN,CKRDATAB ,CKRPPROF )及隶属模块(CKRCARLA ),更重要的是它还直接告诉你在程序偏移量(offset )的多少处开始访问子程序的,有了这个偏移量可以很快地从listing里找出是哪条CALL语句出了问题。

 

根据前者的解析和蓝字中下划线字段,我们可以得出他们三个的调用顺序是CKRMAIN调用了CKRDATAB,而后者又调用了CKRPPROF。

 

这里插句话,红字部分其实也可以算出是在本程序的哪个CALL语句出了问题,算法为:用本程序中的RET(1432145E)减去父程序中的EPA(0DA961B0),来求出offset,进而翻阅listing文件,轻易锁定出错代码。

 

其实,save area里有很多很多的信息可供我们挖掘,只是你本人要有兴趣并且不要太懒才好。


 ......

如果上面的内容读者能完全理解的话,请不妨想想,是不是也可以从dump里读出程序出错时传过来的实参呢(有时候确定实参合法与否可能更重要,相信很多做大机的朋友都深有体会)? 我来告诉你,答案是肯定的。为避免篇幅过长,放在其他篇幅讲解。

 

                                            申明:本文严禁转载!

有疑问请联系QQ349106216


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: