Process Monitor(ProcMon) 실전 가이드 ── 「설정이 읽히지 않는다」「ACCESS DENIED」를 10분 만에 특정한다

· 업데이트: · · Process Monitor, Sysinternals, 장애 조사, 디버깅, 트러블슈팅, Windows 개발, 운영, 기술 상담

수정 이력(7건, 최종 수정 2026년 09월 03일)

이 글에 적용한 변경 사항의 기록입니다. 보관해 둔 수정 전 버전은 DOI가 부여된 고정 URL에서 읽을 수 있습니다.

Codex 리뷰에 따라 상담·문의 링크에 /ko/ 로케일 접두를 붙였습니다. 본문의 기술적인 주장은 바꾸지 않았습니다.
관련 기사 링크를 한국어 permalink에 맞추는 등 CI가 지적한 표시용 수정을 반영했습니다. 본문의 기술적인 주장은 바꾸지 않았습니다.
permalink·저자 표기·지식 맵 래퍼·깨진 내부 링크 등 CI가 지적한 표시용 수정을 반영했습니다. 본문의 기술적인 주장은 바꾸지 않았습니다.
기사 맨 앞에 「이 기사의 지식 맵」 절을 추가했습니다. 본문에서 다루는 개념과 그 관계를 요약·그림·상세 페이지 링크로 정리한 것입니다. 본문의 주장은 바꾸지 않았습니다.
외부 리뷰(1283건)에 대응해 본문을 갱신했습니다. 개별 변경 내용은 아래 이력을 참조하세요.
「10분 만에 특정」의 내용을 시간 배분 표로 만들고, 처음 5분 동안 볼 곳을 3곳으로 좁혔습니다. 이와 함께 로그가 이어지는 흐름을 읽는 법, 원인을 특정한 뒤에 할 일의 절차, ProcMon으로 보이지 않는 영역과 대체 수단의 빠른 참조 표를 추가했습니다.
본문의 관련 기사 링크 문구가 링크 대상의 현재 제목과 어긋나 있던 부분을 실제 제목에 맞췄습니다. 본문 내용은 바꾸지 않았습니다.
최초 공개
이 글을 인용하기(DOI(등록된 아카이브): 10.5281/zenodo.21635414)

아래 DOI는 이전에 등록된 아카이브를 가리키며 현재 본문과 다를 수 있습니다. 현재 본문을 참조할 때는 이 페이지의 URL을 사용하세요.

Go Komura (2026). 「Process Monitor(ProcMon) 실전 가이드 ── 「설정이 읽히지 않는다」「ACCESS DENIED」를 10분 만에 특정한다」. 합동회사 코무라소프트. https://comcomponent.com/ko/blog/procmon-practical-guide/

DOI(등록된 아카이브)
10.5281/zenodo.21635414
DOI(마지막 등록 버전)
10.5281/zenodo.21635415

「설정 파일을 바꿨는데 앱 동작이 바뀌지 않는다」「개발 머신에서는 되는데, 고객 현장 단말에서만 시작 직후 죽는다」「어제까지는 됐다. 프로그램은 아무것도 바꾸지 않았다」──장애 조사 의뢰는 대개 이런 형태로 들어옵니다. 그리고 이런 증상의 상당수는 소스 코드를 아무리 읽어도 원인에 닿지 못합니다. 앱이 실제로 어떤 파일을 읽고, 어떤 레지스트리를 보고, 무엇에 실패했는지는 코드가 아니라 실행 환경이 정하기 때문입니다.

그 「실제로 무엇이 일어났는지」를 기록해 주는 것이 Microsoft가 무상으로 제공하는 Sysinternals 도구 Process Monitor(ProcMon)입니다. 파일 시스템·레지스트리·프로세스/스레드 활동을 실시간으로 전부 기록하는, 말하자면 Windows의 행동 로그 레코더이며, 당사 장애 조사에서도 WinDbg와 나란히 자주 쓰는 도구입니다.1

강력한 만큼, 아무것도 하지 않고 시작하면 매초 수천〜수만 건의 이벤트가 흘러들어와, 처음 보면 「너무 많아 읽을 수 없다」로 끝나기 쉽습니다. 이 기사에서는 ProcMon을 실무에서 쓰기 위한 최단 경로──필터 거는 법, Result 열 읽는 법, 증상별 정석 조사 패턴, 프로덕션 환경에서의 주의점, 그리고 다른 조사 도구와의 역할 분담──을 장애 조사 현장 관점에서 정리합니다.

