Skip to content

필사 모드: IDE별 디버깅 완전정리: VS Code · IntelliJ IDEA · PyCharm 브레이크포인트, 실행 구성, 프로파일링

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

> 이 글은 **디버깅 실전 시리즈 5편** 중 3편이다.

>

> 1. [언어별 디버깅 가이드](/blog/devops/2026-03-07-devops-debugging-by-language-python-javascript-go-java)

> 2. [프레임워크별 디버깅 실전](/blog/devops/2026-03-07-devops-debugging-by-framework-spring-django-fastapi-react-nextjs)

> 3. **[IDE별 디버깅 완전정리](/blog/devops/2026-03-07-devops-debugging-by-ide-vscode-intellij-pycharm)** ← 현재 글

> 4. [언어×프레임워크 장애 사례집](/blog/devops/2026-03-07-devops-debugging-casebook-language-framework-combos)

> 5. [원격 디버깅 실전 가이드](/blog/devops/2026-03-07-devops-remote-debugging-guide-ssh-tunnel-vscode-intellij-pycharm)

IDE 디버깅은 "설정"이 절반이다

좋은 IDE를 쓰는데도 디버깅이 느린 이유는 대부분 같다.

- 실행 구성이 매번 달라 재현이 흔들림

- 브레이크포인트를 무작정 많이 찍음

- 프로파일링을 장애 후반에야 시작함

아래 설정을 팀 표준으로 맞추면 디버깅 속도가 눈에 띄게 빨라진다. IDE마다 개념은 같지만 설정 방식이 다르므로, 각 IDE별 구체적인 방법을 정리했다.

IDE별 디버깅 기능 비교

| 기능 | VS Code | IntelliJ IDEA | PyCharm |

| ----------------------------- | ----------------------- | ------------------------------ | -------------------------- |

| **실행 구성 파일** | .vscode/launch.json | .run/\*.xml / .idea | .run/\*.xml / .idea |

| **조건부 브레이크포인트** | 우클릭 → Edit Condition | 우클릭 → Condition | 우클릭 → Condition |

| **Logpoint (중단 없는 로그)** | 우클릭 → Add Logpoint | Evaluate and Log (Shift+Click) | Evaluate and Log |

| **Exception Breakpoint** | Run → Add Exception BP | Run → View Breakpoints → + | Run → View Breakpoints → + |

| **Watch Expression** | Debug 패널 → Watch | Variables 패널 + Watches | Variables 패널 + Watches |

| **Evaluate Expression** | Debug Console 입력 | Alt+F8 (디버그 중) | Alt+F8 (디버그 중) |

| **Hot Reload** | 일부 확장 지원 | HotSwap (JVM) 내장 | Django/Flask 자동 리로드 |

| **원격 디버깅** | launch.json attach 설정 | Remote Debug Configuration | Remote Debug Configuration |

| **내장 프로파일러** | 확장 의존 | Ultimate 내장 (CPU/Memory) | Professional 내장 |

| **멀티프로세스 디버깅** | compound launch | Compound Run Config | Compound Run Config |

IDE별 추천 확장/플러그인

| 용도 | VS Code | IntelliJ IDEA | PyCharm |

| ------------------- | ---------------------------- | --------------------- | --------------------- |

| **에러 하이라이트** | Error Lens | 내장 | 내장 |

| **Git 변경 추적** | GitLens | 내장 Git Blame | 내장 Git Blame |

| **REST API 테스트** | REST Client / Thunder Client | HTTP Client (내장) | HTTP Client (내장) |

| **Docker 디버깅** | Docker Extension | Docker Plugin | Docker Plugin |

| **데이터베이스** | SQLTools | Database Tools (내장) | Database Tools (내장) |

| **테스트 실행** | Test Explorer UI | 내장 Test Runner | 내장 pytest Runner |

| **AI 어시스턴트** | GitHub Copilot / Continue | AI Assistant (내장) | AI Assistant (내장) |

| **코드 품질** | SonarLint | SonarLint Plugin | SonarLint Plugin |

| **원격 개발** | Remote - SSH / WSL | Gateway / Remote Dev | Gateway / Remote Dev |

