Skip to content

debug

Debugging in Visual Studio Code

TL;DR

기본 구조

launch.json은 다음과 같은 JSON 구조로 작성됩니다.

{
  "version": "0.2.0",
  "configurations": []
}
  • version: launch.json 파일의 버전을 지정합니다. 현재 버전은 0.2.0입니다.
  • configurations: 디버깅 설정의 배열입니다. 여러 개의 설정을 추가할 수 있으며, 각 설정은 하나의 디버그 구성입니다.
version
  • launch.json 파일에서 version 필드는 디버깅 구성 파일의 스키마(schema) 버전을 나타냅니다.
  • 이는 Visual Studio Code에서 디버깅 구성을 정의할 때 사용하는 형식이 어떤 버전에 따라 작성되었는지를 지정합니다.

주요 특징

  1. 스키마 호환성 유지

    • Visual Studio Code는 시간이 지나면서 디버깅 설정 기능이 확장되고 변경될 수 있습니다.
    • version은 현재 사용 중인 launch.json 파일이 어떤 스키마 규격을 따르는지를 명시하여, VS Code가 올바르게 해당 구성을 해석할 수 있도록 돕습니다.
  2. 현재 사용 가능한 버전

    • 현재 지원되는 최신 버전은 0.2.0입니다. 이는 디버깅 구성 스키마의 안정된 버전으로, 대부분의 프로젝트에서 사용됩니다.
  3. 기본값

    • 새로 생성된 launch.json 파일은 기본적으로 "version": "0.2.0"으로 설정됩니다.
    • 현재는 이 값이 고정되어 있으며, 다른 값으로 변경하지 않습니다.
  4. 미래 가능성

    • 만약 새로운 디버깅 기능이 추가되거나 기존 기능이 변경되어 스키마가 업데이트되면, VS Code는 새로운 버전을 도입할 수 있습니다. 그럴 경우, 새로운 버전과 구 버전 간의 호환성을 유지하기 위해 version 값이 중요하게 작용할 것입니다.

실무적인 의미

  • 현재 버전 0.2.0은 사실상 모든 사용자에게 동일한 디버깅 기능을 제공하므로, version 값 자체를 신경 써서 변경하거나 관리할 필요는 없습니다.

주요 필드

  1. type

    • 디버거의 종류를 지정합니다. 예를 들어 python, node, cppdbg 등이 있습니다.
    • 예시: "type": "python"
  2. request

    • 실행 요청의 종류를 지정합니다.
    • launch: 프로그램을 시작하고 디버깅할 때 사용됩니다.
    • attach: 이미 실행 중인 프로세스에 연결하여 디버깅할 때 사용됩니다.
    • 예시: "request": "launch"
  3. name

    • 이 구성의 이름입니다. 디버깅 구성 메뉴에서 이 이름이 표시됩니다.
    • 예시: "name": "Python: Current File"
  4. program

    • 실행할 프로그램의 경로입니다. 주로 Python 파일이나 Node.js 프로그램 파일을 지정합니다.
    • 예시: "program": "${workspaceFolder}/app.py"
  5. args

    • 프로그램에 전달할 명령줄 인수입니다. 배열로 여러 인수를 제공할 수 있습니다.
    • 예시: "args": ["arg1", "arg2"]
  6. cwd

    • 프로그램을 실행할 때 사용할 작업 디렉터리입니다.
    • 예시: "cwd": "${workspaceFolder}"
  7. env

    • 프로그램 실행 시 설정할 환경 변수를 정의합니다. 객체로 지정되며, 각 키는 환경 변수 이름이고 값은 해당 값입니다.
    • 예시:
    "env": {
      "ENV_VAR1": "value1",
      "ENV_VAR2": "value2"
    }
    
  8. envFile

    • 환경 변수를 로드할 .env 파일을 지정합니다.
    • 예시: "envFile": "${workspaceFolder}/.env"
  9. console

    • 디버그 콘솔의 출력을 어디에 표시할지 지정합니다.
    • integratedTerminal: VS Code 통합 터미널에서 실행
    • externalTerminal: 외부 터미널에서 실행
    • 예시: "console": "integratedTerminal"
  10. stopOnEntry

    • 프로그램이 시작할 때 자동으로 일시 정지할지를 지정합니다.
    • true: 첫 번째 명령에서 프로그램이 일시 정지합니다.
    • false: 자동으로 시작합니다.
    • 예시: "stopOnEntry": false
  11. justMyCode

    • Python 코드에서 사용자 코드만 디버깅할지 여부를 지정합니다. 외부 라이브러리의 코드에서 중단점을 무시하려면 true로 설정합니다.
    • 예시: "justMyCode": true
  12. sourceMaps

    • 소스 맵을 사용할지 여부를 설정합니다. 주로 TypeScript, JavaScript에서 사용되며, 트랜스파일된 코드와 원본 소스 코드를 매핑합니다.
    • 예시: "sourceMaps": true
  13. preLaunchTask

    • 프로그램이 시작되기 전에 실행할 작업을 정의합니다. 이는 주로 tasks.json에서 정의된 작업입니다.
    • 예시: "preLaunchTask": "npm: build"
  14. postDebugTask

    • 디버깅이 끝난 후 실행할 작업을 지정합니다.
    • 예시: "postDebugTask": "cleanup"
  15. attach (request가 attach일 때)

    • 실행 중인 프로세스에 연결할 때 사용합니다. 프로세스 ID 또는 원격 디버깅 포트 등을 지정할 수 있습니다.
    • 예시:
    "processId": "${command:PickProcess}",
    "port": 9229
    
  16. port

    • 원격 디버깅할 때 연결할 포트를 지정합니다.
    • 예시: "port": 9229
  17. outFiles

    • 소스 맵이 존재하는 파일 또는 파일 패턴을 지정합니다. 주로 Node.js 또는 TypeScript 디버깅에 사용됩니다.
    • 예시: "outFiles": ["${workspaceFolder}/dist/**/*.js"]
  18. skipFiles

    • 디버깅 중 건너뛸 파일 패턴을 지정합니다. 이는 주로 라이브러리 코드나 관심 없는 파일을 건너뛰기 위해 사용됩니다.
    • 예시:
    "skipFiles": [
      "<node_internals>/**",
      "node_modules/**"
    ]
    