1. 먼저 결론

  • ProcMon이 답해 주는 질문은 「이 프로세스는 언제·어느 경로에·무엇을 해서·어떻게 되었는지」입니다. 설정 파일이 어디에서 읽히는지, DLL이 어떤 순서로 탐색되었는지, 어느 조작이 ACCESS DENIED가 되었는지가 몇 분 만에 드러납니다.
  • 사용법의 정석은 「먼저 Process Name으로 대상 프로세스에 Include를 걸고, 이어서 Result로 비정상 결과에 좁힌다」입니다. 생 이벤트를 위에서부터 읽는 도구가 아닙니다.
  • Result 열에는 이상처럼 보이지만 정상인 것이 많습니다. BUFFER OVERFLOW는 정상적인 API 왕복이고, NAME NOT FOUND는 탐색 순서의 중간 경과인 경우가 대부분입니다(4장).
  • 필터는 표시상의 좁히기이며, 뒤에서는 전체 이벤트가 기록됩니다. 로그를 저장해 사람에게 넘길 때는 전체 이벤트로 저장합니다. 반대로 장시간 캡처에서는 Drop Filtered Events로 메모리를 지킵니다(5장).
  • ProcMon은 만능이 아닙니다. 「지금 어느 프로세스가 이 파일을 잡고 있는지」는 Process Explorer, 크래시 순간의 상태는 크래시 덤프, CPU를 어디에서 쓰는지는 PerfView의 영역입니다(7장).

증상에서 도구를 고르는 빠른 참조 표를 먼저 둡니다.

증상·알고 싶은 것 먼저 쓰는 도구
설정이 반영되지 않는다/어느 파일·레지스트리를 읽고 있는지 ProcMon
특정 환경에서만 시작되지 않는다·DLL을 찾지 못한다 ProcMon
ACCESS DENIED·권한 관련 실패의 특정 ProcMon
파일을 삭제할 수 없다. 누가 잡고 있는지 Process Explorer(핸들 검색)
앱이 죽는다. 예외·크래시의 원인 크래시 덤프 + WinDbg
느리다. CPU·메모리를 어디에서 쓰는지 PerfView / dotnet-trace
장기 가동에서 핸들·메모리가 계속 늘어난다 Process Explorer + 핸들 누수 조사
통신 내용(패킷)을 보고 싶다 Wireshark / pktmon

제목의 「10분」은 다음 시간 배분을 가정합니다. 소요 시간은 증상과 환경에 따라 다르지만, 절차와 쓸 시간을 먼저 정해 두는 것이 이벤트 바다를 바라보며 오후를 날리지 않기 위한 가장 큰 대책입니다.

경과 할 일 구체적인 조작
〜2분 시작과 필터 설정 관리자로 Procmon.exe 실행 → Ctrl+E로 일단 캡처 중지 → Ctrl+X로 표시 지우기 → Ctrl+L로 Process Name / is / 대상 exe / Include를 추가(3장)
〜5분 재현 수집 Ctrl+E로 시작 → 문제 조작만 재현 → 증상이 나오면 바로 Ctrl+E로 중지
〜8분 비정상 결과로 좁히기 Result / is not / SUCCESS를 더하거나, 눈에 띄는 행을 오른쪽 클릭 → Include / Exclude로 노이즈를 깎는다(3·4장)
〜10분 인과 확인 감이 온 행 주변에서 필터를 끄고, 앞뒤 행을 시계열로 읽는다. 증상 발생 시각과 맞는지 본다(5장)

처음 5분 동안 볼 곳은 세 곳뿐입니다. (1) 대상 프로세스의 ACCESS DENIED, (2) 설정 파일 이름·DLL 이름에 대한 NAME NOT FOUND의 연쇄, (3) 기대하지 않은 위치로의 SUCCESS. 이 세 곳에 아무것도 나오지 않으면, 증상의 원인은 ProcMon의 담당 범위(파일·레지스트리·프로세스) 밖에 있을 가능성이 높으므로, 집착하지 말고 위의 빠른 참조 표로 돌아가 다른 도구로 바꿉니다.

