Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

포스트모템디버깅과 프로세스 덤프 실전

프로세스의 비정상적인 종료에 대처하는 방법에 대해서 설명을 합니다.

  • Identifiez-vous pour voir les commentaires

포스트모템디버깅과 프로세스 덤프 실전

  1. 1. 기술 내용 최종 문서 수정일 문서 작성자 MEMO 포스트 모템 디버깅 2010.10.03 포스트 모템 디버깅과 프로세스 덤프 실전
  2. 2. ● 목 차 2  본 프로젝트의 목표  포스트 모템 디버깅의 정의  프로세스 덤프 분석  예외 핸들러와 프로세스 덤프의 관계  Structued Exception Handler  덤프가 생성되지 않는 문제  예외 핸들러 모듈  결론  참조
  3. 3. ● 포스트 모템 디버깅 3  본 프로젝트의 목표  프로그램의 버그나 크래쉬는 프로그래머가 피해갈 수 있는 문제점 중의 하나임  이런 상황을 타개하기 위해서 포스트 모템 디버깅에 대해 알아볼 것임  또한 프로그램이 프로세스를 덤프를 남기는 과정을 알아보며 프로세스 덤프가 생기지 않는 경우를 고찰하여 이를 해 결할 수 있는 방안을 모색할 것임  최종적으로 현재 자주 쓰이는 검증된 예외 핸들러 모듈에 관해서 알아보며 이들의 성능과 한계에 대해서도 살펴본다. 또한 프로세스 덤프가 남지 않는 경우 반드시 덤프를 남길 수 있도록 처리하는 방법에 대해서 알아보며 검증된 예외 핸들러 모듈과 자신이 추가한 예외 처리를 융합하는 방법을 살펴본다.
  4. 4. ● 포스트 모템 디버깅 4  포스트 모템 디버깅이란  프로그래머가 작성한 프로그램은 QA과정과 디버깅을 통해서 검증을 마치고 최종적으로 고객에게 배포가 된다.  하지만 이렇게 검증을 마친 프로그램 또한 완전하지는 못하여 결함을 지니고 있는 경우가 많다.  프로그램이 배포가 되어 고객이 프로그램을 실행할 때 발생되는 결함, 즉 프로그램의 크래쉬는 대개 프로그램 개발 상황에서는 발생하지 않는 경우가 비일비재하다.  이렇게 최종 유저에게 배포가 된 상태에서 발생하는 버그에 관해서는 어떻게 해서 버그가 발생했는지에 대한 기록이 나 흔적을 남길 필요가 있다.  프로그램 개발 과정에서 버그나 문제를 잡는 것이 아니라 프로그램 배포후 프로그램의 비정상적인 문제점을 캐치하 여 프로그램을 수정하고 고치는 방법을 포스트모템 디버깅이라 한다.  포스트모템의 어원의 뜻 ‘사후검시’에서 알 수 있듯이 프로그램도 크래쉬가 났을 때 어떻게 해서 크래쉬가 발생했는 지 흔적을 남길 수 있다. 이런 흔적을 분석할 수 있는 메커니즘은 이미 운영체제 상에서 지원하고 있다.
  5. 5. ● 프로세스 덤프와 분석 5  프로세스 덤프란  프로세스의 특정 시점에서 레지스터의 값이나 메모리 값들을 그대로 저장한 파일을 의미한다.  프로세스 덤프는 살아있는 프로세스에서 얻을 수도 있으나 보통은 프로세스가 죽기직전의 상황의 상태를 저장하는 경우가 많다.  ProcDump  프로세스의 덤프를 생성하는 프로그램  프로그램에 Hang이 발생했거나 데드락이 걸렸을 경우 이 프로그램을 사용하면 매우 유용하다.  Link : http://technet.microsoft.com/ko-kr/sysinternals/dd996900(en-us).aspx  덤프의 분석  덤프파일은 X86 시스템하에서는 Visual Studio 와 WinDbg를 통하여 분석이 가능하다.
  6. 6. ● 프로세스 덤프와 분석 6  StackOverFlow 감지 스택오버플로우에 의해 프로그램이 죽었을 때 발생하는 덤프 파일 Visual Studio에서 덤프 파일을 분석하여 문제 발생 부분을 알려주고 있다. 소스코드가 있다면 소스코드에 매칭하여 프로그램이 죽기 직전의 상황을 자세히 보여준다. 똑같은 함수를 계속 호출하여 스택이 오버플로우가 난 상황을 정확히 보여주고 있다.
  7. 7. ● 예외 핸들러와 프로세스 덤프의 관계 7  예외 핸들러  X86에서는 프로그램에서 예외가 발생했을 경우 해당 프로그램에서 예외를 처리할 수 있는 기회를 부여해 준다.  프로그램에서는 이런 예외를 처리하기 위해 예외 핸들러를 구현해야 한다.  예외 핸들러가 구현되어 프로그램에서 문제가 발생되면 해당 예외 핸들러에서 예외를 처리하기 위한 루틴이 실행되 며 예외 처리가 구현되어 있지 않다면 디폴트 예외 핸들러로 제어를 옮기게 된다.  디폴트 예외 핸들러
  8. 8. ● 예외 핸들러와 프로세스 덤프의 관계 8  예외 핸들러에서 해야 될 일은…  예외 핸들러의 흐름을 탄다는 것은 프로세스에서 이상이 발생했다는 증거이다.  대부분의 경우 프로세스를 종료시키는 것이 시스템에 도움이 된다.  하지만 그냥 프로그램을 죽으면 프로세스가 어떤 이유로 문제가 발생했는지에 대한 원인 규명이 어렵게 된다.  예외 핸들러에서는 프로세스 덤프를 생성하는 루틴을 추가하여 프로그래머가 포스트 모템 디버깅이 가능할 수 있도 록 해야한다.  DbgHelp.dll  프로세스가 프로세스 덤프를 남길 수 있도록 도와주는 모듈  대부분의 예외 핸들러에서는 이 모듈의 API를 이용해서 덤프를 생성한다.
  9. 9. ● Structured Event Handler 9 X86 – Structured Event Handler Process - 미처리 예외 : 애플리케이션에 준비한 어떠한 예외 핸들러에서도 처리되지 않는 예외를 의미 - 미처리 예외의 경우 Windows에서 제공하는 기본 핸들러가 처리(디폴트 예외 핸들러) - UnhandledExceptionFilter Win32 API 예외발생 Windows가 디버 거에게 최초 디버 그 이벤트 전송 디버거 타입 이 시점에서 예외를 처리한다면 실행 중단 및 원인 분석 이 시점에서 예외를 처리하지 않는다면 ContinueDebugEvent API 호출 Windwos에 DBG_EXCEPTION_NOT_HANDLED를 보냄 Windows에서는 예외 핸들러를 검색해서 실행 어플리케이션에서 설치 한 예외 핸들러 실행 예외가 처리? 예 프로그램 계속 실행 또는 종료 아니오 Windows, UnhandledExceptionFilter 실행 디버그 상태? 예 강제종료 통지 대화상자 표시 디버그 버튼 클릭 실행 중단 및 원인 분석 프로그램 종료 예 아니오 아니오 디버거에 대상 프로세스 아이디 및 이벤트 객체를 넘기고 UnhandledExecptionFilter 실행 대기, 디버거가 디버기에 부 착 완료하면 이벤트 객체를 시그널 상태로 바꿈 UnhandledExecptionFilter 함수는 다시 디버거에 디버그 이 벤트 발송
  10. 10. ● 프로세스 덤프가 생성되지 않는 문제 10  프로세스 덤프가 생성되지 않는다!!!  게임서버가 갑자기 크래쉬 되었는데 어떤 이유로 프로그램이 죽었는지 알 수 없다면… 그 절망감은 서버 프로그래머 라면 크게 공감할 것이다.  보통 로그를 남겨서 프로그램이 죽는 상황을 유추할 수 있으나 가장 확실하게 원인을 파악할 수 있는 방법은 프로세 스 덤프를 분석하는 것이다.  그런데 어떤 경우 프로그램이 덤프를 남기지 않고 죽는 경우가 있다.  이렇게 덤프가 생기지 않는다면 문제의 원인을 고치지 못해 최악의 경우 프로그램 코드 전체를 리뷰할 상황이 생길 수도 있다.  프로세스 덤프는 반드시 남길 수 있도록 해야 한다.  분명 프로세스 덤프가 여러 요인에 의해 생성되지 않는 경우가 있을 수 있다.  하지만 덤프가 반드시 남아야 되는데 남지 않는 경우는 생기지 않도록 해야 한다. 프로세스 덤프가 남지 않는 상황을 고찰하고 그런 경우 덤프가 남을 수 있도록 방법을 강구해 보자
  11. 11. ● 프로세스 덤프가 생성되지 않는 문제 11  프로세스 덤프가 생성되지 않는 경우  Stack OverFlow  Pure Function Call  CRT(C RunTime) Error  Heap Damage(힙손상)  Out Of Memory  기타 원인들  위의 에러들은 덤프로 남기는 것이 가능한가?  다행히 덤프 남기는 것이 가능하며 몇 가지 작업을 해주어야 한다.
  12. 12. ● 프로세스 덤프가 생성되지 않는 문제 12 에러 타입 내 용 해결책 Stack OverFlow 스택이 오버플로우 난 상태이기 때문에 덤 프를 남길 때 스택을 사용하면 문제가 된다. 별도의 쓰레드를 생성하면 스택공간이 새로 생성 되므로 쓰레드를 생성하여 덤프를 남긴다. CRT Error 버퍼 오버 플로우 등 런타임 함수에 인자값 이 이상하게 넘어 올 때 예외를 일으키기 전에 자체적으로 해당 문제를 해결할 수 있 는 함수를 호출한다. 이런 경우 CRT 함수를 잘못 사용했을 때 호출되는 함수를 직접 구현에서 덤프를 남기도록 해야 한다. Out Of Memory 메모리가 부족하여 덤프를 남길 수 없는 상 황 덤프를 남길려고 하기 보다는 메모리를 사용하지 않고 콜스택 내용을 출력해서 어떤 부분에서 메모 리 할당이 이뤄지고 있는 지를 추적하는 방법이 좋 다. Pure Function Call 순수 가상 함수를 호출하는 경우. 프로그램 이나 컴파일러의 오류에 순수가상함수가 호출되는 상황이 발생한다. 순수가상함수 오류 관련 핸들러를 구현해서 덤프 를 남기도록 한다. 힙 손상 객체의 잘못된 타입 캐스팅을 통해 객체 메 모리 크기 이상의 힙영역에 접근하는 경우 어려운 문제임. 힙 손상이 일어나도 프로그램이 죽 지 않을 수 있기 때문.  각 유형별 에러와 해결책
  13. 13. ● 프로세스 덤프가 생성되지 않는 문제 13  프로세스 덤프 남기기 관련 근본적인 해결책  프로세스에 예외 핸들러를 추가하기 위해서 SetUnhandledFilter API를 사용한다.  그런데 앞의 표의 CRT Error 유형같은 경우 예외를 발생시키기 전에 관련 코드들이 자체 핸들러를 호출하고 우리의 예외 핸들러를 호출하지 않도록 함수 오버라이딩을 해버린다.(SetUnhandledFilter를 한번 더 호출하여 우리가 설정한 예외 핸들러 함수를 무효화 시키는 것임)  물론 특정 에러 관련 해당 핸들러를 직접 구현하면 좋겠지만 그 종류 또한 상당해서 모두 구현하는 것은 무리. - _set_invalid_parameter_handler, _set_purecall_handler  이런 상황에서는 무조건 우리가 설정한 예외 핸들러가 호출되도록 구현하는 것이 바람직하다.  어떻게 하면 우리가 설정한 예외 핸들러를 무조건 실행 가능하게 할 수 있을까?  우리의 예외 핸들러를 SetUnhandledFilter 함수를 호출해 세팅을 하고 이 함수를 후킹을 하던지 인라인 페칭을 통해서 어떠한 동작도 하지 않도록 구현한다면 우리의 예외 핸들러가 항상 실행됨을 보장받을 수 있을 것이다.  즉 다음에 SetUnhanledFilter 함수를 호출하는 상황을 만나도 아무런 작업을 하지 않기 때문에 우리가 설정한 예외 핸 들러는 유효하다. 따라서 운영체제로 부터 에러 보고를 받을 수 있는 것이다.
  14. 14. ● 예외 핸들러 모듈 14  EHModule  기존의 검증된 예외 핸들러 모듈과 자신의 커스터마이즈된 예외 처리 루틴을 융합하기 위해서 만든 모듈  검증된 모듈이라도 모든 예외 상황에 대처할수 없기 때문에 커스터마이즈된 예외 처리 루틴과 같이 사용하면 좋다  또는 여러 예외 핸들러 모듈 중 하나를 선택할 수도 있다.  EHModule에 포함된 예외 핸들러 모듈 리스트  버그 트랩 : 대표적으로 많이 사용하는 예외 핸들러  BreakPad : 구글에서 제공한 예외 핸들러 모듈.  StackWalker : 프로세스에서 문제가 발생했을 시 콜스택을 찍어 문제상황을 보여 준다.  MiniDump : 직접 DbgHelp 모듈에 있는 함수를 호출하여 미니 덤프를 생성한다.  BugTrapMix Handler : 버그트랩과 자신이 구현한 예외 핸들러 루틴 Mix  EHModule 기타사항  메모리 오버 플로우시 로그 남김  스택 오버플로우시 덤프 남기게 처리
  15. 15. ● 예외 핸들러 모듈 15  EHModule Test 콘솔 프로젝트로도 테스트 가능(더 정확함)
  16. 16. ● 예외 핸들러 모듈 16  EHModule에 포함된 각 모듈별 성능 비교 모듈 이름 StackOverflow OutOfMemory PureFunctionCall Heap Damage CRT Error 버그 트랩 X X O X O 브레이크 패드 O X O O O 미니덤프 핸들러 O O O O O 버그 트랩 Mix O O O O O 예외 핸들러 구동시 SetUnhandledFilter가 오버라이드 되지 않도록 처리
  17. 17. ● 예외 핸들러 모듈 17  EHModule에 포함된 BugTrap Mix Handler  프로그래머가 구현한 예외 핸들러와 버그트랩을 동시에 사용할 수 있도록 구현한 예외 모듈  최초 SetUnhandledFilter 함수 호출시 자신이 구현한 핸들러 등록  SetUnhandledFilter 함수 무효화 시킴  예외가 발생했을 때 예외가 자신이 등록한 핸들러가 처리할 수 있으면 처리하고 프로그램 종료  처리할 수 없는 항목이라면 SetUnhandledFilter 함수를 다시 원래대로 돌려 유효화 시킴  SetUnhandledFilter 함수를 호출하여 버그트랩을 예외 필터로 추가  소프트웨어 예외를 발생시킴(RaiseException)  이제 예외는 버그 트랩 핸들러로 제어를 옮기며 버그 트랩이 예외 처리를 함 검증된 예외 핸들러 모듈(버그트랩, 브레이크패드) 들을 더욱더 보강해서 포스트 모템 디버깅을 더 강화할 수 있다!!
  18. 18. ● 결 론 18  프로그래머에게 있어 디버깅은 프로그래밍의 50% 이상을 차지할 정도로 중요한 영역이며 디버깅 영역 중 포스트 모템(Post Mortem) 디버깅은 게임서버 운영에 있 어 필수적으로 익혀야 할 영역임  프로세스 덤프는 프로그램의 버그나 크래쉬 의 원인을 조사하기 위한 필수적인 자료임  프로세스 덤프가 남지 않는 예외는 수없이 많으며 이런 상황을 없애기 위해 몇가 지 작업을 해야 함을 알 수 있었다  검증된 예외 모듈과 자신의 예외 처리 핸들러를 융합하는 방식을 쓰면 보다 더 세 밀한 예외 처리를 구현할 수 있음을 알게 되었음
  19. 19. ● 참 조 19  Reference.txt 참조

×