디버깅 키보드 단축키 비교

| 작업 | VS Code (Mac) | VS Code (Win/Linux) | IntelliJ / PyCharm (Mac) | IntelliJ / PyCharm (Win/Linux) |

| ----------------------- | ------------- | ------------------- | ------------------------ | ------------------------------ |

| **디버그 시작** | F5 | F5 | Ctrl+D | Shift+F9 |

| **실행 (디버그 없이)** | Ctrl+F5 | Ctrl+F5 | Ctrl+R | Shift+F10 |

| **Step Over** | F10 | F10 | F8 | F8 |

| **Step Into** | F11 | F11 | F7 | F7 |

| **Step Out** | Shift+F11 | Shift+F11 | Shift+F8 | Shift+F8 |

| **Continue (재개)** | F5 | F5 | Cmd+Opt+R | F9 |

| **Toggle Breakpoint** | F9 | F9 | Cmd+F8 | Ctrl+F8 |

| **Evaluate Expression** | Debug Console | Debug Console | Alt+F8 | Alt+F8 |

| **Stop** | Shift+F5 | Shift+F5 | Cmd+F2 | Ctrl+F2 |

| **Run to Cursor** | - | - | Opt+F9 | Alt+F9 |

1) VS Code

실행 구성 (launch.json) 상세 예시

{

"version": "0.2.0",

"configurations": [

{

// Python FastAPI 디버깅

"name": "Python: FastAPI",

"type": "debugpy",

"request": "launch",

"module": "uvicorn",

"args": ["app.main:app", "--reload", "--port", "8000"],

"console": "integratedTerminal",

"envFile": "${workspaceFolder}/.env",

"justMyCode": true // 라이브러리 코드 스킵 (false로 바꾸면 진입 가능)

},

{

// Node.js Express/NestJS 디버깅

"name": "Node: API Server",

"type": "node",

"request": "launch",

"program": "${workspaceFolder}/dist/index.js",

"preLaunchTask": "npm: build", // 빌드 후 실행

"runtimeArgs": ["--inspect-brk"],

"sourceMaps": true,

"outFiles": ["${workspaceFolder}/dist/**/*.js"],

"envFile": "${workspaceFolder}/.env",

"console": "integratedTerminal"

},

{

// Node.js 실행 중인 프로세스에 연결

"name": "Attach to Node",

"type": "node",

"request": "attach",

"port": 9229,

"restart": true, // 프로세스 재시작 시 자동 재연결

"sourceMaps": true

},

{

// Go Delve 디버깅

"name": "Go: Launch API",

"type": "go",

"request": "launch",

"mode": "auto",

"program": "${workspaceFolder}/cmd/api",

"env": {

"GO_ENV": "development"

},

"args": ["-config", "config.dev.yaml"]

},

{

// Next.js 서버 사이드 디버깅

"name": "Next.js: Server",

"type": "node",

"request": "launch",

"runtimeExecutable": "npx",

"runtimeArgs": ["next", "dev"],

"sourceMaps": true,

"cwd": "${workspaceFolder}",

"console": "integratedTerminal"

},

{

// pytest 디버깅 (특정 테스트)

"name": "Python: pytest Current File",

"type": "debugpy",

"request": "launch",

"module": "pytest",

"args": ["${file}", "-v", "--no-header"],

"console": "integratedTerminal",

"justMyCode": false // 테스트 시 라이브러리 내부도 확인

}

],

"compounds": [

{

// 프론트+백엔드 동시 디버깅

"name": "Full Stack",

"configurations": ["Python: FastAPI", "Next.js: Server"]

}

]

}

브레이크포인트 활용법

조건부 브레이크포인트 설정 방법:

1. 라인 번호 좌측 클릭으로 브레이크포인트 설정

2. 브레이크포인트 우클릭 → "Edit Breakpoint..."

3. 조건 유형 선택:

- Expression: user.id === "U-9999" (조건이 true일 때만 중단)

- Hit Count: 100 (100번째 호출에서 중단)

- Log Message: "userId={user.id} total={total}" (중단 없이 로그만)

Exception Breakpoint 설정 방법:

1. Run → Add Configuration → 또는 Debug 패널 → BREAKPOINTS 섹션