그림의 실선은 항상 성립하는 관계, 점선은 조건이 붙는 관계입니다(성립 조건은 상세 페이지의 관계별 설명에 적혀 있습니다). 관계 전체 목록(총 18건, 근거와 확신도 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 정리되어 있습니다(일본어). 데이터: JSON-LD / Turtle

2. ProcMon이란 무엇인가 ── 도입은 1분이면 끝난다

Process Monitor는 Sysinternals 도구군 중 하나로, 파일 시스템·레지스트리·프로세스/스레드 활동을 실시간으로 표시하는 감시 도구입니다. 과거의 Filemon과 Regmon이라는 두 도구를 통합·강화한 후속이며, 이벤트별 상세 정보, 비파괴 필터, 스레드 스택 기록, 부트 타임 로깅 등을 갖추고 있습니다.1

도입은 간단합니다. 설치 프로그램은 없고, 다운로드 페이지에서 ZIP을 받아 압축을 푼 뒤 Procmon.exe를 실행하면 됩니다. 급한 조사에서는 Sysinternals Live라는 서비스를 사용해 https://live.sysinternals.com/procmon.exe에서 직접 실행할 수도 있습니다.2 첫 시작 시 사용권 계약 동의를 요구하며, 커널 드라이버를 로드하므로 관리자 권한(UAC 상승)이 필요합니다. 관리자 권한이 왜 필요한지에 대한 일반론은 「Windows에서 관리자 권한이 필요한 때는 언제인가」에서 쓴 대로이며, OS 전체 이벤트를 보는 도구는 전형적인 「상승이 필요한」 쪽입니다.

시작한 순간부터 캡처가 시작되고 화면에 이벤트가 흐르기 시작합니다. 주요 조작은 세 가지만 기억하면 됩니다.

조작 단축키 의미
캡처 시작/중지 Ctrl+E 기록 온·오프. 재현 조작 직전에 시작, 직후에 중지가 기본
표시 지우기 Ctrl+X 보이는 상태를 리셋. 재현 조작 직전에 누르면 노이즈가 줄어든다
필터 대화상자 Ctrl+L 좁히기 조건 추가·편집(3장)

한 행의 이벤트는 「Time(시각)·Process Name(프로세스)·PID·Operation(조작)·Path(대상 경로)·Result(결과)·Detail(상세)」로 구성됩니다. Operation은 CreateFile(파일을 열기/만들기), ReadFile/WriteFile, RegOpenKey/RegQueryValue 등 Win32 API에 대체로 대응하는 단위입니다. 즉 ProcMon 로그는 「앱과 OS의 대화 기록」이며, 앱이 설정 파일을 읽으려 했는데 실제로는 어디를 읽었는지라는 「의도」와 「실제」의 차이가 그대로 보입니다.

3. 필터 ── ProcMon은 좁힌 뒤에 읽는 도구

아무것도 하지 않고 캡처하면, 유휴 상태의 Windows에서도 매초 수천 건의 이벤트가 흐릅니다. ProcMon의 실용성은 필터 사용법으로 정해진다고 해도 지나치지 않으며, 정석은 다음 2단계입니다.

필터 대화상자는 Filter 메뉴 > Filter…(Ctrl+L) 로 엽니다. 대화상자 위쪽에 가로 한 줄로 늘어선 것이 조건 입력란이고, 왼쪽부터 「열(Process Name, Path, Result 등)」「관계(is / is not / contains / begins with / ends with 등)」「값(직접 입력)」「Include / Exclude」의 네 가지입니다. 이 네 가지를 고른 뒤 Add 버튼을 눌러야 비로소 아래 목록에 조건이 추가됩니다. 입력만 하고 Add를 누르지 않은 채 OK해서 「필터가 안 먹는다」고 고민하는 것은, 누구나 한 번은 하는 조작 실수입니다. 이미 추가한 조건은 목록 왼쪽 끝 체크박스로 일시적으로 끌 수 있고, 선택한 뒤 Remove로 삭제할 수 있습니다. 이하 조건은 열 / 관계 / 값 / Include 또는 Exclude 순으로 적습니다.

1단계: 프로세스로 좁힌다. 필터 대화상자에서 Process Name / is / myapp.exe / Include를 추가합니다. 도구 모음의 조준 아이콘을 대상 앱 창으로 끌어다 그 프로세스만 필터하는 방법도 있습니다.

2단계: 결과나 조작으로 좁힌다. 「실패한 조작을 찾고 싶다」면 Result / is not / SUCCESS / Include(비정상 결과만 표시). 「쓰기만 보고 싶다」면 Category / is / Write / Include. 「이 설정 파일에 손대는 것은 누구인가」면 프로세스로 좁히지 않고 Path / contains / app.config / Include, 식입니다.

실무에서 더 자주 쓰는 것은 이벤트 행을 오른쪽 클릭한 대화형 좁히기입니다. 목적에 가까운 행을 하나 찾으면, 오른쪽 클릭으로 「Include ‘이 경로’」「Exclude ‘이 프로세스’」만 고르면 대화상자를 열지 않고 필터가 쌓입니다. 노이즈 원인(바이러스 백신, 인덱서 등)을 Exclude로 지워 가며, 목적 조작의 전후만 남기는 것이 기본 동작입니다. 눈으로 보기 위한 보조로는 하이라이트(Ctrl+H)도 쓸 수 있습니다. 필터와 같은 조건식으로 행에 색을 칠 수 있으므로, 「전체 흐름은 보고 싶지만 비정상 결과만 눈에 띄게 하고 싶다」면 필터가 아니라 하이라이트를 씁니다.

세 가지, 모르면 빠지는 사양이 있습니다.

  • 필터는 표시의 좁히기이지, 기록의 좁히기가 아닙니다. 뒤에서는(기본값으로는) 전체 이벤트가 기록되며, 필터를 끄면 언제든 전체로 돌아갈 수 있습니다. 비파괴 필터라고 불리는 이유이며, 「너무 좁혀서 증거를 놓친다」가 일어나기 어려운 설계입니다.1
  • 필터 설정은 다음 시작 시에도 이어집니다. 이전 조사의 필터가 남은 채로 「아무것도 표시되지 않는다」고 고민하는 것은 누구나 한 번은 겪는 길입니다. 표시가 이상하다 싶으면 Filter 메뉴의 Reset Filter(Ctrl+R)를 먼저 의심하세요.
  • 기본값으로 몇 가지 Exclude가 들어가 있습니다. ProcMon 자신이나 페이징 I/O 등은 처음부터 제외되어 있습니다. 「시스템 전체를 빠짐없이」가 요건인 조사에서는 기본 필터의 존재를 의식하세요.

4. Result 열 읽는 법 ── 이상처럼 보이지만 정상인 것

필터로 비정상 결과에 좁히면, 이번에는 「이상해 보이는 결과」가 대량으로 나와 놀라게 됩니다. 여기서 중요한 것은 Result 열의 이상값 대부분은 정상 동작의 일부라는 점입니다. 주요 Result의 읽는 법을 정리합니다.

Result 의미 문제일 가능성
SUCCESS 성공 ─(다만 「성공하면 안 되는 곳에서의 성공」이 원인인 경우도 있다)
NAME NOT FOUND 그 경로에 이름이 없다 낮음〜중간. 탐색 순서의 중간 경과가 대부분. 끝까지 SUCCESS하지 않으면 진짜 원인
PATH NOT FOUND 중간 폴더 자체가 없다 중간. 오타·미작성 폴더·환경 차의 정석
ACCESS DENIED 액세스 거부 높음. 권한·ACL·바이러스 백신·보호 영역으로의 쓰기
SHARING VIOLATION 공유 위반(다른 쪽이 배타로 열고 있다) 높음. 파일 잠금 경합. 상대 프로세스 특정으로
BUFFER OVERFLOW 버퍼가 작아서 필요 크기를 돌려줬다 없음. 정상적인 API 왕복(FAQ 참조)
REPARSE reparse point(심볼릭 링크 등)를 따라갔다 거의 없음. 경로가 바뀐 흔적으로 읽는다
NO MORE FILES / NO SUCH FILE 열거의 끝 등 거의 없음

그리고 실제 로그는 한 행씩 독립해서 읽지 않고 이어지는 흐름으로 읽습니다. 「시작 시 mylib.dll을 찾지 못한다」 케이스를 예로 행 읽는 법을 보입니다. 다음 표는 설명을 위해 Operation / Path / Result 세 열만 뽑아 낸 도식이며, 실제 화면에서는 이 좌우에 Time·Process Name·PID·Detail이 나란히 있습니다(CreateFile의 Detail 열에는 그 호출에 넘겨진 Desired Access:나 ShareMode: 같은 매개변수가 들어갑니다).

# Operation Path Result 이 행의 읽는 법
1 CreateFile C:\Program Files\MyApp\mylib.dll NAME NOT FOUND exe와 같은 폴더를 먼저 봤다. 여기에 없다는 것 자체는 예상 안
2 CreateFile C:\Windows\System32\mylib.dll NAME NOT FOUND 시스템 폴더에도 없다. 아직 이상이라고 말할 수 없다
3 CreateFile C:\Windows\mylib.dll NAME NOT FOUND 탐색 순서를 진행 중(실제로는 이 전후로 여러 폴더가 더 시도된다)
4 CreateFile C:\Tools\mylib.dll SUCCESS PATH 환경 변수의 도중에 찾았다. 여기가 실제로 읽은 곳

1〜3행만 보고 「DLL이 없는 것이 원인이다」라고 결론 내는 것이 가장 흔한 오독입니다. 봐야 할 것은 마지막에 SUCCESS가 있는지, 있다면 그 경로가 의도한 곳인지 두 가지이며, 이 예의 결론은 「DLL은 찾아졌다. 다만 배포했을 C:\Program Files\MyApp의 것이 아니라, 개발 머신에 남아 있던 C:\Tools의 오래된 버전을 잡고 있다」가 됩니다. 4행이 없으면(끝까지 NAME NOT FOUND로 끝나고, 직후에 프로세스가 종료되면) 정말로 찾지 못한 케이스입니다. 「NAME NOT FOUND의 수」가 아니라 「이어지는 흐름이 어떻게 끝나는지」를 본다고 기억하세요.

이 가운데 조사의 주역이 되는 것은 NAME NOT FOUND·ACCESS DENIED·SHARING VIOLATION 세 가지입니다. 각각 정석 조사 패턴이 있으므로, 다음 장에서 증상 쪽에서 보겠습니다.

반대로 놓치기 쉬운 것이 「SUCCESS가 원인」인 패턴입니다. 예를 들어 「고친 설정 파일이 반영되지 않는다」의 답이 다른 곳에 있는 오래된 설정 파일로의 SUCCESS였던 일은 한두 번이 아닙니다. 비정상 결과만 보고 있으면 정상적으로 읽힌 「잘못된 정답」을 놓치므로, 경로로 좁혀 그 파일 종류에 대한 액세스를 성공까지 포함해 전부 보는 것이 확실합니다.

5. 증상별 정석 조사 패턴

5.1 「설정을 고쳤는데 반영되지 않는다」── 어디에서 읽고 있는지를 특정한다

Path / contains / 설정 파일 이름 으로 Include를 걸고 앱을 시작하면, 앱이 그 이름의 파일을 어느 폴더에서, 어떤 순서로 찾았는지가 목록이 됩니다. 흔한 진상은 다음 중 하나입니다.

  • exe와 같은 폴더가 아니라 %APPDATA%나 ProgramData 아래의 복사본을 읽고 있었다(첫 시작 시 복사하는 설계였다)
  • 32bit 프로세스에서의 레지스트리·시스템 폴더 액세스가 WOW64 리다이렉트를 받아, 보고 있다고 생각한 위치와 실제 위치가 어긋나 있었다
  • 설치 위치의 Program Files 아래로의 쓰기가 가상화(VirtualStore)되어, 읽기·쓰기가 다른 곳으로 바뀌어 있었다

어느 쪽이든 ProcMon이면 Path에 전체 경로가 나오므로 한눈에 알 수 있습니다. 설정 파일 두는 곳을 어떻게 설계해야 하는가라는 이면의 이야기는 「appsettings.json만이 전부가 아닙니다 ── Windows 업무 앱의 구성 관리 실무(환경별 설정·비밀 정보·쓰기 위치)」에 썼습니다.

읽은 위치를 알았으면 거기서 끝내지 말고 다음 3단계까지를 한 번의 조사에 넣습니다. 여기를 빼면 「고친 줄 알았는데」가 한 바퀴 더 돕니다.

  1. 읽기 쪽과 쓰기 쪽을 맞춰 본다. 설정 화면에서 저장하는 조작을 같은 필터로 수집해, 어느 경로로 WriteFile이나 RegSetValue가 가는지 봅니다. 읽은 위치와 쓰는 위치가 어긋나면, 그것이 증상의 정체입니다. 레지스트리와 설정 파일 양쪽에 같은 항목이 있는 경우에도, 어느 쪽을 먼저 읽는지는 로그 순서로 알 수 있습니다.
  2. 어느 쪽을 「정본」으로 할지 정한다. 이것은 조사가 아니라 설계 판단입니다. 실무에서는 「이용자가 화면에서 바꿀 수 있는 항목은 사용자 프로필 아래(쓰기 가능), 환경마다 고정하고 싶은 항목은 배치 위치(읽기 전용)」처럼 쓰기 권한으로 나누는 것이 무난합니다. Program Files 아래에 쓰려다 VirtualStore로 바뀌는 경우는, 두는 위치 자체를 다시 볼 신호입니다.
  3. 수정 후에 같은 캡처를 한 번 더 뜬다. 「고쳐졌다」의 확인은 앱 겉모습이 아니라 로그로 합니다. 목적 경로로의 액세스가 SUCCESS로 바뀌고, 오래된 위치로의 읽기가 사라진 것까지 봅니다. VirtualStore나 프로필 아래에 남은 복사본은 원본을 고쳐도 계속 읽히므로, 옛 파일을 삭제한 뒤에 다시 확인하지 않으면 판정이 틀립니다.

5.2 「이 환경에서만 시작되지 않는다」── DLL 탐색을 따라간다

시작 직후 죽거나 「DLL을 찾을 수 없습니다」 계열 오류가 나면, 프로세스로 Include한 다음 Path / ends with / .dll 을 추가하고 NAME NOT FOUND의 연쇄를 봅니다. Windows의 DLL 탐색은 정해진 순서로 폴더를 따라가므로, ProcMon 로그에는 「탐색 순서대로 NAME NOT FOUND가 늘어서고, 어딘가에서 SUCCESS한다(또는 끝까지 찾지 못한다)」는 형태가 그대로 나타납니다. 끝까지 SUCCESS하지 않는 DLL이 원인입니다. 반대로 「SUCCESS했지만, 의도하지 않은 곳의 오래된 DLL을 잡고 있다」 패턴도 여기서 찾습니다. 탐색 순서의 이치는 「Windows DLL 이름 확인 방식」을 함께 읽으세요.

COM/ActiveX 관련의 「클래스가 등록되어 있지 않습니다」도 같은 형이며, RegOpenKey의 CLSID 아래로의 NAME NOT FOUND로 관측할 수 있습니다. 32bit/64bit를 잘못 짚어 다른 뷰의 레지스트리를 보는 사고는 「Office 2024/Microsoft 365에서 ActiveX가 작동하지 않는 원인과 확인 절차」에서 쓴 절차대로 ProcMon이 가장 빠릅니다.

5.3 「ACCESS DENIED가 된다」── 누구의 권한으로 돌고 있는지를 의심한다

ACCESS DENIED를 찾으면 그 이벤트를 더블클릭하고, 열린 이벤트 속성에서 Process 탭을 확인합니다. 그 프로세스가 어느 사용자로 돌고 있었는지가 나오므로, 「서비스는 SYSTEM이 아니라 제한된 서비스 계정으로 돌고 있었다」「작업 스케줄러로 시작할 때만 다른 사용자였다」는 어긋남이 여기서 드러납니다. 대상이 파일이면 그 경로의 ACL과 맞춰 보면 원인이 확정됩니다. 참고로 바이러스 백신이 개입하는 케이스에서는, 직전·직후에 다른 프로세스(백신 엔진)가 같은 경로에 손대는 모습이 보이는 경우가 많고, 이것도 시계열로 기록하는 ProcMon만의 증거가 됩니다. ACL이나 서비스 계정을 고친 뒤에는 같은 필터로 한 번 더 캡처해 해당 조작이 SUCCESS로 바뀌었는지 확인하세요. 첫 ACCESS DENIED를 해소하니 다음 경로에서 멈춘다는 단계적 실패는 흔한 패턴이며, 로그로 확인하지 않으면 「고쳤는데 증상이 안 바뀐다」로 보입니다.

5.4 「가끔 파일 처리가 실패한다」── SHARING VIOLATION의 상대를 찾는다

공유 위반은 시계열이 생명인 조사입니다. 경로로 Include를 걸고 프로세스 필터는 걸지 않은 채 캡처하면, 실패 순간에 같은 파일을 누가 열고 있었는지가 앞뒤 행에 나타납니다. 백업 소프트웨어·바이러스 백신·Excel의 잔여 프로세스 정도가 정석 상대입니다. 파일 연계에서 이 경합을 애초에 일으키지 않는 설계는 「파일 연계의 배타 제어 기초 지식」에, Excel 프로세스가 남는 문제는 「C# Excel 조작에서 EXCEL.EXE가 남는 문제」에 정리했습니다. 「지금 이 순간, 누가 잡고 있는지」만 알고 싶다면 ProcMon보다 Process Explorer의 핸들 검색(Ctrl+F)이 빠른 경우도 덧붙입니다.3

5.5 「시작이 느리다」── 어디에서 시간을 쓰는지 감을 잡는다

Options 메뉴 > Select Columns… 를 열고, 표시할 열 목록에서 Duration에 체크하면 개별 조작에 걸린 시간이 보입니다. 또한 Tools 메뉴의 Process Activity Summary나 File Summary로 프로세스·파일별 조작 횟수와 시간을 집계할 수 있습니다. 「시작 시 수만 회의 레지스트리 읽기를 하고 있었다」「네트워크 너머 경로로의 액세스가 타임아웃까지 기다리고 있었다」 같은 감 잡기에는 충분합니다. 다만 CPU를 어디에서 쓰는지의 본격적인 프로파일링은 ProcMon의 영역이 아닙니다. I/O가 아니라 계산이 느린 경우는 PerfView와 dotnet-trace로 바꿉니다.

5.6 시작 시·로그온 시의 문제 ── 부트 로깅

「서비스가 로그온 전에 실패한다」「시작 프로그램으로 등록한 앱이 시작되지 않는다」처럼, ProcMon을 손으로 시작하기 전에 문제가 생기는 케이스에는 Options 메뉴의 Enable Boot Logging을 씁니다. 다음 시작 시 부트 초기부터의 이벤트가 기록되고, 그다음 ProcMon을 시작할 때 저장을 요청받습니다. 부트 타임 로깅은 ProcMon의 공식 기능으로 제공되는 것이며,1 시작 순서·로그온 스크립트 관련 조사에서는 이것이 유일하게 볼 수 있는 수단입니다.

6. 로그 저장과 전달 ── 고객 환경에서 떠 달라고 할 때

장애 조사 실무에서는 재현하는 환경이 고객 쪽에만 있는 일이 드물지 않습니다. ProcMon 로그는 PML 파일로 저장할 수 있고, 다른 머신에서 열어도 모든 열·모든 상세를 볼 수 있으므로 「고객이 떠 주고, 이쪽에서 분석한다」는 분업이 성립합니다. 의뢰할 때의 절차서는 다음 형태로 둡니다.

  1. Procmon.exe를 관리자로 실행하고 사용권 계약에 동의한다
  2. 시작되면 일단 Ctrl+E로 캡처를 중지하고, Ctrl+X로 표시를 지운다
  3. Ctrl+E로 캡처를 시작해 문제 조작을 재현한다
  4. 재현되면(또는 오류가 나면) 바로 Ctrl+E로 중지한다
  5. File 메뉴 > Save…(Ctrl+S)를 고르고, 열린 대화상자에서 다음 두 가지를 지정해 저장한다
    • Events to save: 세 가지(All events / Events displayed using current filter / Highlighted events) 중 All events
    • Format: 세 가지(Native Process Monitor Format (PML) / Comma-Separated Values (CSV) / Extensible Markup Language (XML)) 중 Native Process Monitor Format (PML)
  6. 저장된 PML 파일을 ZIP으로 압축해 보낸다

Format에서 네이티브 형식(PML)을 고르는 이유는 PML만이 전체 데이터를 유지하고, 다른 머신의 ProcMon에서 그대로 열리기 때문입니다.1 CSV는 스프레드시트에서 열려 손쉽지만, 내보내는 것은 표시 중인 열의 내용뿐이며 스택 등의 상세는 남지 않습니다. 이쪽에서 분석할 전제의 전달에는 맞지 않는다고 보세요.

포인트는 5의 「All events」입니다. 상대 화면에 필터가 남아 있어도 기록 자체는 전량이 있으므로, 이쪽에서 자유롭게 다시 좁힐 수 있습니다. 재현에 시간이 걸리거나 언제 일어날지 모르는 문제에서는, 그대로 두면 메모리를 계속 쓰므로 Filter > Drop Filtered Events를 켜서 대상 프로세스만 기록하거나 File > Backing Files로 저장 위치를 가상 메모리가 아니라 파일로 전환하는 둘 중 적어도 하나를 지정합니다. 이 두 가지를 모르고 하룻밤 돌리면, 메모리를 다 써서 조사 대상보다 먼저 ProcMon이 한계에 닿습니다.

자동화하려면 명령줄 스위치도 쓸 수 있습니다. /AcceptEula로 동의 대화상자를 억제한 뒤, /BackingFile로 기록 대상 파일을 지정하고, /Runtime으로 초 단위 자동 중지, /Terminate로 실행 중인 ProcMon을 종료하는 식으로 조합하면 「장애 발생 시 운영자가 배치를 하나 실행하면 증거가 남는다」 형태가 됩니다. 장애 시 무엇을 수집할지 미리 정해 두는 사고는 크래시 덤프 수집이나 이벤트 로그 설계와 공통입니다.

7. ProcMon의 한계와 다른 도구와의 역할 분담

ProcMon은 「조작의 시계열」을 보는 도구이며, 모든 조사에 맞는 것은 아닙니다. 당사 조사에서의 역할 분담은 이렇습니다.

도구 보이는 것 쓰는 때
Process Monitor 파일·레지스트리·프로세스 시작의 시계열 환경 의존 장애, 설정·DLL·권한·잠금
Process Explorer 현재 프로세스·핸들·DLL의 상태 파일을 잡고 있는 원인 찾기, 핸들 수 관찰3
WinDbg + 덤프 크래시·행업 순간의 메모리와 스택 예외·크래시·프리즈 분석
PerfView / dotnet-trace CPU 샘플·GC·할당 「느림」의 정량 조사
Application Verifier API 오용·비정상 경로의 강제 출하 전 비정상 테스트
Wireshark / pktmon 패킷 내용 통신 프로토콜 수준 조사4

위 표가 도구 기준 목록이므로, 뒤집어서 「ProcMon으로는 보이지 않는 영역」에서도 찾을 수 있게 해 둡니다. 조사가 헛돌면 이 표에서 갈아탈 곳을 찾으세요.

ProcMon으로는 보이지 않는 영역 대신 쓰는 것
패킷 내용(요청·응답의 헤더나 본문) Wireshark / pktmon4
CPU 시간의 내역·GC·할당 PerfView / dotnet-trace
메모리 사용량이 계속 늘어나는 원인 GC인지 누수인지 가르기 / 덤프 분석
「지금」 열려 있는 핸들·DLL 목록 Process Explorer3
크래시·행업 순간의 스택과 변수 값 WinDbg + 덤프
API 오용(힙 파괴·핸들 이중 해제 등) Application Verifier
커널 내부 동작(드라이버 처리, 스케줄링) ETW + Windows Performance Analyzer, 커널 디버거

경계에서 헷갈리기 쉬운 것은 다음 세 가지입니다.

  • 네트워크: ProcMon은 TCP/UDP의 연결·송수신 이벤트(어느 프로세스가 어디와 통신했는지)는 기록하지만, 패킷 내용은 보이지 않습니다. 프로토콜 조사는 Wireshark나 Windows 기본의 pktmon으로 갑니다.4
  • 메모리: 「메모리 사용량이 계속 늘어난다」는 ProcMon으로는 따라갈 수 없습니다. 매니지드 힙이면 GC인지 누수인지 가르기, 핸들이면 핸들 누수 조사의 절차로 갑니다.
  • 스택: 실은 ProcMon도 각 이벤트의 발행원 스레드 스택을 기록하며(이벤트 더블클릭→Stack 탭), 심볼을 설정하면 「누가 이 파일 액세스를 발행했는지」를 코드 수준에서 특정할 수 있습니다. 여기까지 오면 WinDbg의 세계와 이어지고, 심볼(PDB) 관리가 효과를 냅니다.

8. 정리 ── 「코드를 읽기 전에, 사실을 본다」

환경 의존 장애 조사에서 먼저 해야 할 일은 코드를 읽는 것도 가설을 세우는 것도 아니라, 실제로 무엇이 일어났는지의 기록을 남기는 것입니다. ProcMon은 그 최단 경로이며, 도입 1분·캡처 수 분이면 「어느 경로를·어떤 순서로·어떤 권한으로 손대고·무엇에 실패했는지」라는 부정할 수 없는 사실이 손에 들어옵니다. 필터의 2단계(프로세스→Result), 이상처럼 보이지만 정상인 Result 읽는 법, 전체 이벤트 저장으로의 전달──이 세 가지를 잡으면, 「개발 머신에서는 재현되지 않습니다」에서 멈춰 있던 조사가 그날 안에 한 걸음 나아갑니다.

당사에서는 재현 조건을 알 수 없는 장애 조사, 고객 환경에서만 일어나는 장애의 증거 수집 절차 정비, ProcMon·WinDbg·PerfView를 조합한 원인 분석을 맡습니다. 「로그에는 아무것도 안 나오는데 동작하지 않는다」는 단계부터도 도울 수 있습니다.

관련 기사

관련 상담 영역

合同会社小村ソフト에서는 환경에 따라 재현하기 어려운 장애의 원인 조사, 장애 시 증거 수집 절차 정비, 기존 Windows 앱의 트러블슈팅 지원을 다룹니다.

참고 링크

  1. Microsoft Learn, Process Monitor - Sysinternals. Process Monitor가 파일 시스템·레지스트리·프로세스/스레드 활동을 실시간으로 표시하는 감시 도구라는 점, Filemon과 Regmon의 후속이라는 점, 비파괴 필터·스레드 스택 기록·부트 타임 로깅 등의 기능에 대해. ↩ ↩2 ↩3 ↩4 ↩5

  2. Microsoft Learn, Sysinternals Live. Sysinternals Live가 도구를 다운로드하지 않고 live.sysinternals.com/의 URL이나 파일 공유를 통해 직접 실행할 수 있는 서비스라는 점에 대해. ↩

  3. Microsoft Learn, Process Explorer - Sysinternals. Process Explorer가 프로세스가 연 핸들이나 로드한 DLL을 표시할 수 있다는 점, 어느 프로세스가 특정 파일이나 디렉터리를 열고 있는지 검색에 쓸 수 있다는 점에 대해. ↩ ↩2 ↩3

  4. Microsoft Learn, Packet Monitor (Pktmon). Windows 기본 패킷 캡처 도구 Packet Monitor의 개요와 용도에 대해. ↩ ↩2 ↩3

같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.

이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.

이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.

자주 묻는 질문

이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.

ProcMon을 프로덕션 환경에서 실행해도 괜찮습니까?
짧은 시간의 캡처라면 실무에서 자주 하지만, 무조건 안전한 것은 아닙니다. ProcMon은 드라이버를 로드해 대량의 이벤트를 기록하므로, 이벤트 발생량이 많은 서버에서는 CPU와 메모리를 눈에 띄게 소비합니다. 대책은 세 가지입니다. (1) 재현 조작 직전에 시작해 직후에 중지하고 캡처 시간을 가능한 한 짧게 한다, (2) 장시간 감시가 필요하면 Filter 메뉴의 Drop Filtered Events를 켜서 필터 밖 이벤트를 유지하지 않는다, (3) 기록 위치를 메모리가 아니라 파일로 하는 Backing File을 설정한다. 또한 업무 시간 외 실시나 스냅샷 취득 후 실시 등, 평소 변경 작업과 같은 승인 프로세스에 올리는 것을 권합니다.
이벤트가 너무 많아 목적 행을 찾지 못합니다. 어떻게 좁히면 됩니까?
먼저 Process Name으로 대상 프로세스만 Include하고, 이어서 Result로 비정상 결과(NAME NOT FOUND, ACCESS DENIED 등)에 좁히는 것이 정석입니다. 목적 행이 하나 나오면 그 행을 오른쪽 클릭해 나타나는 Include나 Exclude로 대화형으로 좁혀 갑니다. 반대로 「필터를 건 채로 저장해서 정보가 부족했다」는 실패도 많으므로, 로그를 파일로 저장해 다른 사람에게 넘길 때는 필터가 어디까지나 표시상의 좁히기임을 의식하고 전체 이벤트를 저장하세요. 참고로 필터 설정은 다음 시작 시에도 이어지므로, 「아무것도 표시되지 않는다」면 이전의 오래된 필터가 남아 있지 않은지 Filter 메뉴의 Reset Filter로 확인하세요.
Result 열의 BUFFER OVERFLOW는 버그나 공격의 징후입니까?
아닙니다. 보안 용어의 버퍼 오버플로 공격과는 무관하며, 「호출 측이 준비한 버퍼보다 필요한 데이터가 커서 필요 크기를 돌려줬다」는 정상적인 API 왕복입니다. 많은 API는 먼저 작은 버퍼로 호출해 필요 크기를 알아낸 뒤, 다시 확보하고 재호출하는 설계이므로, 직후에 같은 경로로의 SUCCESS가 이어지면 문제 없습니다. 마찬가지로 NAME NOT FOUND도 「탐색 순서 도중에 찾지 못했다」인 경우가 많고, 최종적으로 어딘가에서 SUCCESS했다면 이상이 아닙니다. 비정상 Result는 「그 조작의 실패가 앱 증상과 인과로 이어지는지」까지 확인한 뒤에야 원인이라고 말할 수 있습니다.
Process Explorer와 Process Monitor는 어떻게 나눠 씁니까?
Process Monitor는 「조작의 흐름(언제·어느 프로세스가·어느 경로에·무엇을 해서·어떻게 되었는지)」을 시계열로 기록하는 도구이고, Process Explorer는 「지금 이 순간의 상태(어느 프로세스가 어느 파일이나 DLL을 열고 있는지, CPU·메모리 사용 상황)」를 보는 도구입니다. 예를 들어 「이 파일을 삭제할 수 없다. 누가 잡고 있는지」를 알고 싶다면 Process Explorer의 핸들 검색이 가장 빠르고, 「앱이 이 파일을 언제·어떤 순서로 읽는지」를 알고 싶다면 Process Monitor입니다. 실무에서는 둘 다 Sysinternals Suite로 상비해 두고, 상태는 Process Explorer, 이력은 Process Monitor라고 기억해 두면 헤매지 않습니다.

저자 프로필

기사 저자의 프로필 페이지입니다.

Go Komura

합동회사 코무라소프트 대표

Windows 소프트웨어 개발, 기술 상담, 장애 조사를 중심으로 재현이 어려운 장애 조사와 기존 자산이 남아 있는 프로젝트에 강점이 있습니다.

블로그 목록으로 돌아가기