필수 속성

속성 설명
type 디버깅 구성을 위한 디버거 유형. 설치된 디버깅 확장 프로그램에 따라 달라짐.
예: node(Node.js), php, go.
request 디버깅 요청 유형. launch(새 프로그램 실행) 또는 attach(이미 실행 중인 프로세스에 연결) 지원.
name 디버깅 구성 드롭다운 메뉴에 표시될 사용자 친화적인 이름.

모든 디버깅 구성에서 사용 가능한 선택적 속성

속성 설명
presentation order, group, hidden 속성을 사용해 디버깅 구성 드롭다운 및 빠른 선택 메뉴에서 정렬, 그룹화, 숨김 설정.
preLaunchTask 디버깅 세션 시작 전에 실행할 작업을 설정.
예: tasks.json의 작업 레이블 또는 ${defaultBuildTask}.
postDebugTask 디버깅 세션 종료 후 실행할 작업을 설정.
예: tasks.json의 작업 이름.
internalConsoleOptions 디버깅 세션 중 Debug Console 패널의 가시성을 제어.
debugServer 디버그 확장 프로그램 개발자 전용 속성. 특정 포트로 디버거 어댑터에 연결하도록 설정.
serverReadyAction 디버깅 중 프로그램이 콘솔이나 터미널에 특정 메시지를 출력하면 웹 브라우저에서 URL을 자동으로 열도록 설정.

다수 디버거에서 지원하는 속성

속성 설명
program 디버거 실행 시 실행할 파일이나 스크립트 경로.
args 디버깅 대상 프로그램에 전달할 인자 목록.
예: ["--port", "8080"].
env 환경 변수 설정. 변수 값을 null로 설정하면 해당 변수를 "제거".
envFile 환경 변수 설정이 포함된 .env 파일 경로.
cwd 현재 작업 디렉토리. 디펜던시 및 파일 검색 경로에 영향을 미침.
port 실행 중인 프로세스에 연결할 때 사용할 디버깅 포트 번호.
stopOnEntry 프로그램 시작 시 즉시 멈춤. 초기 상태에서 디버깅을 시작해야 할 때 유용.
console 사용할 콘솔 유형.
예: internalConsole(내장 콘솔), integratedTerminal(통합 터미널), externalTerminal(외부 터미널).

언어별 주요 필드 예시

Python 예시
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Current File",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal"
    }
  ]
}
Node.js 예시
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "program": "${workspaceFolder}/app.js",
      "console": "integratedTerminal"
    }
  ]
}
Go 예시
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "REST",
      "type": "go",
      "request": "launch",
      "mode": "auto",
      "program": "cmd/server/main.go",
      "cwd": "${workspaceFolder}"
    },
    {
      "name": "gRPC",
      "type": "go",
      "request": "launch",
      "mode": "auto",
      "program": "cmd/grpc/main.go",
      "cwd": "${workspaceFolder}"
    }
  ]
}
C++ 예시
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C++ Launch",
      "type": "cppdbg",
      "request": "launch",
      "program": "${workspaceFolder}/a.out",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": true,
      "MIMode": "gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ]
    }
  ]
}

