빛나는 인생ღ

반응형


[CASE 1] 잘못된 메모리 사용

대부분의 경우 응용프로그램이 메모리를 잘못 사용해 문제가 발생한다.


[그림1] 응용프로그램 오류 예시. 아래의 3번 사례에 가깝다

응용프로그램오류


 1. 프로그램에서 문자열 등에 할당한 버퍼 길이보다 더 많은 메모리 사용할 때

 2. 할당한 메모리 길이 보다 긴 길이의 문자열을 복사할 때

 3. 잘못된 포인터 계산으로 잘못된 메모리 사용할 때

 4. 잘못 만들어진 프로그램/소스코드에서 잘못된 메모리를 지시하여 원치 않은 동작이 발생할 때

 5. 메모리 할당하고 해제 했으나 해당 해제된 메모리를 그대로 사용하는 소스코드 (보통 개발자 실수)

 ※ 도움될 만한 툴 : GFlags.exe, Windbg

 - Windbg를 통해 원인 모듈까지 찾을 수 있지만 심볼을 설정해야 해당 함수 사용하는 소스 코드까지 확인 가능함

 

[CASE 2] 특정 프로세스의 CPU 사용률 100% 기록

하나의 스레드로 이뤄진 프로그램이라면 바로 확인 가능하나

멀티 스레드로 이뤄진 프로그램이라면 어떤 스레드가 CPU 자원 소모하고 있는지 파악하기 힘들다.

 ※ 도움될 만한 툴 : Process Explorer, Perfmon, Windbg


1. Process Explorer 사용

 - 항상 CPU 자원 소모하는 주기가 일정할 경우 Process Explorer가 유용함

 - Process Explorer를 통해 스레드 정보 / 스레드 스택 정보 확인 가능

  프로세스에서 CPU 자원 소모하는 스레드와 함수 찾을 수 있음

 - 심볼이 없는 경우 어떤 스레드인지는 확인 가능하나 어떤 함수인지 확인까지는 어려울 수 있다.

 - 심볼이 있다면 : Options > Configure Symbols 경로에서 심볼 위치 지정하여 분석

 

2. Perfmon (성능 모니터) 사용

 - CPU 과다 사용이 간헐적으로발생할 경우

 - 시작 > 실행 > Perfmon.exe 실행

 - 데이터 수집기 집합 > 사용자 정의 > 새로 만들기 > 템플릿으로부터 만들기 > 수동으로 만들기 > 카운터 추가 > Thread > % User Time > 확인 / 마침

  

성능모니터성능모니터


 - 각 스레드의 장기적인 사용 추이 확인

 

3. Windbg 사용

 - 문제 발생하는 Process 확인 > Windbg 실행 > Attach to a Process 메뉴로 Process 붙이기  

windbg

 - 모든 스레드 스택 보기 (~*kb 명령어)

 (ex) 스레드 中 USER32!NtUserGetMessage 함수 실행하는 스레드는 메인 사용자 인터페이스위한 스레드

    Sleep 함수를 호출하는 경우는 정상적인 제어를 갖고 있는 스레드

 - 만약 5번 스레드를 더 자세히 봐야할 경우 >> ~5s 명령어 입력

 

[CASE 3] Deadlock 발생해 멈춘 경우

멀티스레드 프로그램의 데드락의 경우 Windbg를 통해 파악 가능

 - 작업관리자에서 응답 없음 떨어져 있는 프로세스는 보통 데드락 발생 상태

작업관리자


 - Windbg 실행 > 프로세스에서 동작 중인 스레드의 스택 정보를 모두 출력 > 데드락에 빠진 스레드가 어떤 동기화 객체를 기다리고 있는지 확인 > 해당 동기화 객체 소유하고 있는 스레드 정보 확인 + 스레드 스택 확인하여 동기화 객체를 풀어주지 않는 이유 확인

 - 응답 없음 상태 프로세스를 Windbg 사용해 붙이고 ~*k 명령어로 콜스택 확인

  (ex) 

     kernel32!WaitForSIngleObject 함수가 발견되면 높은 확률. 해당 함수가 어떤 핸들을 기다리고 있는지

       해당 함수가 띄워진 스택의 핸들 정보 확인 후 !handle xxxx 명령어로 확인

    ღ 소스 코드가 확인이 된다면 해당 핸들이 특정 이벤트를 기다리고 있는 것을 확인할 수 있다.

    ღ 이 단계까지 오면 Process Explorer를 통해 해당 이벤트 이름 검색하여 어떤 프로세스가 그 이벤트를 소유하고 있는지 확인 가능함

 

