디버그 정보를 사용하여 어셈블된 프로그램을 디버깅하는데 대부분의 Debug Tool 명령을 사용할 수 있습니다. 이에 대한 예외사항은 Debug Tool Reference and Messages를 참조하십시오. 어셈블러 프로그램을 디버깅하기 전에 어셈블러 프로그램 준비를 참조하여 프로그램을 준비하십시오.
SET ASSEMBLER ON 및 SET DISASSEMBLY ON 명령은 몇 가지 같은 기능을 사용 가능하게 합니다. 그러나 사용할 명령을 결정하기 전에 디버깅할 CU의 유형(어셈블러, 디스어셈블리 또는 둘 다)을 고려해야 합니다. 다음은 사용할 명령을 결정하는 데 유용한 가이드라인입니다.
어셈블러 CU를 디버깅하고 있는데 나중에 디스어셈블리 CU를 디버깅하려는 경우 SET ASSEMBLER ON 명령을 입력한 후에 SET DISASSEMBLY ON 명령을 입력할 수 있습니다.
LOADDEBUGDATA 명령 또는 LDD 명령은 컴파일 단위가 어셈블러 컴파일 단위가 되고 해당 컴파일 단위로 연관된 디버그 데이터를 로드하도록 Debug Tool에 지시합니다. LDD 명령은 디버그 정보가 없어서 디스어셈블리 컴파일 단위로 간주되는 컴파일 단위에만 실행할 수 있습니다. 다음 예제에서 mypgm은 어셈블러 프로그램의 컴파일 단위(CSECT) 이름입니다.
LDD mypgm
Debug Tool은 yourid.EQALANGX(mypgm) 이름을 사용하여 데이터셋에서 디버그 정보를 찾습니다. Debug Tool이 이 데이터셋을 찾으면 어셈블러 프로그램 디버그를 시작할 수 있습니다. 그렇지 않으면 SET SOURCE 또는 SET DEFAULT LISTINGS 명령을 입력하여 Debug Tool에 디버그 정보를 찾을 위치를 지시하십시오. 원격 디버그 모드에서는 프로그램이 step into할 때 원격 디버거가 데이터셋 정보를 프롬프트합니다.
일반적으로 DESCRIBE CUS 또는 LIST NAMES CUS 명령을 입력하면 디버그 정보가 없는 컴파일 단위는 나열되지 않습니다. 이러한 컴파일 단위를 포함시키려면 SET ASSEMBLER ON 명령을 입력하십시오. 다음에 DESCRIBE CUS 또는 LIST NAMES CUS 명령을 입력할 때는 이러한 컴파일 단위가 나열됩니다.
아래의 Debug Tool 세션 패널은 사용자가 어셈블러 프로그램을 디버깅하는 중에 소스 창에 표시되는 정보를 나타냅니다.
어셈블러 위치: PUBS :> 34.1 Command ===> Scroll ===> CSR 모니터 --+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+---10----+--- 행: 0/0 ******************************************************* 모니터 맨 위 ******************************************************** ********************************************************* 모니터의 끝 ********************************************************* 소스: PUBS +----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+---10-- 행: 60/513 1 34 2 3 * 7 . 34 00000078 OPENIT EQU * . 34 00000078 + OPEN ((2),INPUT) . 34 4 + CNOP 0,4 전체 단어로 목록 맞춤 . 34 00000078 4510 B080 + BAL 1,*+8 목록 주소와 함께 REG1 로드. @L2A . 35 0000007C + DC A(0) 옵션 바이트 및 DCB 주소. . 36 00000080 5021 0000 + ST 2,0(1,0) 목록에 저장 @L1C. . 37 00000084 9280 1000 + MVI 0(1),128 옵션 바이트로 이동 . 38 00000088 0A13 + SVC 19 문제 열기 서비스 . 39 5 6 CEEMOUT,(문자열,설명,0),값 호출 생략된 피드백 코드 . 39 + SYSSTATE 테스트 @L3A . 39 + CNOP 0,4 . 로그 0----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+---10----+---1 행: 1/9 ********************************************************* 로그 맨 위 ********************************************************** IBM Debug Tool 버전 11 릴리스 1 모드 0 11/06/2010 4:11:41 PM 5655-W45: Copyright IBM Corp. 1992, 2010 0004 EQA1872E 다음 파일을 여는 동안 오류 발생: INSPPREF. 파일이 없거나 액세스할 수 없습니다. 0005 소스 또는 목록 데이터를 사용할 수 없거나 CU가 올바른 컴파일 옵션으로 컴파일되지 않았습니다. 0006 LDD PUBS ; 0007 SET DEFAULT SCROLL CSR ; 0008 AT 34 ; 0009 GO ; ********************************************************* 로그의 끝 ********************************************************* PF 1:? 2:STEP 3:QUIT 4:LIST 5:FIND 6:AT/CLEAR PF 7:UP 8:DOWN 9:GO 10:ZOOM 11:ZOOM LOG 12:RETRIEVE
소스 창에 표시되는 정보는 어셈블러에 의해 생성되는 목록과 유사합니다. 소스 창에는 다음 정보가 표시됩니다.
둘 이상의 행에 동일한 명령문 번호가 지정되는 경우도 있습니다. 시스템이 해당 명령문을 따르도록 지시한 것과 같이 설명, 레이블 및 매크로 호출이 동일한 명령문에 지정됩니다. 이러한 명령문은 모두 CSECT 내에서 동일한 오프셋을 갖습니다. 따라서 사용자가 해당 행 중 어느 행에나 커서를 놓고 PF6을 누르면 중단점을 설정할 수 있습니다. 명령문에 도달하면 매크로 호출 또는 시스템 지시사항 중 하나를 포함하는 명령문 내의 첫 번째 행에 초점이 설정됩니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
다음은 현재 프로그래밍 언어가 어셈블러인 경우에 Debug Tool %PATHCODE 변수에 사용할 수 있는 값을 표시하는 표입니다.
| %PATHCODE | 항목 유형 | 명령어 | 추가 요구사항 또는 설명 |
|---|---|---|---|
| 1 | 블록이 입력되었습니다. | Any | 오프셋이 명령어에 해당되는 외부 기호 |
| 2 | 블록이 종료됩니다. |
BR R14 (07FE) |
|
BALR R14,R15 (05EF) |
이러한 명령어는 이 명령어 다음에 올바른 명령어가 오지 않는 경우에만 Exit로 간주됩니다. | ||
BASR R14,R15 (0DEF) |
|||
BASSM R14,R15 (0CEF) |
|||
BCR 15,x (07Fx) |
|||
| 3 | 프로그램에 코딩된 레이블에 제어가 도달했습니다. | Any | 오프셋이 명령어에 해당되는 레이블 |
| 4 | CALL의 결과로 제어가 전송되고 있습니다. |
BALR R14,R15 (05EF) |
|
BASR R14,R15 (0DEF) |
|||
BASSM R14,R15 (0CEF) |
|||
| SVC (0A) | |||
| PC (B218) | |||
| BAL (45) | BAL 1을 제외하고 xxx는 CALL로 간주되지 않습니다. | ||
| BAS (4D) | |||
BALR x,y (05) |
|||
BASR x,y (0D) |
|||
BASSM x,y (0C) |
|||
| BRAS (A7x5) | |||
| BRASL (C0x5) | |||
| 5 | 제어가 CALL에서 리턴 중입니다. | Statement after CALL | CALL 다음의 명령문이 명령어이면 항목이 여기에 입력됩니다. |
| 6 | 조건부 분기가 실행되려고 합니다. | BC x (47x) | x^=15 & X^=0 |
| BCR x (07x) | x^=15 & X^=0 | ||
| BCT (46) | |||
| BCTR (06) | |||
| BCTGR (B946) | |||
| BXH (86) | |||
| BXHG (EB44) | |||
| BXLE (87) | |||
| BXLEG (EB45) | |||
| BRC x (A7x4) | x^=15 & X^=0 | ||
| BRCL (C0x4) | |||
| BRCT (A7x6) | |||
| BRCTG (A7x7) | |||
| BRXH (84) | |||
| BRXHG (EC44) | |||
| BRXLE (85) | |||
| BRXLG (EC45) | |||
| 7 | 조건부 분기가 실행되지 않았으며 제어가 다음 명령어로 "fallen-through"되었습니다. | Statement after Conditional Branch | |
| 8 | 무조건 분기가 실행되려고 합니다. |
BC 15,x (47Fx) |
|
BRC 15,x (A7F4) |
|||
BRCL 15,x (C0F4) |
|||
| BSM (0B) |
어셈블러 프로그램용 소스 창에 표시되는 정보는 다음과 같은 두 가지 방법 중 하나를 사용하여 표시할 수 있습니다. STANDARD 보기는 매크로 확장을 통해 생성된 행을 포함하여 어셈블러 목록에 있는 모든 행을 표시합니다. NOMACGEN 보기는 매크로 확장에 의해 생성된 행을 생략하므로 PRINT NOGEN이 적용되는 경우에 생성되는 어셈블러 목록과 유사합니다.
다음 명령을 사용하여 어셈블러 프로그램용 소스 창에 표시되는 보기를 제어할 수 있습니다.
로드 모듈이 재진입 불가능으로 표시되고 해당 삭제 없이 여러 번 로드된 경우 로드 모듈의 여러 사본이 동시에 메모리에 존재합니다. 상위 레벨 언어 프로그램이 기본적으로 재진입으로 표시되므로 재진입하지 않는 프로그램 디버깅은 주로 어셈블러 프로그램의 디버깅에 적용됩니다. 다음 상황에는 재진입하지 않는 어셈블러 프로그램을 디버깅할 때 다음 섹션에 설명된 특수 고려사항이 있습니다.
다음 설명은 전체 화면 모드 및 행 모드 디버깅에만 적용됩니다. 원격 디버거를 사용할 때 재진입하지 않는 어셈블러의 디버깅을 지원하기 위한 해당 기능이 없습니다.
다음 명령 중 하나를 사용하여 재진입하지 않는 로드 모듈의 컴파일 단위로 중단점을 조작하는 경우, 명령은 동일한 이름을 가진 로드 모듈의 모든 컴파일 단위 사본에 적용됩니다.
재진입하지 않는 로드 모듈의 컴파일 단위에 있는 로컬 변수를 참조하고 해당 로드 모듈의 여러 사본이 메모리에 존재하는 경우, 명령을 적용하려는 컴파일 단위의 사본을 식별해야 합니다. 컴파일 단위의 사본을 식별하려면 먼저 특정 컴파일 단위의 주소를 가져와야 합니다. 다음 목록에는 특정 컴파일 단위의 주소를 가져올 수 있는 일부 방법에 대해 설명합니다.
주소를 가져온 후 SET QUALIFY address; 명령을 입력하십시오. 여기서, address는 사용자가 식별한 특정 컴파일 단위의 주소입니다.
어셈블러 프로그램을 디버깅할 때 적용되는 일반적인 제한사항은 다음과 같습니다.
Language Environment을 사용할 수 있는 어셈블러 주 프로그램을 디버깅하는 경우 다음 제한사항이 적용됩니다.
CICS에서 실행 중인 Language Environment 확인 어셈블러 기본 프로그램을 디버그하려면 CICS Transaction Server, 버전 3.1 이상으로 실행해야 합니다.
다음은 Language Environment 어셈블러 프로그램의 프롤로그에 명시적 또는 암시적 중단점을 설정하려고 할 때 적용되는 제한사항입니다.
프로그램 시작 후, CALL CEETEST에 의하거나 Language Environment 조건의 발생으로 Debug Tool이 시작될 때 NOPROMPT 하위 옵션과 함께 TEST 런타임 옵션을 지정하는 경우, Language Environment 및 비Language Environment 프로그램을 둘 다 디버깅하고 Debug Tool이 시작된 enclave 및 후속 enclave에서 Language Environment 및 비Language Environment 이벤트를 둘 다 발견할 수 있습니다. 상위 레벨 enclave에서는 비Language Environment 프로그램을 디버깅하거나 비Language Environment 이벤트를 검색할 수 없습니다. Debug Tool이 시작된 enclave에서 제어가 리턴된 후에는 더 이상 비Language Environment 프로그램을 디버깅하거나 비Language Environment 이벤트를 감지할 수 없습니다.
Debug Tool에서는 명령어를 데이터로 사용하는 코드를 디버깅할 수 없습니다. 사용 중인 프로그램이 하나 이상의 명령어를 데이터로 참조하는 경우 Debug Tool의 비정상 종료(ABEND)와 같이 예측할 수 없는 결과를 초래할 수 있습니다. 이것은 중단점을 작성하기 위해 Debug Tool이 가끔 명령어를 SVC로 바꾸기 때문입니다.
예를 들어, Debug Tool은 다음 코드를 올바르게 처리할 수 없습니다.
Entry1 BRAS 15,0
NOPR 0
B Common
Entry2 BRAS 15,0
NOPR 4
Common DS 0H
IC 15,1(15)
이 코드에서 IC는 NOPR 명령어의 두 번째 바이트를 조사하는 데 사용됩니다. 그러나 NOPR 명령어가 SVC로 바뀌어 중단점이 작성되면 0이나 4가 아닌 값을 가져와 사용자 프로그램에서 예상치 않은 결과가 발생할 수 있습니다.
다음 코딩 기술을 사용하여 이 문제점을 제거할 수 있습니다.
메소드 1을 사용하여 위의 예제를 다음 코드로 변경할 수 있습니다.
Entry1 BAL 15,*+L'*+2
DC H'0'
B Common
Entry2 BAL 15,*+L'*+2
DC H'4'
Common DS 0H
IC 15,1(15)
메소드 2를 사용하여 위의 예제를 다음 코드로 변경할 수 있습니다.
Entry1 BRAS 15,0
DC X'0700'
B Common
Entry2 BRAS 15,0
DC X'0704'
Common DS 0H
IC 15,1(15)
Debug Tool은 두 가지 유형(감지 가능 및 감지 불가능)의 자체 수정 코드를 정의합니다. 감지 가능한 자체 수정 코드는 다음과 같습니다.
Inst1 NOP Label1
MVI Inst1+1,X'F0' EQAModIn Inst1
Inst1 NOP Label1
LA R3,Inst1
MVI 0(R3),X'F0'다음 기준 중 하나를 충족하지 않는 자체 수정 코드는 감지 불가능으로 분류됩니다.
Debug Tool이 감지 가능한 자체 수정 코드를 식별하는 경우, 매크로 생성 명령을 표시하는 컬럼의 바로 앞 컬럼에 "X"자를 표시하여 소스 창에 상황을 표시합니다. 이러한 명령어에는 중단점을 설정할 수 없으며 STEP stop할 수도 없습니다.
EQAMODIN 매크로가 Debug Tool 샘플 라이브러리(hlq.SEQASAMP)에 제공됩니다. 이 매크로를 사용하여 감지 불가능한 자체 수정 코드를 감지할 수 있도록 만들 수 있습니다. 실행 가능한 코드는 생성하지 않습니다. 대신에 정보를 SYSADATA 파일에 추가하여 지정된 피연산자를 수정된 것으로 식별합니다. 피연산자는 바로 뒤에 오는 명령어가 수정되었음을 나타내도록 레이블 이름 또는 "*"로 지정될 수 있습니다.
포함된 컴파일 단위를 디버깅하는 동안 명령어를 수정하는 감지 불가능한 자체 수정 코드가 프로그램에 있는 경우 Debug Tool의 비정상 종료(ABEND)와 같이 예측할 수 없는 결과를 초래할 수 있습니다. 포함된 컴파일 단위를 디버그하는 동안 명령어를 완전히 대체하는 자체 수정 코드가 프로그램에 있고 명령어를 수정하는 코드를 단계적으로 실행하지 않는 경우, ABEND가 발생하지 않을 수 있습니다. 그러나 Debug Tool에서 해당 명령어에 대한 중단점을 찾지 못하거나 삭제 시 올바르지 않은 후크 주소를 나타내는 메시지가 표시될 수 있습니다. 명령어를 수정하는 코드를 단계적으로 수행하는 경우, 이동되는 명령어에 중단점이 포함되어 수정된 명령어 실행 시 Debug Tool이 실패할 수 있습니다.
다음 코딩 기술을 사용하여 감지 불가능한 자체 수정 코드 디버깅과 관련된 문제점을 최소화할 수 있습니다.
| 명령어 op-code에서 정의된 명령어를 수정하는 코드 | DC에서 정의된 명령어를 수정하는 코드 |
|---|---|
ModInst BC 0,Target
...
MVI ModInst+1,X'F0' |
ModInst DC X'4700',S(Target)
...
MVI ModInst+1,X'F0' |
| 명령어를 수정하는 코드 | 명령어를 DC로 정의된 명령어로 바꾸는 해당 코드 |
|---|---|
ModInst BC 0,Target ... MVI ModInst+1,X'F0' |
ModInst BC 0,Target ... MVC ModInst(4),NewInst ... NewInst DC X'47F0',S(Target) |
| 명령어를 수정하는 코드 | 표시된 명령어를 EQAMODIN으로 바꾸는 해당 코드 |
ModInst BC 0,Target
...
MVI ModInst+1,X'F0' |
ModInst BC 0,Target
...
MVC ModInst(4),NewInst
...
EQAMODIN NewInst
NewInst BC 15,Target |