大型机汇编(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里有很多很多的信息可供我们挖掘,只是你本人要有兴趣并且不要太懒才好。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/tongue.gif)
......
如果上面的内容读者能完全理解的话,请不妨想想,是不是也可以从dump里读出程序出错时传过来的实参呢(有时候确定实参合法与否可能更重要,相信很多做大机的朋友都深有体会)? 我来告诉你,答案是肯定的。为避免篇幅过长,放在其他篇幅讲解。
申明:本文严禁转载!
有疑问请联系QQ349106216
一般情况下,我们可以加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里有很多很多的信息可供我们挖掘,只是你本人要有兴趣并且不要太懒才好。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/tongue.gif)
......
如果上面的内容读者能完全理解的话,请不妨想想,是不是也可以从dump里读出程序出错时传过来的实参呢(有时候确定实参合法与否可能更重要,相信很多做大机的朋友都深有体会)? 我来告诉你,答案是肯定的。为避免篇幅过长,放在其他篇幅讲解。
申明:本文严禁转载!
有疑问请联系QQ349106216
相关文章推荐
- 大型机汇编(mainframe assembler/HLASM)之中断向量表
- 大型机汇编(mainframe assembler/HLASM)之显示变量值('DISPLAY' in COBOL)
- 大型机汇编(mainframe assembler/HLASM)之LA指令
- 大型机汇编(mainframe assembler/HLASM)之S0C7错误
- 大型机汇编(mainframe assembler/HLASM)之CICS调用
- 大型机汇编(mainframe assembler/HLASM)之DUMP解读
- 大型机汇编(mainframe assembler/HLASM)之经典面试题
- 大型机汇编(mainframe assembler/HLASM)之显示内存实际数据
- 大型机汇编(mainframe assembler/HLASM)之加密与解密
- 大型机汇编(mainframe assembler/HLASM)之藏巧于拙
- 大型机汇编(mainframe assembler/HLASM)之LOCTR
- 大型机汇编(mainframe assembler/HLASM)之STCK/STCKE
- 大型机汇编(mainframe assembler/HLASM)之代码精简高效
- 大型机汇编(mainframe assembler/HLASM)之COBOL解惑
- 大型机汇编(mainframe assembler/HLASM)之代码loop篇
- 大型机汇编(mainframe assembler/HLASM)之S0C4解读
- 大型机汇编(mainframe assembler/HLASM)之BAS指令
- 大型机汇编(mainframe assembler/HLASM)之Branch
- 大型机汇编(mainframe assembler/HLASM)之C++语言对应
- 大型机汇编(mainframe assembler/HLASM)之RECFM=VBA