ABAP 디버깅 완전 정복 (2) 실전편 – 브레이크포인트·워치포인트와 상황별 디버깅

ABAP 디버깅 시리즈

1편에서 /h로 디버거를 켜고 F5~F8로 코드를 따라가는 기본기를 익혔습니다. 이제부터가 실제 업무에서 쓰는 부분입니다.

실무에서 마주치는 문제는 대개 이런 형태입니다. “에러 메시지가 떴는데 어느 코드에서 나온 건지 모르겠다”, “변수 값이 언젠가 이상해지는데 어디서 바뀌는지 모르겠다”, “배치 잡이라서 /h를 쓸 수가 없다”. 이런 상황을 해결하는 도구들을 다룹니다.

⚠️ 이 글의 기능 중 값 변경과 관련된 부분은 개발/테스트 시스템 전용입니다. 운영 시스템에서는 조회 목적으로만 사용하세요.


1. 브레이크포인트 종류 총정리

1편에서는 에디터에서 클릭하는 방식만 다뤘습니다. 실제로는 유효 범위가 다른 네 가지가 있고, 이 차이를 모르면 “브레이크포인트를 걸었는데 안 멈춘다”는 상황을 계속 겪게 됩니다.

종류유효 범위특징
Static Breakpoint소스에 박혀 있음BREAK-POINT, BREAK <USER>. 이관 시 삭제 필수
Session Breakpoint현재 SAP GUI 세션 + 본인에디터에서 클릭해 설정. 원격 디버깅에는 동작 안 함
External Breakpoint시스템 전체 서버 + 지정 사용자RFC, HTTP, OData, 백그라운드 호출을 잡을 때 사용
Debugger Breakpoint현재 디버거 세션만디버거 안에서 임시로 건 것. 디버거 종료 시 사라짐

제한사항

한 프로그램에 브레이크포인트 최대 30개, 워치포인트 최대 10개 까지만 설정 가능합니다.

External Breakpoint 설정법

Fiori 화면이나 인터페이스(OData/RFC) 디버깅에 필수입니다.

  1. SE38/SE80 메뉴에서 Utilities → Settings
  2. ABAP Editor → Debugging
  3. Users 항목에 본인 사용자 ID 입력 (Session ID는 보통 공란)
  4. 저장 후, 브레이크포인트를 설정할 때 External 유형을 선택

이 설정을 해두면 외부 시스템에서 호출이 발생했을 때 내 화면에 디버거가 자동으로 뜹니다.


2. 워치포인트 (Watchpoint)

“이 변수 값이 대체 어디서 바뀌는 거지?” 를 해결하는 기능입니다.

브레이크포인트가 “이 에서 멈춰라”라면, 워치포인트는 “이 변수 값이 바뀌면 멈춰라”입니다. 코드가 수천 줄이고 어디서 값이 오염되는지 모를 때 결정적입니다.

설정 방법

  1. 디버거에 진입한 상태에서 대상 변수를 확인합니다.
  2. 상단 메뉴 Breakpoints → Watchpoint → Create (또는 변수 우클릭 → Create Watchpoint)
  3. 감시할 변수명 입력 (예: LV_TOTAL)
  4. 조건 설정 (선택)
    • 조건 없음 → 값이 바뀔 때마다 멈춤
    • LV_TOTAL > 1000000 → 특정 조건을 만족할 때만 멈춤
  5. F8로 실행하면 조건 충족 시점에 자동으로 멈춥니다.

New Debugger에서 추가된 기능

  • 인터널 테이블에도 워치포인트 설정 가능 (잘못된 행이 삽입되는 순간 포착)
  • 오브젝트 속성(Class Attribute)에도 설정 가능
  • 조건식에 비교 연산자뿐 아니라 복합 조건 사용 가능

주의

워치포인트는 현재 디버거 세션에서만 유지됩니다. 디버거를 닫으면 사라지므로 재현할 때마다 다시 걸어야 합니다.


3. 값 변경과 데이터 분석 도구

값 변경하기

  1. 변경할 변수 옆의 연필 아이콘(Change) 클릭
  2. 새 값을 입력하고 Enter

