원격 디버깅이란?

  • 앱을 개발할 때에는 적어도 세 가지 환경을 사용한다.
    • 개발 환경(development environment, DEV): 앱을 배포할 환경과 유사한 환경이다. 개발자는 주로 로컬 시스템에서 개발을 진행하고 이 환경에서 새로운 기능과 수정 사항을 테스트한다.
    • 사용자 인수 테스트 환경(user acceptance test, UAT): 개발 환경에서 테스트를 마친 앱은 사용자 인수 테스트 환경에 설치된다. 사용자는 새로운 구현체와 수정된 코드를 시험하고, 실체 데이터가 있는 프로덕션 환경에 앱을 배포하기 전에 정상 작동하는지 확인한다.
    • 프로덕션 환경(production environment, PROD): 새로운 구현체가 예상대로 잘 작동되고 사용상 문제가 없다면 프로덕션 환경에 앱을 설치한다.
  • 똑같이 컴파일한 앱인데 환경이 달라지면 다르게 작동되는 경우가 종종 있다.
    • 원격 디버깅은 이와 같은 상황에서 소프트웨어 동작을 더 빨리 이해하는 데 큰 도움이 될 수 있다.
    • 하지만 어떤 경우에도 프로덕션 환경에서 원격 디버깅을 사용해서는 안된다.
  • 원격 디버깅을 하려면 앱을 실행할 때 에이전트라는 소프트웨어를 앱에 부착해야된다. 디버깅 에이전트를 부팅면 이런 현상이 나타날 수 있다.(그래서 프로덕션 환경에서 원격 디버깅을 하지 말라는 것이다)
    • 에이전트 때문에 앱 실행 속도가 느려질 수 있다. 속도가 느려지면 예기치 않은 성능 문제가 발생할 수 있다.
    • 에이전트가 디버거 도구와 통신하려면 네트워크를 통해야 하는데, 특정 포트를 오픈하는 과정에서 보안 취약 요소가 발생할 수 있다.
    • 앱의 어떤 부분을 다른 곳에서 동시 사용 중일 경우, 해당 코드를 디버깅하면 전체적인 기능에 간섭을 일으킬 수 있다.
    • 디버깅 하다가 앱이 무한정 차단돼서 프로세스를 재시작해야 할 때도 있다.

원격 환경에서 조사하기

  • 원격 디버깅할 앱은 커맨드 라인에서 java로 앱을 시작할 때 -agnetlib.jdwp 매개변수를 추가하여 디버거 에이전트를 연결시켜야 한다.
  • 이때 디버거 도구를 연결할 포트번호를 지정한다.
    • transport=dt_socket: 디버거 도구가 디버거 에이전트와 통신하는 방식을 지정한 것이다. dt_socket은 네트워크를 통해 TCP/IP 접속을 하겠다는 뜻이다. 에이전트와 디버거는 항상 이 방식으로 통신한다.
    • server=y: 앱 실행에 부착한 에이전트를 서버로 사용한다는 의미다. 에이전트는 디버거 도구가 자신에게 접속할 때까지 기다리고 이를 통해 앱 실행을 제어한다. server=n으로 설정하면 디버거 에이전트를 시작하지 않고 바로 접속할 수 있다.
    • suspend=n: 디버거 도구가 접속하길 기다리지 않고 앱을 시작한다는 것이다. suspend=y로 설정하면 디버거에 접속할 때까지 앱을 실행하지 않는다. 서버 부팅 프로세스에 문제가 있어 조사를 한다면 디버거 도구가 접속한 이후 앱을 시작해야 할 테니 suspend=y로 설정해야 할 것이다.
    • address=*:5005: 디버거 도구가 에이전트와 5005 포트로 통신하도록 선언한다. 시스템에서 이미 사용중인 포트는 지정하면 안 되며, 디버거 도구와 에이전트 강 통신에 문제가 없도록 네트워크 작업이 필요하다.
  • IntelliJ 환경에서 원격 앱에 디버거로 접속하는 방법
  • 사용하는 코드의 버전을 잘 살펴야 한다.
    • 로컬에서 디버깅을 할 때는 IDE가 앱을 컴파일한 후 새로 컴파일된 코드에 디버거를 부착한다.
    • 그러나 원격 앱에 접속하는 경우, 내가 갖고 있는 소스 코드와 디버거를 접속시킨 원격 앱의 컴파일된 코드가 일치하지 않을 수도 있다.
    • 버전이 다른 소스 코드를 사용하면 디버거가 이상하고 혼란스럽게 작동할 수 있다.