본문 바로가기

Java/트러블슈팅

02. 디버깅 기법으로 앱 로직 이해하기

💡 본 게시글은 라우렌치우 스필커 저자의 '자바 잘 읽는 법' 교재를 공부하고, 이에 대해 정리한 내용입니다.

들어가며

 매일 코드를 작성하면서도 능숙하게 문제를 해결하는 선배 개발자를 볼 때마다 부러움을 느낍니다. 코드 리뷰를 받을 때마다 항상 많은 것을 배우지만, 동시에 더 빨리 성장하고 싶은 마음이 간절합니다. 그러던 중 신입 개발자들이 디버깅을 하지 않고 대부분 출력문을 이용해 검증한다는 말을 듣고 뜨끔했습니다. 저 역시 대부분 검증을 출력으로 진행했기 때문입니다. 그래서 디버깅이 왜 필요한지, 그리고 그 사용 방법을 정리해보고자 합니다.

※ 디버거란?

  • 원하는 코드 라인에서 실행을 잠깐 멈추고 각 커맨드를 수동 실행하며 데이터가 어떻게 바뀌는지 확인할 수 있는 도구

1) 코드 분석만으로는 불충분한 경우

 코드를 읽는 것만으로는 코드를 이해하기 쉽지 않습니다. 그 이유는 무엇일까?

  • 첫째, 코드는 선형적(linear)이지 않습니다. 코드는 한 줄씩 순서대로 읽는 것이 아니라, 메서드 사이를 왔다 갔다 하며 데이터가 어떻게 이동하고, 처리되는지 해당 로직을 파악해야 합니다.
  • 둘째, 코드는 모든 사람에게 동일한 의미를 가집니다. 이 의미를 정확히 이해하는 것이 코드 분석의 목표입니다. 코드를 통해 실제로 어떤 작업이 이루어지는지 자세히 살펴보고, 그 배후에 숨겨진 로직과 작동 원리를 파악해야 합니다. 이렇게 하면 코드가 의도한 대로 작동하는지 확인할 수 있으며, 더 나아가 코드를 개선하거나 문제를 해결하는 데 도움이 됩니다.

※ Tip. 코드 조사를 할 때에는 가급적 열린 플랜 수를 줄여 읽기 경로를 단축해야 합니다.
- 디버거를 사용하면 코드를 더 쉽게 탐색하고, 현재 위치를 추적하며, 앱 실행 도중 데이터가 어떻게 바뀌는지 관찰할 수 있습니다. 이를 통해 코드를 보다 체계적으로 이해하고, 문제를 빠르게 발견하고 해결할 수 있습니다.


2) 디버거를 이용한 코드 조사

(1) 디버거를 사용하면 조사 프로세스가 간소화됩니다.

  • 특정 스텝에서 잠깐 실행을 멈추고 각 커맨드를 본인 페이스에 맞게 수동 실행할 수 있습니다.
  • 코드 읽기 경로상의 현재 위치와 출처를 표시함으로써 세부 정보를 일일이 다 기억하지 않아도 편리한 안내 지도 역할을 합니다.
  • 변수에 어떤 값이 담겼는지 화면에 표시되어 코드 조사가 더 눈에 잘 띄고 쉽게 진행할 수 있습니다.
  • 와처(watcher)로 즉석에서 원하는 동작을 바로 시험하거나 표현식을 평가할 수 있습니다.

(2) 디버거를 언제 사용해야 할까?

  • 지금 내가 조사하려는 로직이 무엇인지를 꼭 알아야 합니다. 어느 커맨드부터 코드 조사를 시작해야 할지도 모르면 디버거를 사용할 수 없습니다.

(3) 디버거 사용방법

  • 먼저, 코드를 읽어보고 이해가 되는 부분과 안 되는 부분을 파악합니다.
  • 로직이 불분명한 곳을 찾아냈다면 앱을 실행하고, 그 위치에서 실행을 멈추도록 디버거에게 지시합니다.
  • 이해가 안 되는 코드 라인에서 실행을 멈추고 데이터가 어떻게 변경되는지 들여다 봅니다.
  • 앱 실행을 중단시킬 위치는 브레이크포인트를 찍어 표시합니다.
  • 디버거로 앱을 실행합니다.

※ Tip. 디버거로 코드를 조사할 때는 이해할 수 없는 코드의 첫 라인부터 시작합니다. 
- 주니어 개발자를 보면서 그들이 특정 코드 블록의 첫 라인부터 디버깅을 시작하는 모습을 숱하게 봤습니다. 그러나 디버거 없이 먼저 코드를 읽고 이해할 수 있는지 확인하는 편이 효과적입니다. 그런 다음에 문제가 되는 지점부터 바로 디버깅을 시작해야 합니다. 그래야 굳이 디버거를 사용하지 않고도 어떤 로직에서 무슨 일이 일어나는지 알 수 있으므로 시간이 절약됩니다.

- 윈도우 / 리눅스 : ctrl + F8
- macOS : command + F8


(4) 디버거의 정보

  • 스코프 내 모든 변수 값
  • 실행 스택 트레이스

3) 실행 스택 트레이스란 무엇이고, 어떻게 사용해야 할까?

(1) 스택 트레이스란?

  • 스택 트레이스는 디버거가 실행을 멈춘 지점까지 메서드가 어떻게 호출되는지를 나타냅니다.
  • 메서드명, 클래스명, 호출한 코드 라인을 자세히 표시합니다.

(2) 스택 트레이스의 사용 이유

  • 스택 트레이스를 통해 코드가 어떻게 실행되는지, 어떤 경로로 메서드가 호출되었는지 파악할 수 있습니다.
  • 이는 디버깅 과정에서 문제의 원인을 찾고 해결하는 데 유용합니다.

(3) 프레임워크 사용 시 주의 사항

  • 스프링이나 하이버네이트 같은 프레임워크를 사용하는 앱은 메서드의 실행 체인을 바꾸는 경우가 많습니다.
  • 예를 들어, 스프링 프레임워크에서는 애스펙트(aspect)라는 장치를 사용해 디커플링된 코드를 사용합니다.
  • 따라서 코드를 읽을 때 추가로 실행될 로직이 있다는 사실을 파악하기 어렵습니다.
  • 이러한 숨겨진 로직이 실행될 때에는 코드 조사가 혼란스러울 수 있습니다.

출처: https://java-is-happy-things.tistory.com/41

 


4) 디버거로 코드 탐색하기

(1) 디버거로 코드를 탐색하는 세 가지 기본 기술

  • 스텝 오버(step over)
    • 동일한 메서드에서 다음 코드 라인으로 계속 실행합니다.
  • 스텝 인투(step into)
    • 현재 라인에서 호출된 메서드 중 하나의 내부에서 실행을 계속합니다.
  • 스텝 아웃(step out)
    • 조사하던 메서드를 호출한 메서드로 실행을 되돌립니다.

'Java > 트러블슈팅' 카테고리의 다른 글

01. 애플리케이션의 문제점 찾기  (0) 2024.05.16