인터널 테이블도 New Debugger에서는 행 삽입 / 수정 / 삭제가 모두 가능합니다. 예외 케이스를 재현하기 어려울 때 매우 유용합니다.

값 변경 아이콘이 비활성 상태라면 S_DEVELOP ACTVT=02 권한이 없는 것입니다. 운영 시스템에서는 정상적인 상태입니다.

Diff Tool – 오브젝트 비교

“기대한 테이블과 실제 테이블이 뭐가 다르지?”를 눈으로 비교하는 기능입니다.

  • 인터널 테이블, 구조체, 단일 변수, 클래스 변수 모두 비교 가능
  • Variable 1, Variable 2에 비교 대상을 입력하고 Start Comparison 실행
  • 차이가 있는 항목만 리스팅해 줍니다

행이 수백 개인 인터널 테이블이나 필드가 많은 구조체 비교에 특히 좋습니다.


4. 실전 시나리오 7가지

시나리오 1 — 에러 메시지의 원인을 찾고 싶다

가장 자주 마주치는 상황이자, 가장 효과가 큰 기법입니다.

  1. 화면에 뜬 에러 메시지를 클릭(또는 더블클릭)
  2. 팝업에서 메시지 클래스메시지 번호를 확인 (예: 클래스 F5, 번호 104)
  3. 해당 트랜잭션을 다시 실행하고 /h 입력
  4. 디버거에서 메뉴 Breakpoints → Breakpoint At → Message
  5. 메시지 클래스(F5)와 번호(104) 입력
  6. F8 실행 → 메시지가 발생하는 바로 그 줄에서 멈춥니다

이제 그 줄 앞의 IF 조건과 변수 값을 보면, 왜 이 메시지가 떴는지 정확히 알 수 있습니다.

시나리오 2 — 어느 SELECT가 잘못된 데이터를 가져오는지 모르겠다

프로그램에 SELECT가 15개쯤 있을 때 씁니다.

  1. 디버거에서 Breakpoints → Breakpoint At → Statement
  2. ABAP Cmnds 탭에 SELECT 입력
  3. F8 실행 → 모든 SELECT 구문마다 순서대로 멈춥니다
  4. 각 시점의 SY-SUBRC와 결과 테이블을 확인

같은 방식으로 LOOP, MESSAGE, CALL FUNCTION, INSERT, UPDATE 등 어떤 ABAP 키워드에도 걸 수 있습니다. 이벤트(START-OF-SELECTION, AT SELECTION-SCREEN) 단위 설정도 Breakpoint At → Event로 가능합니다.

시나리오 3 — 펑션모듈 하나만 따로 테스트하고 싶다

  1. SE37에서 펑션모듈명 입력
  2. Test/Execute (F8) 클릭
  3. 파라미터 입력 화면에서 실행 전에 커맨드 필드에 /h 입력
  4. 실행 버튼 클릭 → 펑션모듈 첫 줄부터 디버깅 시작

시나리오 4 — 백그라운드 잡을 디버깅하고 싶다

배치 잡은 화면이 없어서 /h를 쓸 수 없습니다.

  1. SM37에서 대상 잡을 조회
  2. 잡을 선택(체크)한 상태에서 커맨드 필드에 JDBG 입력 후 Enter
  3. 디버거가 열립니다 (처음엔 SAP 표준 코드에서 시작)
  4. F7을 몇 번 눌러 실제 프로그램 영역으로 빠져나온 뒤 진행

이미 실행 중인 잡을 잡으려면 SM50에서 해당 프로세스를 선택하고 메뉴 Administration → Program → Debugging을 사용합니다.

시나리오 5 — User Exit / BAdI 안에서 멈추고 싶다

  1. 해당 Exit의 인클루드나 BAdI 구현 클래스를 SE38/SE24로 엽니다
  2. 브레이크포인트 설정 (Session Breakpoint로 대부분 동작)
  3. 트랜잭션을 평소처럼 실행하면 해당 지점에서 멈춥니다

시나리오 6 — 인터페이스(RFC / OData) 디버깅

