본문 바로가기
개발 관련 강의 정리/10분 테코톡

[10분 테코톡] 오리의 Intellij Debugging 정리

by 코딩개발 2023. 6. 10.
728x90
반응형

디버깅이란?
프로그래밍 과정에서 발생한 오류를 파악하고 또 파악한 오류를 수정하는 일련의 과정

 


인텔리제이에서는 디버깅을 이용자들이 손쉽게 수행할 수 있도록 또 효과적으로 할 수 있도록 별도의 디버깅 기능을 제공해 준다.

 


인텔리제에서 디버깅을 수행할 때 가장 시작점은 브레이킹 포인트를 설정하는 것이다. 말 그대로 멈출 지점으로 선택하는 것인데, 예를 들어 위와같이 move라는 메소드의 특정한 라인에 브레이킹 포인트를 설정 했다고 생각해 보자. 그렇다면 디버그시 이 라인이 호출 된다면 그 직전에 디버그는 멈추게 된다. 말 그대로 브레이크 하는 것이다. 만약 디버그를 수행하는데 브레이킹 포인트가 설정된 부분을 만나지 않는다면 멈추지 않고 쭉 진행될 뿐이다. 

 

 

이 테스트 코드는 move라는 메소드를 호출하고 있다. 그래서 만약 이 테스트 코드를 디버그를 한다면 그 이전에 내가 예상치 못한 예외를 만나서 터지는 게 아닌 이상 우리가 설정한 브레이킹 포인트에서 멈추게 될 것이다. 이 테스트 코드를 디버그 수행한다.

 

 

그러면 브레이킹 포인트를 설정한 라인에서 멈추게 된다. 현재 이 상태는 이전 라인까지 실행된 상태이다. 브레이킹 포인트가 걸린 라인은 아직 실행되지 않은 직전의 상태이다. 이 상태에서 좌측 하단에는 어떻게 여기까지 거슬러 올라가게 되었는지 stack trace가 나타나고 우측 하단에 맵핑된 정보나 객체들을 볼 수 있다. 예를 들어 인자로 소스나 타겟이 넘어왔는데 그 정보를 내부에서 확인할 수 있고, 필드에는 source piece, target piece등이 있는데 source piece의 컬러는 화이트이고 piece 타입은 퀸이다. 이렇게 브레이크를 설정한 후 하나하나 로직을 진행하면서 어떻게 진행되는지 어떻게 객체가 맵핑되는지 확인하는 게 디버깅의 과정이다. 


여기서 여러가지 이동할 수 있는 기능들이 있는데 이것에 대해서 알아보자

 

Resume은 다음 브레이크 포인트로 이동한다. 현재 위와같이 라인에 브레이크가 걸려있는데, 만약 turn.nextTurn이라는 라인에 우리가 추가적인 브레이크 포인트를 설정하고 Resume을 설정 하면은 그 사이에 있는 코드는 모두 실행 된다. 그리고 turn.nextTurn이 호출되기 직전의 상태에서 break가 된 것이다.

 


step over는 다음 라인으로 이동한다. 현재 라인의 코드를 실행하고 다음 라인의 validateObstacle 이 메소드를 호출하기 직전의 상태에서 멈추게 된다.

 


step into는 안으로 들어 가는데 어디로 들어가냐면 현재 브레이크가 걸린 라인의 내부의 로직으로 들어간다. 이 코드는 지금 sourcePiece.findPath라는 라인이 내부에 로직이 존재하는데 step into를 하면 이 메소드 내부로 들어가서

 


첫 번째 줄에 브레이크하게 된다. 그리고 step into에서 들어온 지점으로 빠져 나오는 step out이라는 기능도 존재한다.

 

 

하나하나씩 다시 살펴보면 다음 브레이크 포인트로 이동하는 Resume, 다음 라인으로 이동하는 step over, 해당하는 라인의 메소드 내부로 들어가는 step into, 빠져나오는 step out 이런 기능들이 있다.

 

 

Evaluate라는 것은 디버깅중에 자바코드를 실행할 수 있다. 그래서 실행할 수 있는 자바 코드는 이 메소드 내부에서 실행할 수 있는 자바 코드는 다 실행할 수 있다고 보면 된다. 예를 들어 인스턴스 필드 파라미터로 놓은 변수들을 활용해서 사용할 수도 있고, public static으로 열려 있는 메소드도 호출할 수 있다. 예를 들어서 디버깅을 하다가 어떤 값을 계산해 보고 싶어, 어떤 로직을 수행해 보고 싶어, stream 돌려서 sum해서 값을 확인해볼 수도 있고 다양하게 활용이 가능하다.


다만 주의해야할 점은 여기서 Evaluate에서 실행하는 코드들은 실제로 실행되는 자바 코드이다. 예를 들어서 어떤 자료구조가 있다고 가정하고 Evaluate를 통해 이 자료구조에 add하거나 remove 한다면 그 자료구조의 실제로 상태가 변한 것이다. 추가하거나 삭제되었기 때문에 테스트를 디버깅 한다고 생각한다면 변화시켰기 때문에 통과해야 하는 테스트가 깨질 수도 있고 반대로 깨져야 하는 테스트가 통과할 수도 있다. 이렇게 상태를 변화시킬 수 있기 때문에 에러가 있는 코드에 브레이크를 걸어 놓고 어떤 식으로 변화시켜서 통과 시킬까 그렇게 직접 해보면서 테스트해 볼 수 있다.

 

 

브레이킹 포인트를 만나면 기본적으로 멈춘다. 그런데 모든 브레이킹 포인트의 조건을 선택할 수도 있다. 그래서 브레이킹 포인트를 만나더라도 그 조건이 true일 때 만 브레이크 하고 false라면 브레이크 하지 않도할 수 있다. 예를 들어서 1부터 100까지 순회하는 반복문이 있다고 가정해 보자. 여기서 100개를 다 찍어 보고 싶진 않고 '90 이상의 숫자에만 브레이크 해', '10의 배수일 때만 브레이크 해' 이런 식으로 조건문을 설정할 수 있다.


인텔리제이에서 디버깅할때 뒤로가기나 취소 같은 기능은 없지만 아주 특정한 상황에서 유사하게 활용할 수 있는 기능이 있다.

 


Reset Frame이라고 하면은 jvm 에 한층 한층씩 층이 있을 것이다. 이 층이 popping되면서 계속 로직이 진행 될 텐데
특정한 시점으로 되돌려서 로직을 다시 수행할 수 있는 기능이 존재한다. 다만 이것을 명확한 뒤로 가기 라고 부를 순 없다. 왜냐면 이 라인에서 바로 윗 라인으로 올라가고 싶지만 같은 stack frame이기 때문에 리셋이 불가능할 수 있고, popping중인 프레임이기 때문에 아예 리셋이 안 될 수도 있다. 또 만약에 리셋을 시켜서 했더라도 static하거나 인스턴스 변수의 값이 이미 변경되었다면 이전 상태로 초기화 되지 않고 이미 변경 된 상태로 넘어간다. 그렇기 때문에 이것을 완전히 다시 하기 라고 보긴 어렵다. 플로우를 다시 확인 할 때, 로직을 다시 한번 거슬러 올라 가고 싶을 때 정도로 특수한 상황에서 활용할 수 있을 것이다. 그렇기 때문에 일반적으로 다시 디버그를 수행 하는 게 최선의 판단이다.


참고

https://www.youtube.com/watch?v=JSVvhwwOvAY&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC 

728x90
반응형

댓글