2. "Add Function Breakpoint" 또는 언어별 Exception BP 추가

- Python: "Raised Exceptions" / "Uncaught Exceptions" 체크

- Node.js: "All Exceptions" / "Uncaught Exceptions" 체크

멀티프로세스 디버깅

// tasks.json — 디버그 전에 실행할 빌드 태스크

{

"version": "2.0.0",

"tasks": [

{

"label": "Start Docker DB",

"type": "shell",

"command": "docker compose up -d postgres redis",

"problemMatcher": []

}

]

}

launch.json의 `compounds` 설정으로 여러 프로세스를 동시에 디버깅할 수 있다. 프론트엔드와 백엔드를 동시에 실행하고, 각각에 독립적인 브레이크포인트를 설정할 수 있다.

프로파일링

- **JS/TS**: DevTools Performance/Memory (F12 → Performance 탭)

- **Python**: 터미널에서 py-spy 연동, 또는 debugpy의 profiling 옵션

- **추천 확장**: Error Lens (인라인 에러 표시), GitLens (변경 이력 추적)

2) IntelliJ IDEA

Run/Debug Configuration 상세 예시

필수 표준화 항목:

1. JVM 옵션: -Xmx512m -XX:+HeapDumpOnOutOfMemoryError

2. 환경변수 파일: .env 또는 EnvFile 플러그인 연결

3. 활성 프로파일: -Dspring.profiles.active=dev

4. Working directory: $MODULE_DIR$ (모듈 루트 고정)

5. Before launch: Build 태스크 자동 실행 확인

<!-- .run/SpringBootApp.run.xml — Git에 포함하여 팀 공유 -->

value="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/" />

원격 디버그는 "Attach to process"보다 **고정 포트 설정**을 권장한다.

Remote Debug Configuration 설정:

1. Run → Edit Configurations → + → Remote JVM Debug

2. Host: localhost, Port: 5005

3. Command line arguments 복사하여 서버 실행 시 적용

4. "Auto restart" 체크하면 서버 재시작 시 자동 재연결

브레이크포인트 고급 기능

IntelliJ 브레이크포인트 고급 옵션 (우클릭 → More):

1. Condition: orderId.equals("ORD-1234")

→ 조건이 true일 때만 중단

2. Log message to console: "Processing order: " + orderId

→ 중단 없이 디버그 콘솔에 출력 (Logpoint)

3. Evaluate and log: order.getItems().size()

→ 표현식을 평가하고 결과를 로그로 출력

4. Remove once hit: 한 번 걸리면 자동 제거

→ 초기화 코드처럼 한 번만 확인할 때 유용

5. Disable until hitting another breakpoint

→ 특정 조건에 도달한 후부터 활성화 (체이닝)

6. Instance filter: 특정 객체 인스턴스에서만 중단

→ 멀티스레드 환경에서 특정 요청만 추적

Exception Breakpoint 설정:

1. Run → View Breakpoints (Cmd+Shift+F8 / Ctrl+Shift+F8)

2. + → Java Exception Breakpoints

3. NullPointerException, IllegalStateException 등 선택

4. "Caught exception" / "Uncaught exception" 체크

5. Class filters로 내 패키지만 필터링: com.example.*

멀티스레드 디버깅

멀티스레드 디버깅 설정:

1. 브레이크포인트 우클릭 → Suspend policy 설정

- All: 모든 스레드 중단 (기본값)

- Thread: 해당 스레드만 중단, 나머지는 계속 실행

2. Threads 패널에서:

- 각 스레드의 스택 트레이스 확인

- 스레드 간 전환하여 변수 상태 비교

- "Resume thread" 로 특정 스레드만 재개

3. 데드락 감지:

- Debug 패널 → 우클릭 → "Detect Deadlock"

- 자동으로 데드락 관련 스레드와 Lock 정보 표시

프로파일링

IntelliJ 내장 프로파일러 (Ultimate):

1. Run → Profile (CPU/Memory 선택)

2. 또는 실행 아이콘 옆 드롭다운 → "Profile with IntelliJ Profiler"

3. 결과:

- Flame Graph: 핫스팟 시각화

