강연소개 exception handler 를통한 에러검출및수정 file강연소개– exception handler...

39
강연 소개 Exception Handler 를 통한 에러 검출 및 수정 디버깅을 즐겨 하십니까..? 에러를 만나면 반갑습니까..? 전화로 버그 보고를 받았나요..? 잡히지 않는 버그 !!!! 따분한 강의 졸아도 좋습니다 !!!!

Upload: others

Post on 06-Nov-2019

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

강연 소개 – Exception Handler 를 통한에러 검출 및 수정

디버깅을 즐겨 하십니까..?

에러를 만나면 반갑습니까..?

전화로 버그 보고를 받았나요..?

잡히지 않는 버그 !!!!

따분한 강의 – 졸아도 좋습니다 !!!!

Page 2: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

강연자 소개

테스터

온라인 게임 클라이언트 개발

로컬라이즈 및 해외지원 업무

디버깅, 최적화, 호환성 향상에 관심

Page 3: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

강연 대상

x86 환경에서 Windows 프로그래밍– 디버깅/에러 추적은 CPU/OS에 따라 다르다

– 소개할 기술은 x86/Windows 에서 사용됨.

C/C++, Assembler에 대한 구조적인 지식– Stack 이나 Register 등의 접근을 요구함

– Listing File 을 참고해야 하는 경우가 있다.

Page 4: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

디버깅의 난해함

작은 개발 팀에서의 프로그램 출시– 테스팅/QA 팀이 없거나 기술적으로 미숙함

– 부족한 시간에 따른 충분하지 못한 테스팅

에러에 대한 부족한 정보– 유저들에게 충실한 에러 보고를 요구 할 수 없다.

– 에러의 존재 유무조차 알 수 없는 경우도 많다.

온라인 서비스– 자주 출시되는 실행 파일로 테스트 부족

– 서비스 중단에 따른 금전적 손실

Page 5: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

C/C++ 버그의 대표적인 예

포인터, 포인터, 포인터 !!!– 기술적인 에러의 98% 는 포인터 문제다.

간혹 일어나는 divide by zero– 발생 확률이 적어서 디버깅이 더 어렵다.

Debug Code 에선 에러가 나지 않을 수 있다.– Release 로 컴파일 해서 디버깅은 가능하다.

방어적인 코딩으로는 해결되지 않는다.– 방어적인 코딩은 에러를 감출 뿐이다.

Page 6: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

SHE의 소개

SEH - Structured Exception Handling– Windows 에서 제공해주는 예외 처리 기능

– User Mode 에서의 S/W, H/W 예외의 처리

예외의 종류– STATUS_ACCESS_VIOLATION

– EXCEPTION_INT_DIVIDE_BY_ZERO

– 기타 에러는 GetExceptionCode() 함수 참고

Page 7: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

각종 예외 – Windows 98

Page 8: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

각종 예외 – Windows XP

Page 9: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

각종 예외 – 라그나로크

Page 10: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

SEH의 사용 - __try ~ __except

void main(){

int* p = 0x00000000; // pointer to NULLputs("hello");try{

puts("in try");try{

puts("in try");*p = 13; // causes an access violation exception;

}__finally{puts("in finally");

}}__except(puts("in filter"), 1){

puts("in except");}puts("world");

}

Page 11: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

SHE의 사용 -SetUnhandledExceptionFilter

LPTOP_LEVEL_EXCEPTION_FILTER

SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter );

– 기본 구조는 __try ~ __except 와 같음

– 미 설정시 윈도우의 오류 화면 출력

– __try ~ __except 가 준비되지 않은 코드에서 자동적으로 호출됨

Page 12: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

UnhandledExceptionFilter

LONG UnhandledExceptionFilter( STRUCT _EXCEPTION_POINTERS *ExceptionInfo );

typedef struct _EXCEPTION_POINTERS {

PEXCEPTION_RECORD ExceptionRecord;

PCONTEXT ContextRecord;

} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

– SetUnhandledExceptionFilter 의 인자

– 일반적인 CallBack 함수와 같은 형태

– ExceptionInfo에서 CONTEXT 정보를 얻을 수 있다.

Page 13: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

CONTEXT 란..?

Thread Context– CPU의 각종 레지스터 정보

– CPU 에 따라 다른 정보가 들어있을 수 있음

디버깅에서의 Thread Context– 실행중인 쓰레드의 정보를 알 수 있다.

– 메모리의 정보와 조합하여 프로그램의 실행 상태를 모두 파악할 수 있다.

Page 14: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

X86의 CONTEXT 구조체

