Debug Tool을 사용해서 C 및 C++ 프로그램을 디버깅하는 방법을 아래 주제에서 설명합니다.
예제: C 및 C++ 블록에서 변수 참조 및 중단점 설정
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
Debug Tool 명령 언어는 C 및 C++ 명령 언어의 서브세트이며 동일한 구문 요구 사항을 포함합니다. Debug Tool은 새 명령 세트에 대한 학습이 필요없는 친숙한 언어로 작업할 수 있습니다.
아래 표는 Debug Tool이 인식한 C 및 C++ 명령의 해석 가능한 서브세트를 표시합니다.
| 명령 | 설명 |
|---|---|
| block({}) | 컴포지트 명령 그룹화 |
| break | 루프 또는 switch 명령 종료 |
| declarations | 세션 변수 선언 |
| do/while | 반복 루핑 |
| expression | 조건부(?) 연산자를 제외한 C 표현식 |
| for | 반복 루핑 |
| if | 조건부 실행 |
| switch | 조건부 실행 |
이 명령의 서브세트는 현재 프로그래밍 언어가 C 또는 C++인 경우에만 유효합니다.
또한 사용자가 사용할 수 있는 C 및 C++ 명령의 서브세트가 사용 예약 키워드 목록이거나 약어로 표시할 수 없는 C 및 C++ 인식 명령인 경우, 변수명으로 사용하거나 ID의 기타 유형으로 사용합니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
Debug Tool은 C 또는 C 및 C++에서 올바른 모든 프로그램 변수를 처리할 수 있습니다. 사용자 세션 중에 변수 값을 지정하고 표시할 수 있습니다. 인식된 C 선언으로 세션 변수를 선언하여 테스트 요구를 충족할 수도 있습니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
Debug Tool은 컴파일러가 작성한 기호 테이블을 사용하여 이름별 프로그램 변수 정보를 얻습니다. 컴파일 시 TEST(SYM)를 지정한 경우, 컴파일러는 프로그램에서 참조할 수 있는 변수의 기호 테이블을 작성합니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
변수 또는 표현식 값을 표시하려면 LIST 명령을 사용하십시오. Debug Tool은 LIST 명령으로 표현식의 평가 결과를 포함한 현재 변수의 값과 요청된 경우, 이름을 로그하고 표시합니다.
프로그램 변수 X, row[X] 및 col[X]와 25행의 변수 값을 표시한다고 가정합니다. 다음 명령을 실행하는 경우,
AT 25 LIST ( X, row[X], col[X] ); GO;
Debug Tool은 25행(AT)에 중단점을 설정하고 프로그램 실행을 시작(GO) 합니다. 25행에서 중지하고 변수명 및 값을 표시합니다.
추가한 결과를 보려면 다음을 입력하십시오.
AT 25 LIST ( X + row[X] + col[X] ); GO;
Debug Tool은 25행(AT)에 중단점을 설정하고 프로그램 실행을 시작(GO) 합니다. 25행에서 중지하고 표현식의 결과를 표시합니다.
둘 이상을 나열할 경우에는 변수 사이에 쉼표를 넣으십시오. LIST 명령 실행 시, 변수명을 표시하려면 LIST UNTITLED를 입력하십시오.
다음과 같이 printf 함수 호출로 변수를 나열할 수도 있습니다.
printf ("X=%d, row=%d, col=%d₩n", X, row[X], col[X]);그러나 printf 출력은 SET INTERCEPT ON FILE stdout을 하지 않으면 로그 창에 나타나지 않고 로그 파일로 기록되지 않습니다.
C 및 C++ 변수에 값을 지정하려면 assignment 표현식을 사용하십시오. Assignment 표현식은 왼쪽 피연산자에 값을 지정합니다. 왼쪽 피연산자는 수정 가능한 lvalue이어야 합니다. lvalue은 조사되거나 변경될 수 있는 데이터 오브젝트를 나타내는 표현식입니다.
C는 두 가지 유형의 assignment 연산자를 포함합니다. 유형은 단순과 복합입니다. 단순 assignment 연산자는 왼쪽 피연산자에게 오른쪽 연산자 값을 제공합니다.
다음 예제는 payroll 구조의 employee 멤버에 number 값을 지정하는 방법을 설명합니다.
payroll.employee = number;
복합 assignment 연산자는 양 쪽 연산자에 오퍼레이션을 수행하고 왼쪽 피연산자에 해당 오퍼레이션 결과를 제공합니다. 예를 들어 이 표현식은 index 변수에 index plus 2 값을 제공합니다.
index += 2
Debug Tool은 3진 연산자를 제외한 모든 C 연산자를 지원하며, 기타 전체 C 언어 지정 및 함수가 사용자 또는 C 라이브러리 함수에 호출합니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
아래 표는 현재 프로그래밍 언어가 C 및 C++인 경우, Debug Tool 변수 %PATHCODE의 가능한 값을 표시합니다.
| –1 | Debug Tool은 경로 또는 어텐션 상황의 결과로 제어 상태가 아닙니다. |
| 0 | Attention 함수(ATTENTION 조건이 아님)입니다. |
| 1 | 블록이 입력되었습니다. |
| 2 | 블록이 종료됩니다. |
| 3 | 제어권이 사용자 레벨에 도착했습니다. |
| 4 | 함수 참조의 결과로 제어권이 전송되고 있습니다. 호출된 루틴의 매개변수가 있는 경우, 준비되었습니다. |
| 5 | 제어권이 함수 호출에서 리턴 중입니다. 레지스터 15에 포함된 리턴 코드가 아직 저장되지 않았습니다. |
| 6 | 조건부 do/while, for 또는 while 명령문에서 포함된 일부 로직이 실행되려고 합니다. 단일 또는 Null 명령문일 수 있고 블록 명령문은 아닙니다. |
| 7 | if(...) 다음의 로직이 실행되려고 합니다. |
| 8 | else 다음의 로직이 실행되려고 합니다. |
| 9 | switch 내 case 다음의 로직이 실행되려고 합니다. |
| 10 | switch 내 기본값 다음의 로직이 실행되려고 합니다. |
| 13 | switch, do, while, if(...) 또는 for의 끝 다음의 로직을 실행하려고 합니다. |
| 17 | goto, break, continue 또는 return이 실행되려고 합니다. |
프로그램이 경로 후크를 지원하는 옵션으로 컴파일된 경우, 범위 3–17 사이의 값은 %PATHCODE로만 지정될 수 있습니다.
세션 코스 중에 사용하려는 세션 변수를 선언하려고 합니다. declaration에서 세션 변수를 초기화할 수 없습니다. 그러나 assignment 명령문 또는 함수 호출을 사용하여 세션 변수를 초기화할 수 있습니다.
C에서와 같이 키워드는 임의의 순서로 지정될 수 있습니다. 변수명은 255자까지 사용할 수 있습니다. ID는 대소문자를 구분하지만 현재 프로그래밍 언어를 C에서 HLL로 변경한 경우 세션 변수를 사용하는 경우, 변수는 대문자 이름이어야 하고 호환 가능한 속성이어야 합니다.
maximum 16진 부동 소수점 변수를 선언하려면 다음 C 선언을 입력하십시오.
double maximum;
스칼라, 스칼라 배열, 구조 및 Debug Tool 내 유니온(위에 허용된 것에 대한 포인터)만 선언할 수 있습니다.
프로그래밍 변수와 같은 이름인 세션 변수를 선언한 경우, 세션 변수는 프로그래밍 변수를 숨깁니다. 프로그래밍 변수를 참조하려면 변수를 규정해야 합니다. 예를 들면 다음과 같습니다.
main:>x for the program variable x x for the session variable x
CLEAR 명령을 사용하여 세션 변수를 삭제하지 않은 경우 전체 디버그 세션 중에 세션 변수는 유효합니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
사용자 테스트 프로그램에서 Debug Tool으로 표현식을 평가합니다. C 및 C++에서 사용 가능한 모든 표현식은 Debug Tool 내에서도 사용 가능합니다. 단, 다음 조건식은 예외합니다(? :). 즉, +, -, %: 및 +=와 같은 모든 연산자는 조건부 연산자의 예외로 완전히 지원됩니다.
C 및 C++ 언어 표현식은 포함된 연산자와 표현식 사용 방법에 따라 다음 그룹으로 배열됩니다.
lvalue은 조사되거나 변경될 수 있는 데이터 오브젝트를 나타내는 표현식입니다. 표현식 및 연산자에 대한 세부사항은 C 및 C++ 프로그램 안내서를 참조하십시오.
C 및 C++ 연산자용 시맨틱은 컴파일된 C 또는 C++ 프로그램에서와 같습니다. 피연산자는 상수(integer, floating-point, character, string 및 enumeration), C 및 C++ 변수, Debug Tool 변수 또는 Debug Tool 세션 중에 선언된 세션 변수를 혼용할 수 있습니다. 언어 상수는 C 및 C++ 언어 참조서에서 설명된 대로 지정되었습니다.
Debug Tool 명령 DESCRIBE ATTRIBUTES은 실제 표현식 평가없이 표현식의 결과 유형을 표시하는 데 사용될 수 있습니다.
C 및 C++ 언어는 함수 호출 인수의 평가 순서를 지정하지 않습니다. 따라서 Debug Tool 내에서 보다 컴파일된 코드에서 다른 실행 순서를 가진 표현식이 가능합니다. 예를 들어, 대화식 세션에서 다음을 입력한 경우,
int x;
int y;
x = y = 1;
printf ("%d %d %d%" x, y, x=y=0);결과는 C 또는 C++ 프로그램 세그먼트의 같은 명령문이 생성한 결과와 다를 수 있습니다. ANSI 표준으로 정의되지 않은 동작을 포함하는 표현식은 Debug Tool이 평가한 경우와 컴파일러가 평가한 경우, 다른 결과를 생성할 수 있습니다.
다음 예제에서는 Debug Tool이 사용자 프로그램에서 표현식 사용을 지원하는 다양한 방법을 표시합니다.
a = (1,2/3,a++,b++,printf("hello world₩n"));league[num].team[1].player[1]++; league[num].team[1].total += 1; ++(*pleague);
v.x = 3; a = b = c = d = 0; *(pointer++) -= 1;
*pointer_to_long = 3521L = 0x69a1; float_val = 3e-11 + 6.6E-10; char_val = '7';
intensity <<= 1, shade * increment, rotate(direction); alpha = (y>>3, omega % 4);
long_double_val = unsigned_short_val; long_double_val = (long double) 3;
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
프로그램이 DEBUG 컴파일러 옵션의 FORMAT(DWARF) 하위 옵션으로 컴파일되지 않은 경우, Debug Tool의 사용자 및 C 라이브러리 함수 호출을 수행할 수 있습니다.
언제든지 C 라이브러리 함수로 호출할 수 있습니다. 또한 함수 호출을 포함하는 표현식에서 C 라이브러리 변수 stdin, stdout, stderr, __amrc 및 errno를 사용할 수 있습니다.
라이브러리 함수가 main 또는 main으로 링크된 함수 중 하나인 프로그램 내 컴파일 단위에서 참조되지 않은 경우 ctdli를 호출할 수 없습니다.
사용자 호출 함수를 만들 수 있으며 제공된 Debug Tool이 사용자 프로그램의 기호 정보에서 함수에 대해 적당한 정의를 찾을 수 있습니다. 이 정의는 프로그램이 C용 TEST(SYM) 또는 C++용 TEST를 컴파일할 경우 작성됩니다.
Debug Tool은 매개변수 변환 및 가능한 경우 매개변수 불일치 확인을 수행합니다. 매개변수 확인은 다음 같은 경우 수행됩니다.
SET WARNING OFF를 지정하여 이 확인을 해제할 수 있습니다.
C 또는 C++ 컴파일러로 지원된 연계를 포함하는 사용자 함수로 호출할 수 있습니다. 그러나 C++의 경우 사용자 함수로 호출할 때 함수는 다음과 같이 선언되어야 합니다.
extern "C"
예를 들어, 애플리케이션 신호 핸들러를 디버깅하려는 경우 이 선언을 사용하십시오. 조건이 발생한 경우 신호 핸들러로 제어권을 전달한 Debug Tool에 제어권을 전달합니다.
Debug Tool은 연계 확인을 시도하고 연계가 일치하지 않는 경우 함수 호출을 수행하지 않습니다. 대상 프로그램이 하나의 연계를 소유하고 있으나 소스 프로그램에서 다른 연계로 인식하면 링크 불일치가 발생합니다.
다음 노트는 함수 호출에 관한 중요한 정보입니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
아래 테이블에서는 C 언어에서 예약된 모든 키워드를 나열합니다. 현재 프로그래밍 언어가 C 또는 C++인 경우 이 키워드는 약어로 표시할 수 없으며 변수명으로 사용되거나 ID의 다른 유형으로 사용될 수 없습니다.
| auto | else | long | switch |
| break | enum | register | typedef |
| case | extern | return | union |
| char | float | short | unsigned |
| const | for | signed | void |
| continue | goto | sizeof | volatile |
| default | if | static | while |
| do | int | struct | _Packed |
| double |
아래 테이블에서는 우선 순위 순서로 C 언어 연산자를 나열하고 각 연산자의 조합 방향을 표시합니다. 기본 연산자는 최고 우선순위입니다. 쉼표 연산자는 최저 우선순위입니다. 동일 그룹 내 연산자는 동일 우선순위입니다.
| 우선순위 레벨 | 조합 | 연산자 |
|---|---|---|
| 기본 | 왼쪽에서 오른쪽 | () [ ] . –> |
| 단항 | 오른쪽에서 왼쪽 | ++ -- - + ! ~ & * (typename) sizeof |
| 곱셈 | 왼쪽에서 오른쪽 | * / % |
| 덧셈 | 왼쪽에서 오른쪽 | + - |
| 비트 이동 | 왼쪽에서 오른쪽 | << >> |
| 관계형 | 왼쪽에서 오른쪽 | < > <= >= |
| 같음 | 왼쪽에서 오른쪽 | ++ != |
| 비트 논리 AND | 왼쪽에서 오른쪽 | & |
| 비트 독점 OR | 왼쪽에서 오른쪽 | ^ 또는 ¬ |
| 비트 포함 OR | 왼쪽에서 오른쪽 | | |
| 논리 AND | 왼쪽에서 오른쪽 | && |
| 논리 OR | 왼쪽에서 오른쪽 | || |
| 지정 | 오른쪽에서 왼쪽 | = += -= *= /= <<= >>= %= &= ^= |= |
| 쉼표 | 왼쪽에서 오른쪽 | , |
Language Environment 조건 이름(기호 피드백 코드 CEExxx)은 다음 테이블에 나열된 동치 C 및 C++ 조건으로 호환 사용될 수 있습니다. 예를 들어, AT OCCURRENCE CEE341은 AT OCCURRENCE SIGILL과 같습니다. CEE341 조건이 발생하면 AT OCCURRENCE SIGILL 중단점 및 반대로 트리거합니다.
| Language Environment 조건 | 설명 | 동치 C/C++ 조건 |
|---|---|---|
| CEE341 | 오퍼레이션 예외 | SIGILL |
| CEE342 | 특권 오퍼레이션 예외 | SIGILL |
| CEE343 | 실행 예외 | SIGILL |
| CEE344 | 보호 예외 | SIGSEGV |
| CEE345 | 주소 지정 예외 | SIGSEGV |
| CEE346 | 스펙 예외 | SIGILL |
| CEE347 | 데이터 예외 | SIGFPE |
| CEE348 | 고정 소수점 오버플로우 예외 | SIGFPE |
| CEE349 | 고정 소수점 나누기 예외 | SIGFPE |
| CEE34A | 10진수 오버플로우 예외 | SIGFPE |
| CEE34B | 10진수 나누기 예외 | SIGFPE |
| CEE34C | 지수 오버플로우 예외 | SIGFPE |
| CEE34D | 지수 언더플로우 예외 | SIGFPE |
| CEE34E | 중요 예외 | SIGFPE |
| CEE34F | 부동 소수점 나누기 예외 | SIGFPE |
Debug Tool은 한 개 이상의 표현식 콜렉션으로 대부분 입력을 해석합니다. 표현식을 사용하여 프로그램 변수를 변경하거나 AT 중단점에서 제어하는 지점에 표현식을 추가하여 프로그램을 확장할 수 있습니다.
Debug Tool은 z/OS XL C/C++ Language Reference에서 설명한 다음 규칙에 따라 C 및 C++을 평가합니다. 표현식 결과는 동일 표현식이 컴파일된 프로그램의 부분인 경우 생성된 결과와 동일합니다.
암시적 문자열 연결이 지원됩니다. 예를 들어, "abc" "def"은 "abcdef"로 승인되고 동일하게 다뤄집니다. 넓은 문자열 리터럴이 문자열 리터럴로 연결은 지원되지 않습니다. 예를 들어, L"abc"L"def" 은 유효하고 "abcdef"와 같지만 "abc" L"def"은 올바르지 않습니다.
사용자 세션 중에 사용한 표현식은 같은 민감도로 평가되어 컴파일된 표현식과 같이 사용 가능하게 합니다. 사용 가능해진 조건은 프로그램 명령문에 대해 존재하는 것과 같습니다.
Debug Tool 세션 중에 WARNING의 현재 설정이 ON인 경우, 아래 나열된 조건 중 하나의 C++ 또는 C 프로그램 발생으로 진단 메시지를 표시합니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
SET INTERCEPT 명령 사용 시 C 애플리케이션을 디버깅하는 중에 파일을 인터셉트하려면 일부 고려사항을 숙지해야 합니다.
CICS® 전용: SET INTERCEPT는 CICS에 지원되지 않습니다.
C++의 경우 IOStreams 인터셉트에 특정 지원이 없습니다. IOStreams은 다음을 의미하는 C I/O를 사용하여 구현합니다.
디버그 세션 중에 SET INTERCEPT 명령으로 다음 이름을 사용할 수 있습니다.
system() 호출 경계를 통한 I/O 인터셉트 동작은 글로벌입니다. 프로그램 A system()이 프로그램 B로 호출하는 경우 프로그램 B에도 올바른 프로그램 A에서 INTERCEPT ON for xx 설정을 의미합니다. 따라서 프로그램 B에서 xx의 INTERCEPT OFF를 설정하면 프로그램 B가 A로 리턴될 때 프로그램 A에서 인터셉트를 해제합니다. 파일이 프로그램 B에서 인터셉트되어 프로그램 A로 리턴하는 경우 true입니다. 이 모델은 디스크 파일, 메모리 파일 및 표준 스트림에 적용합니다.
스트림이 인터셉트된 경우 fopen 명령문에서 지정된 텍스트/2진 속성은 전승됩니다. Debug Tool로 출력 및 입력 로그 파일은 다음 고려사항대로 단말기 I/O처럼 작동합니다.
인터셉트된 기타 특성은 다음과 같습니다.
표준 스트림의 명령행 리다이렉션은 아래 표시된 대로 Debug Tool에서 지원됩니다.
동일 표준 스트림은 명령행에 두 번 경로 재지정될 수 없습니다. 위반 시, 아래 표시되는 대로 인터셉트는 정의되지 않습니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
데이터 유형 및 선언된 이름이 블록 및 소스 파일에서 알려진 경우, 오브젝트는 블록 또는 소스 파일에서 visible입니다. 오브젝트가 표시되는 리젼은 범위에 따라 참조됩니다. Debug Tool에서 오브젝트는 변수 또는 함수일 수 있으며 행 번호를 참조하는 데 사용되기도 합니다.
ANSI C에서 네 종류의 범위는 다음과 같습니다.
C++의 경우 또한 C에 정의된 범위는 클래스 범위도 같습니다.
선언이 블록 내에 있는 경우 오브젝트는 블록 범위를 갖습니다. 블록 범위를 포함한 오브젝트는 블록을 종료하는 닫는 중괄호(})로 선언된 지점에서 표시될 수 있습니다.
정의가 블록 밖에서 나타나는 경우, 오브젝트는 파일 범위를 갖습니다. 이런 오브젝트는 소스 파일의 끝을 선언하는 지점에서 표시될 수 있습니다. Debug Tool에서, 파일 정적 변수를 포함한 컴파일 단위로 규정된 경우, 파일 정적 및 글로벌 변수는 항상 표시될 수 있습니다.
함수 범위를 포함한 오브젝트 유형만 레이블 이름입니다.
선언이 함수 프로토타입에서 매개변수 목록 내에 나타나는 경우 오브젝트는 함수 프로토타입 범위를 갖습니다.
선언이 클래스 내에 있는 경우 클래스 멤버는 클래스 범위를 갖습니다.
함수 프로토타입 범위에서 표시할 수 있는 오브젝트를 참조할 수 없으나 파일 또는 블록 범위에서 표시할 수 있는 오브젝트를 참조할 수 있습니다.
Debug Tool은 파일 범위에서 다르게 오브젝트를 처리하는 경우를 제외하고 ANSI로 동일 범위 규칙을 따릅니다. 파일 범위에서 오브젝트는 소스 파일 내 지점에서 Debug Tool 내에서 참조될 수 있으나 선언된 소스 파일의 지점에서는 참조되지 않습니다. Debug Tool 세션 변수는 항상 프로그램 변수보다 높은 범위를 갖고 지속적으로 동일 이름을 가진 프로그램 변수보다 우선순위가 높습니다. 프로그램 변수는 항상 자격 부여를 통해 액세스될 수 있습니다.
또한 Debug Tool은 다중 로드 모듈에서 변수 참조를 지원합니다. 다중 로드 모듈은 C 라이브러리 함수 dllload(), dllfree(), fetch() 및 release()을 통해 관리됩니다.
예제: C 및 C++ 블록에서 변수 참조 및 중단점 설정
Debug Tool은 다음 스토리지 클래스로 선언된 모든 오브젝트의 참조 및 변경을 지원합니다.
Debug Tool 세션 중에 선언된 세션 변수는 참조 및 변경에서 사용 가능합니다.
auto 스토리지 클래스를 포함한 오브젝트는 활성으로 정의된 블록을 제공받은 Debug Tool에서 참조 또는 변경에 사용 가능합니다. 일단 블록 실행이 완료되면 이 블록 내 auto 변수는 더 이상 변경할 수 없지만 DESCRIBE ATTRIBUTES를 사용하여 조사될 수 있습니다.
register 스토리지 클래스를 포함한 오브젝트는 레지스터를 최적화하지 못한 변수를 제공받은 Debug Tool에서 참조 또는 변경할 수 있습니다.
static 스토리지 클래스를 포함한 오브젝트는 Debug Tool에서 항상 변경 또는 참조할 수 있습니다. 현재 규정된 컴파일 단위에 없는 경우, 특별히 규정해야 합니다.
extern 스토리지 클래스를 포함한 오브젝트는 Debug Tool에서 항상 변경 또는 참조할 수 있습니다. 이 소스 파일 내에서 정의되거나 참조되지 않은 경우 프로그램의 변수와 같은 참조도 가능할 수 있습니다. 제공된 Debug Tool은 적당한 정의와 함께 TEST(SYM)로 컴파일된 다른 컴파일 단위를 찾을 수 있습니다.
현재 블록에서 바로 표시할 수 없는 참조 블록 또는 지정된 블록으로 시작이나 종료 시 중단점을 설정해야 합니다. Debug Tool은 이름 지정된 모든 블록에 이와 같이 중단점을 설정할 수 있습니다. 다음 이름 지정 규칙을 따릅니다.
이 블록명이 Debug Tool 명령에서 사용되는 경우 같은 소스 파일 내 다른 함수에서 중첩된 블록과 구분해야 합니다. 다음 두 방법 중 한 가지로 블록명 지정을 수행할 수 있습니다.
%BLOCKyyy는 %BLOCKzzz을 포함하며 %BLOCKxxx.에서 포함됩니다. 짧은 양식은 항상 허용되며 긴 양식을 지정해야 할 필요는 없습니다.
현재 활성 블록명은 Debug Tool 변수 %BLOCK에서 검색할 수 있습니다. 다음을 입력하여 블록 수를 표시할 수 있습니다.
DESCRIBE CU;
블록 ID는 C++ 함수가 오버로드될 수 있으므로 C보다 C++이 더 긴 편입니다. 함수명을 다른 것과 구분하기 위해 각 블록 ID는 프로토타입과 같습니다. 예를 들어, C에서 shapes(int,int)으로 이름 지정된 함수는 shapes 이름 지정된 블록이 있습니다. C++에서는 블록이 shapes(int,int)으로 호출됩니다.
함수가 오버로드되지 않더라도 전체에서 항상 C++ 블록 ID를 참조해야 합니다. 즉, shapes으로만 shapes(int,int)를 참조할 수 없습니다.
블록명이 상당히 길 수 있으므로 화면 첫 번째 행의 LOCATION 필드에서 잘린 이름을 볼 수 있습니다. 사용자 위치를 찾아 내려면 다음을 입력하십시오.
QUERY LOCATION
세션 로그에서 줄 바꾸기된 전체 이름이 표시됩니다.
블록 ID는 255자 길이로 제한됩니다. 어떤 이름이든지 255자를 넘을 경우 잘립니다.
아래 프로그램은 여러 예제에 대해 기본으로 사용되며 프로그램이 표시된 후에 설명됩니다.
#pragma runopts(EXECOPS)
#include <stdlib.h>
main()
{
>>> Debug Tool is given <<<
>>> control here. <<<
init();
sort();
}
short length = 40;
static long *table;
init()
{
table = malloc(sizeof(long)*length);
·
·
·
}
sort ()
{ /* Block sort */
int i;
for (i = 0; i < length–1; i++) { /* If compiled with ISD, Block %BLOCK2; */
/* if compiled with DWARF, Block %BLOCK8 */
int j;
for (j = i+1; j < length; j++) { /* If compiled with ISD, Block %BLOCK3; */
/* if compiled with DWARF, Block %BLOCK13 */
static int temp;
temp = table[i];
table[i] = table[j];
table[j] = temp;
}
}
}
위에 표시된 프로그램이 TEST(SYM)으로 컴파일되었다고 가정합니다. Debug Tool이 제어권을 획득한 경우 파일 범위 변수 length 및 table은 다음과 같이 변경될 수 있습니다.
length = 60;
블록 범위 변수 i, j 및 temp는 이 범위에서 볼 수 없으며 동시에 Debug Tool 내에서 직접 참조될 수 없습니다. 다음을 입력하여 현재 범위에서 행 번호를 나열할 수 있습니다.
LIST LINE NUMBERS;
이제 프로그램이 TEST(SYM, NOBLOCK)으로 컴파일되었다고 가정합니다. 프로그램이 명시적으로 NOBLOCK을 사용하여 컴파일되었으므로 Debug Tool은 변수 j 및 temp에 대해 알지 못 합니다. 다른 블록에서 중첩된 블록에서 변수가 정의되었기 때문입니다. 중첩된 범위 안에 있는 경우 Debug Tool은 변수 i를 인식하지 못합니다.
위 프로그램에서 sort 함수에는 다음 세 개의 블록이 있습니다.
| 프로그램이 ISD 컴파일러 옵션으로 컴파일되는 경우 | 프로그램이 DWARF 컴파일러 옵션으로 컴파일되는 경우 |
|---|---|
| sort | sort |
| %BLOCK2 | %BLOCK8 |
| %BLOCK3 | %BLOCK13 |
다음 예제에서는 sort의 두 번째 블록 시작 시 중단점을 설정합니다.
다음 예제에서는 main의 첫 번째 블록의 종료 시 중단점을 설정하고 정렬된 테이블 항목을 나열합니다.
at exit main {
for (i = 0; i < length; i++)
printf("table entry %d is %d₩n", i, table[i]);
}
다음 예제에서는 sort의 세 번째 블록에서 temp 변수를 나열합니다. 이는 temp에 static 스토리지 클래스가 있으므로 가능합니다.
DESCRIBE 명령을 사용하여 현재 런타임 환경에 적용 가능한 속성 목록도 표시할 수 있습니다. 표시되는 정보 유형은 언어마다 다양합니다.
DESCRIBE ENVIRONMENT를 실행하여 열린 파일 목록 및 런타임 환경에서 모니터된 조건을 표시합니다. 예를 들어, C 또는 C++ 프로그램을 디버깅하는 중에 DESCRIBE ENVIRONMENT를 입력하면 다음 출력을 확인할 수 있습니다.
Currently open files
stdout
sysprint
The following conditions are enabled:
SIGFPE
SIGILL
SIGSEGV
SIGTERM
SIGINT
SIGABRT
SIGUSR1
SIGUSR2
SIGABND
자격 부여는 다음 중 한 메소드 입니다.
프로그램이 다중 모듈, 컴파일 단위 및/또는 함수로 구성되는 경우 이름 충돌로 인해 자격 부여는 자주 필요합니다.
프로그램 실행이 일시중단되고 Debug Tool이 제어권을 수신한 경우 기본 또는 암시적 자격 부여는 프로그램 일시중단 지점에 활성 블록입니다. 이 블록에서 C 또는 C++ 프로그램에 표시할 수 있는 모든 오브젝트가 Debug Tool에서도 표시될 수 있습니다. 해당 오브젝트는 규정자를 사용하지 않고 명령에서 지정될 수 있습니다. 다른 오브젝트는 명시적 자격 부여를 사용하여 지정되어야 합니다.
규정자는 당연히 사용자가 작업 중인 시스템의 이름 지정 규칙을 따릅니다.
사용자가 알고 있는 다음을 제공하여 오브젝트를 정확하게 지정할 수 있습니다.
규정자로서 일부 또는 전체에 대한 알려진 이 정보들이 명령에서 오브젝트를 참조할 때 필요할 수 있습니다. 규정자는 부호(>) 및 콜론을 제외하고 더 큰 조합에 의해 구분될 수 있으며 규정한 오브젝트를 선행합니다. 예를 들어, 다음은 완전히 규정된 오브젝트입니다.
load_name::>cu_name:>block_name:>object
필요한 경우 load_name은 로드 모듈의 이름입니다. 프로그램이 여러 로드 모듈로 구성되고 자격 부여를 현재 로드 모듈 이외의 로드 모듈로 변경할 경우에만 필요합니다. load_name은 큰따옴표(") 안에 있습니다. 그렇지 않은 경우, C 또는 C++ 프로그래밍 언어에서 올바른 ID여야 합니다. load_name은 Debug Tool 변수 %LOAD일 수도 있습니다.
필요한 경우 CU_NAME은 컴파일 단위 또는 소스 파일명입니다. cu_name은 완전한 소스 파일명 또는 절대 경로명이어야 합니다. 현재 규정된 컴파일 단위를 제외한 다른 것으로 자격 부여를 변경하려고 할 때에만 필요합니다. Debug Tool 변수 %CU일 수 있습니다. 예를 들어, 컴파일 장치명과 블록명을 혼동할 우려가 있는 경우에는 컴파일 장치명을 큰따옴표(") 안에 넣어야 합니다.
필요한 경우 block_name은 블록명입니다. block_name은 Debug Tool 변수 %BLOCK이 될 수 있습니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
명령행 또는 명령 파일에서 보기 지점을 변경하려면 SET QUALIFY 명령과 함께 규정자를 사용하십시오. 현재 보기 지점에서 액세스할 수 없는 데이터를 가져올 때 필요할 수 있거나 참조되고 있는 오브젝트의 수를 간단하게 디버깅할 수 있습니다.
다른 로드 모듈로 보기 지점을 변경하거나 다른 컴파일 단위, 중첩된 블록 또는 중첩되지 않은 블록으로 DLL을 변경할 수 있습니다. SET 키워드는 선택적입니다.
아래 예제에서는 다음 프로그램을 사용합니다.
LOAD MODULE NAME: MAINMOD
SOURCE FILE NAME: MVSID.SORTMAIN.C
short length = 40;
main ()
{
long *table;
void (*pf)();
table = malloc(sizeof(long)*length);
·
·
·
pf = fetch("SORTMOD");
(*pf)(table);
·
·
·
release(pf);
·
·
·
}
LOAD MODULE NAME: SORTMOD
SOURCE FILE NAME: MVSID.SORTSUB.C
short length = 40;
short sn = 3;
void (long table[])
{
short i;
for (i = 0; i < length-1; i++) {
short j;
for (j = i+1; j < length; j++) {
float sn = 3.0;
short temp;
temp = table[i];
·
·
·
>>> Debug Tool is given <<<
>>> control here. <<<
·
·
·
table[i] = table[j];
table[j] = temp;
}
}
}
Debug Tool이 제어권을 수신한 경우, 변수 i, j, temp, table 및 length는 명령에서 규정자 없이 지정될 수 있습니다. 변수 sn이 참조되면 Debug Tool은 float 변수를 사용합니다. 그러나 운영 체제와 호환성이 유지보수되는 경우 블록 및 컴파일 단위 이름이 다릅니다.
"SORTMOD"::>"MVSID.SORTSUB.C":>length = 20;
%LOAD::>"MVSID.SORTMAIN.C":>length = 20;
length가 현재 로드 모듈 및 컴파일 단위에 있기 때문에 변경될 수도 있습니다.
length = 20;
AT CHANGE temp; AT CHANGE %BLOCK3:>temp; AT CHANGE sort:%BLOCK3:>temp; AT CHANGE %BLOCK:>temp; AT CHANGE %CU:>sort:>%BLOCK3:>temp; AT CHANGE "MVSID.SORTSUB.C":>sort:>%BLOCK3:>temp; AT CHANGE "SORTMOD"::>"MVSID.SORTSUB.C":>sort:>%BLOCK3:>temp;
이 예제의 %BLOCK 및 %BLOCK3 변수는 프로그램이 ISD 컴파일러 옵션으로 컴파일되었다고 가정합니다. 예제가 DWARF 컴파일러 옵션으로 컴파일된 경우, DESCRIBE PROGRAM 명령을 입력하여 올바른 %BLOCK 변수를 판별하십시오.
SET QUALIFY BLOCK %BLOCK2;다음을 포함하는 다른 방법의 수로 실행할 수 있습니다.
QUALIFY BLOCK sort:>%BLOCK2;
보기 지점이 변경되면 Debug Tool은 이 보기 지점에서 액세스 가능한 오브젝트로 액세스합니다. 다음과 같이 규정자 없는 명령으로 이 오브젝트를 지정할 수 있습니다.
j = 3; temp = 4;
QUALIFY BLOCK "MAINMOD"::>"MVSID.SORTMAIN.C":>main; LIST table[i];
생성되고 폐기되는 오브젝트로 메소드를 step through할 수 있습니다. 또한 정적 생성자 및 폐기자를 step through할 수 있습니다. main() 전후에 각각 실행된 오브젝트 메소드입니다.
헤더 파일에 있는 함수를 호출하는 프로그램을 디버깅하는 경우 커서는 적용 가능한 헤더 파일로 이동합니다. 이를 step through하여 함수 소스를 볼 수 있습니다. 함수가 리턴되면 원래 함수 호출의 그 다음 행에서 디버깅이 계속됩니다.
STEP OVER 명령을 실행해서 헤더 파일 함수를 스텝할 수 있습니다. 디버깅할 수 없는 string.h에서 정의된 문자열 함수와 같은 라이브러리 함수를 스테핑하는 데 유용합니다.
C++ 및 C의 중단점 설정 방법의 차이를 아래에서 설명합니다.
AT ENTRY/EXIT이 지정된 블록에 중단점을 설정합니다. 메소드, 중첩된 클래스 내 메소드, 템플리트 및 오버로드된 연산자에 중단점을 설정할 수 있습니다. 각각 아래에 해당 예제가 있습니다.
블록 ID는 특히 템플리트, 중첩된 클래스 또는 상속 레벨이 많은 클래스에 상당히 깁니다. 특정 함수의 블록명으로 처음에 명백하지 않을 수 있습니다. 중요한 블록에 중단점을 설정하는 것이 상당히 번거로울 수 있습니다. 그러므로 DESCRIBE CU를 사용해서 세션 로그에서 블록 ID를 검색하는 방법을 권장합니다.
DESCRIBE CU를 수행한 경우 메소드는 항상 클래스에 의해 규정된 것을 표시합니다. 메소드가 고유한 경우 바로 메소드 이름을 사용하여 중단점을 설정할 수 있습니다. 그렇지 않은 경우, 클래스 이름으로 메소드를 규정해야 합니다. 다음 두 예제는 동일합니다.
AT ENTRY method() AT ENTRY classname::method()
다음 예제는 유효합니다.
| AT ENTRY square(int,int) | '단순' 메소드 스퀘어입니다. |
| AT ENTRY shapes::square(int) | 클래스 쉐이프로 규정된 메소드 스퀘어입니다. |
| AT EXIT outer::inner::func() | 중첩된 클래스입니다. 외부 및 내부가 클래스입니다. func()는 클래스 내부에 있습니다. |
| AT EXIT Stack<int,5>::Stack() | 템플리트입니다. |
| AT ENTRY Plus::operator++(int) | 오버로드된 연산자입니다. |
| AT ENTRY ::fail() | 파일 범위에서 정의된 함수는 글로벌 범위 연산자(::)가 참조해야 합니다. |
다음 예제는 올바르지 않습니다.
| AT ENTRY shapes | 쉐이프 위치가 클래스입니다. 클래스에 중단점을 설정할 수 없습니다. (클래스에는 블록 ID가 없습니다.) |
| AT ENTRY shapes::square | 메소드 스퀘어는 매개변수 목록 앞에 있어야 하므로 올바르지 않습니다. |
| AT ENTRY shapes:>square(int) | 쉐이프는 블록명이 아니라 클래스 이름이므로 올바르지 않습니다. |
애플리케이션 코드가 지정된 시작점을 호출하려고 할 때 AT CALL이 Debug Tool에 제어권을 부여합니다. 시작 이름은 완전한 이름이어야 합니다. 즉, DESCRIBE CU로 표시되는 이름이 사용되어야 합니다. 다음 예제를 사용합니다.
AT ENTRY shapes::square(int)
메소드 스퀘어에서 중단점을 설정하려면 다음을 입력하십시오.
AT CALL shapes::square(int)
스퀘어가 고유하게 식별되었을 경우에도 다음을 입력하십시오.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
C++ 오브젝트를 표시할 경우 로컬 멤버 변수만 표시됩니다. 액세스 유형(공용, 개인용, 보호)는 변수 사이에서 구별되지 않습니다. 멤버 함수는 표시되지 않습니다. 속성을 보려면 구성원을 클래스 컨텍스트가 아닌 개별적으로 표시하십시오. 파생 클래스를 표시하려면 파생 클래스 안에 기본 클래스가 유형 클래스로 표시되고 확장되지 않습니다.
이 절에서 설명하는 자료와 연관된 자세한 정보에 대해서는 다음 주제를 참조하십시오.
아래 예제에서는 다음 정의를 사용합니다.
class shape { ... };
class line : public shape {
member variables of class line...
}
line edge;
오브젝트 edge 속성을 설명하려면 다음 명령을 입력하십시오.
DESCRIBE ATTRIBUTES edge;
로그 창이 다음 출력을 표시합니다.
DESCRIBE ATTRIBUTES edge;
속성: edge
주소: yyyyyyyy, 길이: xx
class line
class shape
member variables of class shape....
기본 클래스가 클래스 쉐이프 _shape로 표시됨을 참고하십시오.
shape 클래스 속성을 표시하려면 다음 명령을 입력하십시오.
DESCRIBE ATTRIBUTES class shape;
로그 창이 다음 출력을 표시합니다.
DESCRIBE ATTRIBUTES class shape ; 속성: class shape const class shape...
클래스가 정적 데이터를 포함하는 경우 정적 데이터는 클래스의 일부로 표시됩니다. 예를 들면 다음과 같습니다.
class A {
int x;
static int y;
}
A obj;클래스 A의 각 오브젝트가 같은 값을 가지므로 A::y으로 참조한 정적 멤버도 표시할 수 있습니다.
혼동을 막기 위해 파일 범위에서 선언된 변수는 글로벌 범위 연산자 ::을 사용하여 참조될 수 있습니다. 예를 들면 다음과 같습니다.
int x;
class A {
int x;
·
·
·
}
}
A의 멤버 함수 내에 있고 파일 범위에서 x 값을 표시하려면 LIST ::x을 입력하십시오. ::을 사용하지 않은 경우 LIST x을 입력하면 현재 오브젝트(예: this–>x)에 대한 x 값이 표시됩니다.
LIST REGISTERS 명령을 사용하여 사용자 코드 및 어셈블리 목록을 통해 스테핑하는 동안 레지스터 감시(일반 용도 및 부동 소수점)하는 데 유용할 수 있습니다. 컴파일러 목록은 Debug Tool 후크를 포함한 의사 어셈블리 코드를 표시합니다. 후크 사이에 의사 어셈블리 지시사항과 함께 단계별 레지스터 값에서 예상된 변경을 감시하고 중지하는 후크를 감시할 수 있습니다. 사용자 코드를 통해 스테핑하는 동안 시스템 레지스트 값을 수정할 수도 있습니다.
다양한 방법으로 스토리지 컨텐츠를 나열할 수 있습니다. LIST REGISTERS 명령을 사용하여 일반적인 용도의 레지스터 또는 부동 소수점 레지스터의 컨텐츠 목록을 받을 수 있습니다.
스토리지의 덤프 형식 표시를 지정하여 스토리지의 컨텐츠를 모니터할 수도 있습니다. 이것을 수행하려면 LIST STORAGE 명령을 사용하십시오. 바이트 수와 사용자가 보려고 하는 주소를 지정할 수 있습니다.
아래 예제에서는 다음 C 프로그램을 사용하여 레지스터 및 스토리지를 모니터링하고 수정하는 방법을 설명합니다.
int dbl(int j) /* line 1 */
{ /* line 2 */
return 2*j; /* line 3 */
} /* line 4 */
int main(void)
{
int i;
i = 10;
return dbl(i);
}
위의 예제처럼 컴파일러 옵션 TEST(ALL),LIST을 사용하여 프로그램을 컴파일하면 의사 어셈블리 목록이 아래 표시된 목록과 유사합니다.
* int dbl(int j)
ST r1,152(,r13)
* {
EX r0,HOOK..PGM-ENTRY
* return 2*j;
EX r0,HOOK..STMT
L r15,152(,r13)
L r15,0(,r15)
SLL r15,1
B @5L2
DC A@5L2-ep)
NOPR
@5L1 DS 0D
* }
@5L2 DS 0D
EX r0,HOOK..PGM-EXIT
모니터 창에 지속적으로 레지스터 업데이트 보기를 표시하려면 다음 명령을 입력하십시오.
MONITOR LIST REGISTERS
몇 단계 이후에 Debug Tool은 라인 1(위 목록에서 표시된 프로그램 입력 후크)에서 정지합니다. 다른 STEP을 따라 행 3으로 이동한 후 명령문 후크에서 정지합니다. 다음 STEP을 따라 행 4로 이동한 후 프로그램 종료 후크에서 정지합니다. 의사 어셈블리 목록에 의해 표시된 대로 레지스터 15만 STEP 중에 변경되고 함수 리턴 값을 포함합니다. 모니터 창에서 레지스터 15는 예상한대로 값 0x00000014(10진수 20)을 갖습니다.
이 명령을 실행하여 dbl()에서 리턴하기 전에 값을 20에서 8로 변경할 수 있습니다.
%GPR15 = 8 ;