외부 시스템에서 호출되는 코드는 내 세션이 아니므로 Session Breakpoint가 동작하지 않습니다.

  1. Utilities → Settings → Debugging에서 본인 사용자 ID 등록
  2. 대상 코드에 External Breakpoint 설정
  3. 외부에서 호출이 발생하면 내 화면에 디버거가 자동으로 뜹니다

OData 서비스는 Eclipse ADT에서 브레이크포인트를 거는 편이 더 안정적입니다.

시나리오 7 — 업데이트 태스크 디버깅

CALL FUNCTION ... IN UPDATE TASK로 호출되는 로직은 COMMIT WORK 이후 별도 프로세스에서 실행되기 때문에 일반 디버깅으로는 잡히지 않습니다.

  1. 디버거 진입 후 메뉴 Settings → Update Debugging 체크
  2. 또는 처음부터 /hs로 진입
  3. COMMIT WORK를 지나면 업데이트 모듈에서 다시 멈춥니다

5. 브레이크포인트 관리 메뉴 활용

디버거가 열린 상태에서 상단 Breakpoints 메뉴를 열면 유용한 옵션들이 있습니다.

메뉴기능
Delete all bps모든 브레이크포인트 삭제 (영구)
Deactivate all bps이번 세션에서만 무시. 재실행 시 다시 동작
Activate all bps비활성화 해제
Save bps (Ctrl+S)브레이크포인트 세트를 저장해 다음에 재사용

특히 Deactivate all bps는 LOOP 안에 브레이크포인트를 걸어놓고 “이번 한 번만 그냥 통과시키고 싶을 때” 유용합니다. Delete와 달리 다음 실행에서는 다시 살아납니다.


6. 자주 겪는 문제와 해결

증상원인 / 해결
/h 입력해도 디버거가 안 열림S_DEVELOP 권한 부족. Basis에 요청
브레이크포인트가 안 잡힘주석·선언문에 걸었거나, 해당 코드가 실행 경로에 없음
RFC 호출인데 안 멈춤Session이 아닌 External Breakpoint로 설정 필요
배치 잡이 안 잡힘SM37 + JDBG 사용
프로그램 수정 후 엉뚱한 줄에 걸림소스 활성화(Activate) 후 다시 설정
디버거가 표준 코드로 계속 들어감F5 대신 F6 사용, 잘못 들어갔으면 F7
값 변경 아이콘이 비활성S_DEVELOP ACTVT=02 권한 없음 (운영에서는 정상)
워치포인트가 사라짐디버거 세션 종료 시 자동 삭제됨. 정상 동작

7. 디버깅 실력을 빠르게 올리는 팁

  1. SY-SUBRC를 습관적으로 보세요. 대부분의 버그는 “예상한 데이터가 안 나왔다”에서 시작합니다.
  2. 콜스택(Call Stack)을 읽는 습관을 들이세요. 지금 이 코드가 어디서 호출됐는지 알면 원인 범위가 크게 좁아집니다.
  3. F5보다 F6을 먼저 쓰세요. 큰 흐름을 먼저 파악하고, 문제 구간이 좁혀지면 그때 F5로 파고듭니다.
  4. 에러 메시지 브레이크포인트를 최우선으로 시도하세요. 원인 파악 시간을 극적으로 줄여줍니다.
  5. 디버깅 전에 가설을 세우세요. “이 변수가 초기값일 것이다” 같은 가설이 있어야 확인할 대상이 명확해집니다.

마무리

2편에서 다룬 내용을 정리하면 이렇습니다.

  • 브레이크포인트는 유효 범위(Session / External / Static / Debugger)를 구분해서 써야 한다
  • 변수 오염 추적에는 워치포인트가 가장 빠르다
  • 에러 원인은 Message 브레이크포인트로 바로 찾을 수 있다
  • 배치는 JDBG, 인터페이스는 External Breakpoint, 업데이트 태스크는 /hs

기본기가 아직 익숙하지 않다면 1편 기본편을 먼저 보시길 권합니다.

다음 글에서는 Eclipse ADT 환경에서의 디버깅CDS View / OData 서비스 디버깅 방법을 다뤄보겠습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