- Call Tree: 호출 관계별 시간 분포

- Method List: 함수별 총 시간/자체 시간

- Timeline: 시간축 기반 스레드별 활동

JFR 파일 분석:

1. .jfr 파일을 IntelliJ에서 직접 열기

2. Flame Graph / Call Tree로 상위 10개 함수부터 분석

3. Allocation 탭에서 메모리 할당 핫스팟 확인

3) PyCharm

실행 구성 상세 예시

PyCharm Run Configuration 표준화:

1. Django 서버:

- Type: Django Server

- Host: 0.0.0.0, Port: 8000

- Environment variables: .env 파일 연결

- Additional options: --settings=config.settings.dev

2. FastAPI (uvicorn):

- Type: Python

- Module name: uvicorn

- Parameters: app.main:app --reload --port 8000

- Working directory: $PROJECT_DIR$

- EnvFile 플러그인으로 .env 로드

3. pytest (단위 테스트):

- Type: pytest

- Target: tests/unit/

- Additional arguments: -v --tb=short

- Environment variables: TESTING=true

4. pytest (통합 테스트):

- Type: pytest

- Target: tests/integration/

- Additional arguments: -v --tb=long -x

- Environment variables: DB_HOST=localhost

conftest.py에서 테스트용 디버그 설정

@pytest.fixture(autouse=True)

def debug_sql_queries(settings):

"""테스트 중 SQL 쿼리 로그 출력"""

settings.DEBUG = True

settings.LOGGING = {

'version': 1,

'handlers': {'console': {'class': 'logging.StreamHandler'}},

'loggers': {

'django.db.backends': {

'level': 'DEBUG',

'handlers': ['console'],

}

}

}

브레이크포인트 고급 활용

PyCharm 브레이크포인트 옵션:

1. Condition + Hit Count 조합:

- Condition: len(items) > 100

- 활성화 조건: Hit count >= 5

→ 아이템이 100개 초과인 요청이 5번째 이상일 때만 중단

2. Django/FastAPI 엔드포인트 진입점에 우선 배치:

- View 함수 첫 줄

- serializer.is_valid() 직후

- ORM 쿼리 실행 직전

3. Evaluate and Log:

- 브레이크포인트 우클릭 → "Evaluate and log"

- 예시: f"user={request.user}, method={request.method}"

- 중단 없이 디버그 콘솔에 출력

조건부 브레이크포인트 실전 예시

def process_batch(items):

for i, item in enumerate(items):

PyCharm에서 이 라인에 조건부 BP 설정:

Condition: item.status == "ERROR" and i > 50

→ 50번째 이후의 ERROR 아이템에서만 중단

result = transform(item)

save(result)

멀티스레드/멀티프로세스 디버깅

PyCharm 멀티스레드 디버깅:

1. Thread 패널에서 활성 스레드 목록 확인

2. 스레드 선택하여 개별 스택 트레이스 확인

3. 브레이크포인트의 Suspend policy:

- All Threads: 모든 스레드 중단

- Thread: 해당 스레드만 중단

Django + Celery 동시 디버깅:

1. Compound Run Configuration 생성

2. 구성 1: Django Server (runserver)

3. 구성 2: Python → celery -A config worker -l debug

4. 양쪽에 독립적 브레이크포인트 설정 가능

gunicorn 멀티워커 디버깅 — 단일 워커로 제한

gunicorn.conf.py

workers = 1 # 디버깅 시 워커 1개로 제한

timeout = 300 # 브레이크포인트에서 멈춰도 타임아웃 안 되게

accesslog = '-' # stdout으로 로그 출력

프로파일링

PyCharm 내장 프로파일러 (Professional):

1. Run → Profile 'configuration name'

2. 또는 실행 아이콘 옆 → "Profile"

3. 결과 분석:

- Call Graph: 함수 호출 관계와 시간 시각화

- Statistics: 함수별 호출 횟수/총 시간/자체 시간 테이블

- 느린 함수 클릭 → 소스코드로 바로 이동

Line Profiler 연동:

1. pip install line-profiler

2. @profile 데코레이터를 느린 함수에 적용

3. kernprof -l -v script.py 실행

