본문으로 건너뛰기

VSCode 디버깅 및 프로젝트 관리

이 문서는 VSCode에서 Functorium 프로젝트를 효율적으로 디버깅하고 개발하기 위한 환경 설정을 안내합니다. 디버깅 설정에 어려움을 겪거나, 팀 전체의 개발 환경을 표준화하고 싶을 때 참고하세요.

Terminal window
# 디버깅 시작
F5
# 디버깅 없이 실행
Ctrl+F5
# 빌드 태스크 실행
Ctrl+Shift+B
# 태스크 목록 열기
Ctrl+Shift+P "Tasks: Run Task"

1. 디버깅 시작:

Terminal window
# 1. F5 키 누르기
# 2. 디버그 구성 선택 (예: "LayeredArch")
# 3. 통합 터미널에서 로그 확인
파일역할
launch.json디버깅 구성 (F5로 실행)
tasks.json빌드/실행 태스크 정의
settings.json프로젝트별 VSCode 설정
확장용도
C# Dev KitC# 개발 지원
.NET Install Tool.NET SDK 관리

요약에서 디버깅과 태스크의 핵심 명령을 확인했습니다. 이제 VSCode 설정 파일의 구조와 각 파일의 역할을 상세히 살펴봅니다.

.vscode/
├── settings.json # 프로젝트별 VSCode 설정
├── launch.json # 디버깅 설정 + compounds
├── tasks.json # 빌드 태스크 설정
└── keybindings.json # 단축키 설정 (참고용)

디버깅 구성을 정의합니다. 구성 이름은 {ProjectName} 패턴을 사용합니다.