Attach vs Launch

  • launchattach는 VS Code에서 디버깅할 때 사용하는 두 가지 주요 모드로, 디버거가 프로그램과 어떻게 상호작용하는지를 결정

1. Launch 모드

  • VS Code가 프로그램을 직접 실행하고 디버그
  • 디버거가 프로세스의 시작 단계부터 관리
  • 개발자가 앱 실행부터 디버깅까지 모두 VS Code 내에서 관리하고자 할 때 유용
사용 사례
  • 서버, 데스크톱 앱, CLI 도구를 개발할 때, VS Code에서 프로그램을 실행하며 디버깅하고 싶을 때.
  • 예를 들어:
    • Go 프로그램, Python 스크립트, Node.js 서버를 VS Code에서 직접 실행.
    • 브라우저를 열 필요 없이, 브라우저 없는 환경에서 동작하는 앱.
구성 방식
  • launch.json 파일에 디버깅 대상의 실행 경로와 환경 설정을 작성
{
  "type": "node",
  "request": "launch",
  "name": "Launch Program",
  "program": "${workspaceFolder}/app.js" // 실행 파일 경로
}
동작 방식
  1. VS Code가 앱 실행 명령을 내림
  2. 앱은 디버그 모드로 시작됨
  3. 디버거가 처음부터 앱의 모든 동작을 추적

2. Attach 모드

  • 이미 실행 중인 앱이나 외부에서 실행된 프로세스에 VS Code 디버거를 연결
  • 디버거는 프로그램이 실행 중일 때 중단점 설정, 변수 추적 등 디버깅 작업만 수행
  • 프로세스를 실행하지 않음
사용 사례
  • 브라우저나 다른 환경에서 이미 실행 중인 앱 디버깅.
  • 서버, 컨테이너, 또는 리모트 머신에서 실행 중인 앱에 디버거를 연결하고 싶을 때.
  • 예를 들어:
    • 브라우저에서 실행 중인 웹 앱의 JavaScript를 디버깅.
    • Docker 컨테이너에서 실행 중인 Node.js 서버를 디버깅.
구성 방식

launch.json 파일에 실행 중인 프로세스의 디버깅 포트와 연결 정보를 작성

{
  "type": "node",
  "request": "attach",
  "name": "Attach to Process",
  "port": 9229, // 디버깅 포트
  "address": "localhost"
}
동작 방식
  1. 앱은 이미 실행 중이어야 함.
  2. 디버거가 지정된 포트나 프로세스에 연결.
  3. 디버깅 작업(중단점 설정, 변수 추적)을 진행.

3. 차이점 요약

특징 Launch 모드 Attach 모드
프로세스 실행 VS Code가 직접 프로그램을 실행. 이미 실행 중인 프로그램에 디버거를 연결.
사용 대상 새로 실행할 앱을 디버깅. 외부에서 실행 중인 앱이나 리모트 프로세스 디버깅.
설정 요구사항 실행 파일 경로, 환경 변수 등. 디버깅 포트, 프로세스 ID 또는 네트워크 주소.
예시 Node.js 앱, Python 스크립트, Go 서버 디버깅. 브라우저 탭, Docker 컨테이너, 원격 서버 디버깅.

4. 실제 예제

Launch 모드: Node.js 앱 실행 및 디버깅
  • VS Code에서 Node.js 앱 실행 후 디버깅.
{
  "type": "node",
  "request": "launch",
  "name": "Launch Node.js App",
  "program": "${workspaceFolder}/server.js"
}
Attach 모드: Docker 컨테이너에서 실행 중인 Node.js 서버 디버깅
  • Docker 컨테이너 내에서 실행 중인 Node.js 서버에 연결.
{
  "type": "node",
  "request": "attach",
  "name": "Attach to Node.js in Docker",
  "port": 9229,
  "address": "localhost",
  "localRoot": "${workspaceFolder}",
  "remoteRoot": "/usr/src/app" // 컨테이너 내 경로
}

5. 브라우저 개발 vs 서버 개발에서의 차이

  • 브라우저 개발자:
    • 이미 브라우저에서 실행 중인 앱에 DevTools처럼 연결하는 방식(attach)이 익숙.
    • 브라우저의 디버깅 포트(예: 9222)로 연결.
  • 서버/데스크톱 개발자:
    • 프로그램을 편집기에서 실행(launch)하며 디버거와 함께 시작하는 워크플로를 선호.