4. 결과: 함수 내 각 라인별 실행 시간/호출 횟수

cProfile 통합:

1. Run → Profile → cProfile 선택

2. 결과를 .prof 파일로 저장

3. snakeviz로 시각화: snakeviz output.prof

memory_profiler로 메모리 사용량 라인별 분석

from memory_profiler import profile

@profile

def load_dataset():

data = [] # 시작: 50 MiB

for chunk in read_chunks():

processed = transform(chunk) # 여기서 +200 MiB → 누수 의심

data.append(processed)

return data # 최종: 800 MiB

IDE 공통 베스트 프랙티스

1) 디버그 프로필을 코드처럼 관리

- `.vscode/launch.json`, `.run/`, `.idea` 일부 템플릿을 저장소에 포함

- 팀원 온보딩 시 "실행 버튼 한 번"으로 재현 가능하게

- `.gitignore`에서 개인 설정은 제외하되, 공통 실행 구성은 커밋

.gitignore 예시

IntelliJ — 개인 설정 제외, 공통 실행 구성은 포함

.idea/*

!.idea/runConfigurations/

!.idea/codeStyles/

VS Code — launch.json은 포함

.vscode/*

!.vscode/launch.json

!.vscode/tasks.json

!.vscode/extensions.json

2) 브레이크포인트 계층화

- **Level 1 (진입/경계)**: Controller/View 진입, 외부 API 호출 직전/직후. 항상 먼저 설정한다.

- **Level 2 (분기 조건)**: if/switch 분기, 유효성 검사. 원인이 좁혀지면 설정한다.

- **Level 3 (내부 루프)**: 반복문 내부. 반드시 조건부로만 설정한다.

3) 프로파일링을 조기 시작

- "느리다" 체감하면 바로 60초 샘플링. 감으로 최적화하면 잘못된 곳을 고치게 된다.

- flamegraph 상위 3개 핫스팟 함수부터 집중. 나머지는 효과가 미미하다.

- 최적화 전/후 프로파일을 비교하여 개선 효과를 수치로 검증한다.

4) 재현 스크립트 자동화

- Makefile/npm script/pytest marker로 고정

- 실행 인자 누락으로 인한 "내 로컬만 됨" 방지

- docker compose로 DB/캐시 등 의존 서비스 자동 실행 포함

Makefile 예시

.PHONY: debug test profile

debug-api:

docker compose up -d postgres redis

python -m debugpy --listen 5678 --wait-for-client -m uvicorn app.main:app --reload

debug-test:

pytest -x --pdb -v tests/

profile-api:

py-spy record -o profile.svg --pid $$(pgrep -f uvicorn)

장애 대응용 종합 체크리스트

디버그 환경 준비

- [ ] 실행 구성(launch.json / Run Configuration)이 팀 표준에 맞게 설정되어 있는가?

- [ ] 환경변수 파일(.env)이 올바르게 연결되어 있는가?

- [ ] Source map / 디버그 심볼이 활성화되어 있는가?

- [ ] 필요한 확장/플러그인이 설치되어 있는가?

브레이크포인트 전략

- [ ] Exception breakpoint가 활성화되어 있는가? (NPE, TypeError 등)

- [ ] 진입점(Level 1)에 브레이크포인트를 먼저 설정했는가?

- [ ] 루프 내 브레이크포인트에 조건을 설정했는가?

- [ ] Logpoint를 활용하여 서비스 중단 없이 값을 확인했는가?

재현 및 관측

- [ ] 같은 입력으로 재현되는가?

- [ ] Request ID로 전체 경로 추적되는가?

- [ ] Watch Expression에 핵심 변수를 등록했는가?

- [ ] Evaluate Expression으로 가설을 즉시 검증했는가?

프로파일링

- [ ] CPU 프로파일을 캡처했는가?

- [ ] 메모리 프로파일(heap dump/snapshot)을 확인했는가?

- [ ] flamegraph에서 상위 핫스팟을 식별했는가?

- [ ] 최적화 전/후 수치 비교를 했는가?

해결 후 후속

- [ ] 근본 원인(root cause)을 식별하고 문서화했는가?

- [ ] 회귀 테스트를 작성했는가?

- [ ] 디버그 실행 구성을 업데이트하여 저장소에 커밋했는가?

- [ ] 팀에 원인과 재발 방지 방법을 공유했는가?

IDE 디버깅 트러블슈팅 FAQ

IDE에서 디버깅할 때 자주 마주치는 문제와 해결 방법을 정리했다.

| 증상 | 원인 | 해결 |

| -------------------------------------- | ------------------------------------ | ---------------------------------------------- |

| 브레이크포인트가 회색(unverified) | 소스맵 경로 불일치 또는 빌드 안 됨 | `outFiles`/소스맵 경로 확인, 재빌드 후 재시작 |

| 브레이크포인트 히트가 안 됨 | 다른 프로세스/포트에 연결됨 | `attach` 설정의 port/pid 확인, `lsof -i :9229` |

| 변수값이 `undefined`/`<optimized out>` | 컴파일러 최적화, minification | Go: `-gcflags="all=-N -l"`, JS: 소스맵 활성화 |

| "Cannot connect to runtime" | 프로세스가 디버그 모드로 안 떴음 | `--inspect`/`-agentlib:jdwp` 옵션 확인 |

| Watch에서 "Expression not available" | 스코프 밖이거나 인라인 최적화 | 해당 스코프까지 step-into 후 재시도 |

| Hot Reload 후 브레이크포인트 안 걸림 | 재로드 후 매핑이 깨짐 | 디버거 재시작, 또는 브레이크포인트 재설정 |

| Docker 컨테이너 디버깅 연결 실패 | 포트 매핑 누락 또는 바인드 주소 문제 | `-p 5005:5005` 확인, `0.0.0.0` 바인딩 확인 |

원격 디버깅 퀵스타트 — IDE별 비교

원격 서버에 디버거를 붙이는 최소 설정을 IDE별로 비교한다. 상세 가이드는 [원격 디버깅 실전 가이드](/blog/devops/2026-03-07-devops-remote-debugging-guide-ssh-tunnel-vscode-intellij-pycharm)를 참고한다.

| 단계 | VS Code | IntelliJ IDEA | PyCharm |

| ---------------- | -------------------------------------------- | -------------------------------------------- | ----------------------------------------------- |

| **1. SSH 터널** | `ssh -N -L 5005:127.0.0.1:5005 user@server` | 동일 | 동일 |

| **2. IDE 설정** | launch.json `attach` 타입 추가 | Run > Edit Configurations > Remote JVM Debug | Run > Edit Configurations > Python Remote Debug |

| **3. 경로 매핑** | `localRoot`/`remoteRoot` 또는 `pathMappings` | 자동 (같은 프로젝트) 또는 module classpath | Path mappings 설정 |

| **4. Attach** | F5 (해당 설정 선택) | Debug 버튼 | Debug 버튼 |

| **비용** | 무료 | Ultimate 라이선스 | Professional 라이선스 |

결론

IDE는 편집기가 아니라 **문제 탐지 장비**다.

실행 구성/브레이크포인트/프로파일링을 표준화하면, 개인 역량이 아니라 팀 시스템으로 디버깅 속도를 끌어올릴 수 있다.

**빠른 디버깅은 천재성이 아니라, 잘 설계된 IDE 습관에서 나온다.**

팀원 누구나 "실행 버튼 한 번"으로 문제를 재현하고, 브레이크포인트 하나로 원인을 좁히며, 프로파일링 결과로 근거를 남길 수 있어야 한다. 그것이 IDE 디버깅의 궁극적인 목표다.

> 실전 장애 사례는 [언어×프레임워크 장애 사례집](/blog/devops/2026-03-07-devops-debugging-casebook-language-framework-combos)에서, 원격 디버깅 전체 절차는 [원격 디버깅 실전 가이드](/blog/devops/2026-03-07-devops-remote-debugging-guide-ssh-tunnel-vscode-intellij-pycharm)에서 확인할 수 있다.

현재 단락 (1/362)

좋은 IDE를 쓰는데도 디버깅이 느린 이유는 대부분 같다.

작성 글자: 0원문 글자: 12,565작성 단락: 0/362