{
"version": "0.2.0",
"configurations": [
{
"name": "LayeredArch",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-LayeredArch",
"program": "${workspaceFolder}/Tests.Hosts/01-SingleHost/Src/LayeredArch.Adapters.Infrastructure/bin/Debug/net10.0/LayeredArch.Adapters.Infrastructure.dll",
"args": [],
"cwd": "${workspaceFolder}",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
]
}

주요 속성:

속성설명
name디버그 구성 이름 (F5 시 선택 가능), {ProjectName} 패턴 사용
preLaunchTask디버깅 전 실행할 태스크, build-{ProjectName} 패턴으로 tasks.json의 label 참조
program실행할 DLL 경로
cwd작업 디렉토리
env환경 변수

빌드 및 실행 태스크를 정의합니다. 태스크 레이블은 {task}-{ProjectName} 패턴을 사용합니다.

{
"version": "2.0.0",
"tasks": [
{
"label": "build-LayeredArch",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Tests.Hosts/01-SingleHost/Src/LayeredArch.Adapters.Infrastructure/LayeredArch.Adapters.Infrastructure.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
태스크 패턴설명실행 방법
build-{ProjectName}프로젝트 빌드F5 (자동) 또는 Ctrl+Shift+B
publish-{ProjectName}배포용 빌드Tasks: Run Task → publish-{ProjectName}
watch-{ProjectName}Hot Reload 모드 실행Tasks: Run Task → watch-{ProjectName}

프로젝트별 VSCode 설정:

{
"dotnet.defaultSolution": "Functorium.slnx",
"omnisharp.enableRoslynAnalyzers": true,
"omnisharp.enableEditorConfigSupport": true,
"csharp.semanticHighlighting.enabled": true,
"files.exclude": {
"**/bin": true,
"**/obj": true,
"**/TestResults": true
},
"dotnet.preferCSharpExtension": true
}

설정 파일의 구조를 이해했으니, 이제 실제 디버깅 워크플로우를 단계별로 살펴봅니다.

  1. F5 키를 눌러 디버깅 시작
  2. 디버그 구성 선택 (예: LayeredArch)
  3. build-{ProjectName} 태스크가 먼저 실행됨
  4. 빌드 성공 시 애플리케이션 시작
  5. 통합 터미널에서 로그 확인
1. 코드 왼쪽 여백 클릭 → 빨간 점 표시
2. F5로 디버깅 시작
3. 해당 코드 실행 시 중단
4. F10 (Step Over), F11 (Step Into), F5 (Continue)

브레이크포인트 우클릭 → Edit Breakpoint...에서 조건 설정:

유형설명예시
Expression조건이 true일 때 중단user.Id == 42
Hit CountN번째 실행 시 중단= 10
Log Message중단 없이 로그만 출력User: {user.Name}

코드 수정 없이 디버깅 중 로그를 출력합니다. 코드 왼쪽 여백 우클릭 → Add Logpoint...:

Processing user: {user.Name}, Role: {user.Role}
Request received: {request.Method} {request.Path}

팁: 로그포인트는 빨간 점 대신 다이아몬드 모양으로 표시됩니다.

옵션Ctrl+C 지원설명
integratedTerminalO통합 터미널에서 실행, Ctrl+C 전달됨
externalTerminalO외부 터미널 창에서 실행
internalConsoleX디버그 콘솔 (Ctrl+C 미지원)

참고: internalConsole을 사용하면 Ctrl+C가 전달되지 않아 애플리케이션이 강제 종료됩니다. 리소스 정리가 필요한 경우 반드시 integratedTerminal을 사용하세요.

단축키동작설명
F5Start/Continue디버깅 시작 또는 계속 실행
Ctrl+F5Run Without Debugging디버깅 없이 실행
Shift+F5Stop디버깅 중지
Ctrl+Shift+F5Restart디버깅 재시작
F6Pause실행 일시 중지
단축키동작설명
F10Step Over현재 줄 실행 (함수 내부로 들어가지 않음)
F11Step Into현재 줄 실행 (함수 내부로 들어감)
Shift+F11Step Out현재 함수에서 빠져나옴
Ctrl+F10Run to Cursor커서 위치까지 실행
단축키동작설명
F9Toggle Breakpoint브레이크포인트 설정/해제
Ctrl+F9Enable/Disable브레이크포인트 활성화/비활성화
Ctrl+Shift+F9Remove All모든 브레이크포인트 제거
단축키동작설명
Ctrl+Shift+DDebug View디버그 패널 열기
Ctrl+Shift+YDebug Console디버그 콘솔 열기
Ctrl+K Ctrl+IShow Hover변수 정보 팝업 표시

파일 탐색:

단축키동작
Ctrl+P파일 빠른 열기
Ctrl+Shift+P명령 팔레트
Ctrl+Shift+E탐색기 패널
Ctrl+Shift+F전체 검색

코드 편집:

단축키동작
F12정의로 이동
Alt+F12정의 미리보기
Shift+F12모든 참조 찾기
F2심볼 이름 변경
Ctrl+SpaceIntelliSense 표시

기본 디버깅과 단축키를 익혔으니, 이제 Watch, 디버그 콘솔, Hot Reload 등 고급 디버깅 기법을 알아봅니다.

디버깅 중 Ctrl+Shift+D → WATCH 섹션에서 표현식 추가:

users.Count
users.Where(u => u.IsActive).ToList()
response?.Content?.Headers?.ContentType
user?.Name ?? "Anonymous"

디버깅 중 Ctrl+Shift+Y로 표현식을 실행:

// 변수 값 확인
user.Name
// 객체 JSON 직렬화
System.Text.Json.JsonSerializer.Serialize(user, new System.Text.Json.JsonSerializerOptions { WriteIndented = true })
// 컬렉션 내용 확인
string.Join(", ", items.Select(i => i.Name))

디버깅 중 코드를 수정하고 계속 실행합니다.

지원되는 변경: 메서드 본문 수정, 지역 변수 추가/수정, 람다 표현식 수정, 속성 값 변경

지원되지 않는 변경: 메서드 시그니처 변경, 새 클래스/인터페이스 추가, 제네릭 타입 변경, async/await 추가

브레이크포인트에서 중단 후 CALL STACK 패널에서 함수 호출 경로를 추적합니다.

{
"justMyCode": true,
"enableStepFiltering": true,
"symbolOptions": {
"searchMicrosoftSymbolServer": true
}
}

launch.jsoncompounds 구성 사용:

{
"compounds": [
{
"name": "API + Worker",
"configurations": ["API Server", "Worker Service"],
"stopAll": true
}
]
}
속성설명
name복합 구성 이름 (F5 시 선택 가능)
configurations동시에 실행할 구성 이름 배열
stopAll하나가 종료되면 모두 종료 (true 권장)

Docker 컨테이너에서 실행 중인 애플리케이션을 디버깅합니다.

launch.json 설정:

{
"name": "Docker Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickRemoteProcess}",
"pipeTransport": {
"pipeProgram": "docker",
"pipeArgs": ["exec", "-i", "container-name"],
"debuggerPath": "/vsdbg/vsdbg",
"pipeCwd": "${workspaceFolder}"
},
"sourceFileMap": {
"/app": "${workspaceFolder}/Src/MyApp"
}
}

태스크 레이블은 {task}-{ProjectName} 네이밍 규칙을 따릅니다.

프로젝트를 빌드합니다.

Terminal window
# 수동 실행
Ctrl+Shift+B
# 또는
Ctrl+Shift+P "Tasks: Run Task" "build-LayeredArch"

배포용으로 빌드합니다.

Terminal window
Ctrl+Shift+P "Tasks: Run Task" "publish-LayeredArch"

Hot Reload 모드로 실행합니다. 코드 변경 시 자동으로 재빌드하고 재시작합니다.

Terminal window
Ctrl+Shift+P "Tasks: Run Task" "watch-LayeredArch"

원인: C# 확장이 설치되지 않았거나 활성화되지 않음

해결:

Terminal window
# 1. 확장 설치 확인
Ctrl+Shift+X "C# Dev Kit" 검색 설치
# 2. VSCode 재시작

증상: preLaunchTask 'build-{ProjectName}' could not be found

원인: tasks.json 파일이 없거나 해당 build 태스크가 정의되지 않음

해결: .vscode/tasks.json 파일에 build-{ProjectName} 태스크가 정의되어 있는지 확인

해결:

Terminal window
# 1. .NET SDK 설치 확인
dotnet --version
# 2. 터미널에서 직접 빌드 시도
dotnet build <프로젝트경로>/<프로젝트>.csproj

메서드 시그니처 변경, 새 클래스 추가 등은 Hot Reload를 지원하지 않습니다. watch 태스크를 중지(Ctrl+C) 후 재시작하세요.

VSCode에서 설정이 반영되지 않을 때

섹션 제목: “VSCode에서 설정이 반영되지 않을 때”

해결: Ctrl+Shift+P → “Developer: Reload Window” 또는 VSCode 재시작

해결:

Terminal window
# 현재 세션에서만 허용
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
# 또는 사용자 수준에서 허용
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Q1. launch.json과 tasks.json의 차이점은 무엇인가요?

섹션 제목: “Q1. launch.json과 tasks.json의 차이점은 무엇인가요?”
파일용도실행 방법
launch.json디버깅 구성 정의F5
tasks.json빌드/실행 태스크 정의Ctrl+Shift+B 또는 Run Task

launch.jsonpreLaunchTasktasks.json의 태스크를 참조합니다.

Q2. 다른 프로젝트를 디버깅하려면 어떻게 하나요?

섹션 제목: “Q2. 다른 프로젝트를 디버깅하려면 어떻게 하나요?”

launch.json{ProjectName} 패턴으로 새 구성을 추가하고, tasks.json에 대응하는 build-{ProjectName} 태스크를 추가합니다.

Q3. 여러 프로젝트를 동시에 실행하려면 어떻게 하나요?

섹션 제목: “Q3. 여러 프로젝트를 동시에 실행하려면 어떻게 하나요?”

launch.jsoncompounds에 동시에 실행할 구성 이름을 배열로 지정합니다. F5에서 compound 구성을 선택하면 여러 프로젝트가 동시에 시작됩니다.

Q4. 환경 변수를 추가하려면 어떻게 하나요?

섹션 제목: “Q4. 환경 변수를 추가하려면 어떻게 하나요?”

launch.jsonenv 섹션에 추가:

{
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"MY_CUSTOM_VAR": "value"
}
}

Q5. Ctrl+C로 애플리케이션이 종료되지 않습니다.

섹션 제목: “Q5. Ctrl+C로 애플리케이션이 종료되지 않습니다.”

console 설정을 integratedTerminal로 변경하세요:

{
"console": "integratedTerminal"
}

internalConsoleCtrl+C 신호가 전달되지 않습니다.

Q6. 동시 실행 시 각 프로젝트의 포트가 충돌합니다.

섹션 제목: “Q6. 동시 실행 시 각 프로젝트의 포트가 충돌합니다.”

각 구성의 env에서 다른 포트를 지정하세요:

{
"env": {
"ASPNETCORE_URLS": "http://localhost:5000"
}
}

Q7. 단축키로 다른 프로젝트를 빌드하려면?

섹션 제목: “Q7. 단축키로 다른 프로젝트를 빌드하려면?”

Ctrl+Shift+P → “Tasks: Run Task”에서 원하는 build-{ProjectName} 태스크를 선택합니다.