[CASE 4] 핸들 누수

 - Windows 환경에서 파일 열기 : CreateFile() 함수 호출 > 핸들 획득 > 핸들에 사용하는 API 호출 > 사용 마친 후 CloseHandle() 함수를 통해 핸들을 닫음

 - 응용프로그램의 오동작 혹은 버그로 핸들을 닫지 않는 경우 핸들 누수가 발생 

   → 시스템은 닫지 않은 핸들을 관리하기 위해 정보를 커널 메모리에 지속 유지 

   → 시스템 동작에 영향 (메모리 부족 등)


1. 작업관리자로 누수 확인

  - 작업 관리자 통해 핸들 개수 확인 가능 (세부정보 > 열 선택 > 핸들)

  - 핸들 개수는 확인 가능하나 어떤 핸들을 사용하고 있는지, 문제가 있는지(증가하고 있는지) 확인은 어려움


2. 성능 모니터로 누수 확인

  - Perfmon 통해 Process 성능 개체의 Handle Count 값 추가해서 핸들 값 변화 추이 확인 가능


3. Process Explorer로 누수 확인

 - View > Slow Lower Pane > Handle 선택 (혹은 Ctrl + H)

  - 어떤 핸들이 생성되어 있는지는 확인 가능. 어떤 함수를 통해 핸들 생성됐는지 알 수 없음

  - 결국은 작업관리자와 동일하게 추이까지는 확인이 어려움


4. Windbg로 누수 확인

  - !Handle, !htrace 명령어로 핸들 정보 확인

  - 핸들 시점의 콜스택 정보 확인 가능

  - 핸들 누수 의심 프로그램 (Perfmon으로 특정 가능) > Windbg에 붙이기 > !htrace - enable 명령으로 핸들 생성 함수가 무엇인지 콜스택 저장

  - 핸들 누수 의심 동작 시나리오가 있다면 

    → 시나리오 실행 전 !htrace -snapshot 명령어 수행하여 현재 핸들 정보 저장 

    → 핸들 누수 의심 동작 수행 

    → !htrace -diff 명령 실행 

    → 스냅샷 설정부터 !htrace -diff 명령어 전까지 열리고 닫힌 모든 핸들 정보 확인 가능

       (프로세스, 스레드 정보와 함께 콜스택 출력되어 어떤 함수 경로 통해 핸들이 열리고 닫히는지 확인 가능)

 

[CASE 5] 메모리 누수 (Memory Leak)

 - 메모리 사용 후에는 반드시 해제해줘야 한다.

 - 메모리 사용량이 계속 증가하면 프로그래머 실수로 메모리 해제하지 않은 “Memory Leak” 의심

  ※ 32bit Application 가상 메모리 공간은 최대 2GB (커널 메모리가 2G 차지하기 때문에 4G는 아님)

   64bit Application 가상 메모리 공간은 최대 8TB 

     → Out of Memory까지는 잘 뜨지 않지만 퍼포먼스에 영향 줄 수 있다.

  

1. 작업 관리자로 누수 확인

 - Working Set : 해당 프로세스가 사용하는 물리 메모리의 양

 - 특정 프로세스가 과도한 메모리를 사용하는 것을 의심한다면 커밋 크기를 확인


2. 성능 모니터로 누수 확인

 - 장기간 누수가 발생하나 어떤 프로세스인지 특정하지 못한 경우 성능모니터를 사용

 - Process 성능 개체의 Private Byte 를 모든 프로세스에 설정해 메모리 사용 증가량 확인

 - 지속적으로 메모리 증가 그래프가 확인된다면 프로그램 제작사나 개발자가 문제 확인해야함

 

 

3. 재현 시나리오가 있는 경우 : UMDH(User Mode Dump Heap)로 확인

 - CMD > GFlags -i 프로세스명 +ust 로 유저모드 스택 추적 설정

 - 재현 전에 콜스택 별 메모리 할당량 미리 기록

   Umdh -pn:프로세스ID > c:\before.txt

 - N회 재현 (재현 숫자는 경험치에 맡김. 보통 4~5, 많으면 10)

 - 재현 후 콜스택 별 메모리 할당량 다시 기록

   Umdh -pn:프로세스ID > c:\after_N.txt

 - Before / After 정보 차이점 확인

   Umdh c:\before.txt c:\after_N.txt > c:\diff.txt


반응형

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band