typedef struct _CONTEXT {

DWORD ContextFlags;

DWORD Dr0;DWORD Dr1;DWORD Dr2;DWORD Dr3;DWORD Dr6;DWORD Dr7;

FLOATING_SAVE_AREA FloatSave;

DWORD SegGs;DWORD SegFs;DWORD SegEs;DWORD SegDs;

DWORD Edi;

DWORD Esi;

DWORD Ebx;

DWORD Edx;

DWORD Ecx;

DWORD Eax;

DWORD Ebp;

DWORD Eip;

DWORD SegCs; // MUST BE SANITIZED

DWORD EFlags; // MUST BE SANITIZED

DWORD Esp;

DWORD SegSs;

BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

Page 15: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

예제 프로그램 (1)

UnahdledExceptionFilter 예제

Page 16: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

ExceptionFilter 에서 정보를 얻자.

레지스터의 값에서 얻을 수 있는 정보– EIP 를 통한 현재 실행 명령의 주소

– ESP/EBP를 통한 Stack 의 범위/내용

– 범용 레지스터로 부터 현재 실행상태

메모리에서 얻을 수 있는 정보– ExceptionFilter도 같은 프로세스이다.

– ESP/EBP의 범위는 항상 유효하다.

– Static/Global 한 정보도 항상 유효하다.

Page 17: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

Debug Help Library 의 간단한 소개

Debug Help Library 의 기능– Symbol 의 접근 및 정보 제공

– MiniDump 의 접근 및 정보 제공

DbgHelp.dll 을 통해 제공– Windows 2000 이후에는 OS 기본 제공

– 프로그래머가 직접 배포할 수 있다.

Debugging Symbol – 컴파일시 함수명/변수명 정보가 기록

– Debug 모드에선 EXE 에 포함

Page 18: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

SymFromAddr

The SymFromAddr function retrieves symbol information for the specified address.

BOOL SymFromAddr(

HANDLE hProcess,

DWORD64 Address,

PDWORD64 Displacement,

PSYMBOL_INFO Symbol

);

Page 19: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

SymFromAddr (2)

실행중인 주소의 SYMBOL_INFO 를 읽어옴

CONTEXT 의 EIP 에 해당함

프로그램은 항상 같은 주소에서 실행된다.

SYMBOL_INFO 에서 클래스 함수나 현재 실행중인 함수를 얻어올 수 있다.

Page 20: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

SymGetLineFromAddr

The SymGetLineFromAddr function locates the source line for the specified address.

BOOL SymGetLineFromAddr(

HANDLE hProcess,

DWORD dwAddr,

PDWORD pdwDisplacement,

PIMAGEHLP_LINE Line );

Page 21: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

SymGetLineFromAddr (2)

실행중인 주소의 IMAGEHLP_LINE 을 읽어옴

CONTEXT의 EIP 에 해당함

IMAGEHLP_LINE 에서 에러가 발생한 소스코드의 파일명, 행수를 얻어올 수 있다.

Page 22: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

StackWalk

The StackWalk function provides a portable method for obtaining a stack trace.

BOOL StackWalk(

DWORD MachineType,

HANDLE hProcess,

HANDLE hThread,

LPSTACKFRAME StackFrame,

PVOID ContextRecord,

PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,

PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,

PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,

PTRANSLATE_ADDRESS_ROUTINE TranslateAddress );

Page 23: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

StackWalk (2)

Stack을 뒤져서 Return 주소를 찾아낸다.

계속해서 찾으면 CallStack이 된다.

CONTEXT의 EIP와 ESP/EBP로 찾는다.

Symbol 없을 경우 ESP/EBP를 기본으로 찾아간다.

Debugging Application 서적을 참고하자.

Page 24: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

Release 에서 PDB 만들기

Visual C++ 의 설정– Release 옵션에서 기본 설정으로 PDB 생성 않음

– Project Setting->Link->[Debug]->Debug Info

주의 사항– PDB는 실행파일과 같은 디렉토리나 Symbol 디렉

토리에 존재해야한다.

– Visual C++ 6.0 에서는 ‘Run’ 명령으로는 PDB를정상적으로 찾지 못한다.

Page 25: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

예제 프로그램 (2)

ExceptionFilter 를 통한 에러 로그 출력

Page 26: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

PDB의 배포와 문제점

PDB의 배포– 용량이 크다.

– 프로그램의 각종 세 한 정보가 들어 있다.

PDB가 없을 경우– Symbol이 없으므로 CallStack의 에러를 내용을

알 수 없다.

– 최적화된 경우 PDB 없이 StackWalk가 CallStack을 정상적으로 찾을 수 없다.

Page 27: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

Frame-Pointer

Frame-Pointer 란..?– 함수마다 Frame 정보를 Stack에 남긴다.

– Frame 정보는 EBP/ESP 정보들이다.

– Frame-Pointer-Omission 된 상태에서는FPO_DATA 데이터가 Symbol 에 저장된다.

Frame-Pointer 의 설정– 최적화시 Frame-Pointer-Omission이 된다.

– CL.EXE 컴파일러의 /Oy- 옵션으로 강제 설정

Page 28: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

PDB 없이 Exception 데이터 생성

실행파일 설정– 긱종 디버깅 정보를 남긴다.

– 실행파일은 FP를 함수에서 남기도록 설정

– Exception Filter 는 StackWalk로 CallStack의 주소만을 알아내서 로그로 남기게 된다.

Symbol Reader 제작– PDB를 뒤져서 CallStack의 정보를 읽을 수 있는

버전으로 해독한다.

Page 29: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

주의 사항 – Time Stamp, 실행파일 이름

여러 버전의 실행파일의 출시– TimeStamp를 찍는다.

– 유저의 시스템은 가능한 믿지 말자.

어느 실행파일의 에러인가..? – 여러 개의 실행파일을 출시하는 경우 실행파일 이

름이 없으면 어떤 에러인지 알 수 없다.

Page 30: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

예제 프로그램 (3)

PDB 없이 Exception 데이터 생성

PDB,EXE 파일로 CallStack 정보를 읽어내기

Page 31: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

Call Stack 으로 알아보기 힘든 버그

한줄에서 여러가지 작업을 하는 경우– Line을 알아도 에러를 특정할 수 없다.

최적화시에는 순서가 바뀔 수 있다.– 최적화가 되어 있을 경우 실행 순서가 바뀐다.

– PDB에 잘못된 행수가 적힐 수 있다.

포인터 에러는 구분하기 힘들 수 있다.– 포인터의 포인터 연산

– 포인터가 한줄에 여러 개 있다.

Page 32: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

Listing File 의 생성 및 사용

Listing File 이란..?– C/C++의 컴파일 결과물을 보여주는 텍스트 파일

– Source Code/Assembler/Machine Code

Listing File 의 생성– Project Settings->C/C++->Listing Files

Listing File의 용도– SymFromAddr의 Displacement로 에러 확인

– 에러 추적을 위해서 Assembler 지식이 필요함

Page 33: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

Memory Dump의 유용성

Memory Dump 란..?– ESP가 가르키는 Stack의 일정 영역을 기록

– 프로그래머가 미리 지정한 특정 주소를 기록

Memory Dump 의 사용법– Stack의 내용은 Listing File 참조

– Listing File에 어셈블러 코드만으로 디버깅이 안될때 사용한다.

Page 34: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

예제 프로그램 (4)

Listing 파일에서 에러 찾기

메모리 덤프 참고하기

Page 35: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

CallStack 이 비정상적으로 보이는 경우

Template– Symbol 정보가 정상적으로 남아있지 않는 경우

– iterator 가 end를 넘어간 경우

inline 된 함수들의 디버깅– inline은 호출 함수에 녹아들어간다.

– CallStack은 inline의 위치만 표시한다.

NULL Function Pointer 의 호출– StackWalk가 비정상적인 작동

Page 36: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

디버깅이 매우 힘든 에러

다른 Thread 에서 에러– DirectX 내부에서 호출되는 에러가 검출된다.

– 멀티 쓰레드의 경우 해당 Thread 정보만 남는다.

ExceptionFilter 에 걸리지 않는 종료– Windows NT 계열에서 발생

– Handle을 너무 많이 쓰거나 지속적으로 증가시발생하는 경우가 많음.

– 에러 추적이 매우 어려움

Page 37: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

비정상적인 Data, System 문제도 고려한다

일어날 수 없는 에러– 0.000001%의 에러도 있다.

– 프로그램에서 절대 발생할 수 없는가..?

– 일단 지나가자 !!!

데이터에는 문제가 없는가..?– 데이터의 의존하는 코드의 문제

– 각종 유저 데이터도 확인한다.

Page 38: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

에러는 어떻게 모을 것인가..?

유저들의 직접 전달에 의한 접수

네트워크를 통한 간단한 툴을 제작

모두 자동화 시킨다.

Page 39: 강연소개 Exception Handler 를통한 에러검출및수정 file강연소개– Exception Handler 를통한 에러검출및수정 z디버깅을즐겨하십니까..? z에러를만나면반갑습니까..?

질문 / 답변 받기