Windows Debugging Technique #2

29
서서서 서서서 http://www.debuglab.com http://www.debuglab.com 서서서 서서서 ([email protected]) ([email protected]) Go to Debugging World #2 Go to Debugging World #2 - Native Debugging - Native Debugging

Transcript of Windows Debugging Technique #2

Page 1: Windows Debugging Technique #2

서우석서우석http://www.debuglab.comhttp://www.debuglab.com 운영자운영자([email protected])([email protected])

Go to Debugging World #2Go to Debugging World #2 - Native Debugging - Native Debugging

Page 2: Windows Debugging Technique #2

AgendaAgenda 버그 예방책버그 예방책 Native Debugging with VC++ 6Native Debugging with VC++ 6 Assembly Assembly 코드 보기코드 보기

Page 3: Windows Debugging Technique #2

누구를 위한 웹 캐스트인가누구를 위한 웹 캐스트인가 ?? Visual C++ 6.0 Visual C++ 6.0 디버거를 제대로 활용하고 디버거를 제대로 활용하고

싶은 개발자싶은 개발자 버그를 예방하는 방법에 대해서 고민하고 버그를 예방하는 방법에 대해서 고민하고

있는 개발자있는 개발자 Assembly Assembly 코드만 보면 디버그 창을 코드만 보면 디버그 창을

닫아버리는 개발자닫아버리는 개발자 AssemblyAssembly 의 의 ‘‘ A’A’ 자만 들어도 겁이 나는 자만 들어도 겁이 나는

개발자개발자

Page 4: Windows Debugging Technique #2

버그 예방책버그 예방책 디버깅을 잘하는 것보다 미리 예방하는 디버깅을 잘하는 것보다 미리 예방하는

것이 더 중요것이 더 중요 !! 소 잃고 외양간 고치기소 잃고 외양간 고치기 ??

버그 예방 버그 예방 = = 디버깅디버깅 ASSERT!ASSERT!

Page 5: Windows Debugging Technique #2

ASSERTASSERT 어설트의 대상이 되는 조건이 참이어야 함어설트의 대상이 되는 조건이 참이어야 함

거짓거짓 (FALSE)(FALSE) 이면 오류 발생이면 오류 발생 릴리즈 시에는 포함되지 않기 때문에릴리즈 시에는 포함되지 않기 때문에 , , 주로 주로

테스트를 위하여 사용테스트를 위하여 사용 문서화 역할도 수행문서화 역할도 수행

Page 6: Windows Debugging Technique #2

ASSERTASSERT 할 대상은 무엇할 대상은 무엇 ?? 가능한 모든 것가능한 모든 것 !! 프로그램을 작성하면서 가정하고 있는 프로그램을 작성하면서 가정하고 있는

사항들사항들 ““ 이 변수는 이 값을 가져야 해이 변수는 이 값을 가져야 해 .”.” ““ 이 식의 결과는 이 값을 가져야 해이 식의 결과는 이 값을 가져야 해 .”.” ““ 이 함수로 들어오는 매개 변수는 절대로 이 이 함수로 들어오는 매개 변수는 절대로 이

값을 가져서는 안돼값을 가져서는 안돼 .”.” 매개 변수로 들어오는 값매개 변수로 들어오는 값 , , 리턴 되는 값리턴 되는 값

Page 7: Windows Debugging Technique #2

ASSERT ASSERT 사용 시 주의 사항사용 시 주의 사항 Be a smart guy!Be a smart guy!

실패할 수 있는 모든 사항에 대하여 어설트를 실패할 수 있는 모든 사항에 대하여 어설트를 하지는 않는다하지는 않는다 .. 예예 ) ) 데이터베이스 연결이 실패했을 때마다 데이터베이스 연결이 실패했을 때마다

어설트가 실패하면 프로그램이 진행되지 않는다어설트가 실패하면 프로그램이 진행되지 않는다 .. 심각한 오류에 대해서만 어설트를 한다심각한 오류에 대해서만 어설트를 한다 ..

논리적인 상황에 대한 어설트는 별도의 논리적인 상황에 대한 어설트는 별도의 어설트 함수로 작성한다어설트 함수로 작성한다 .. 예예 ) AssertTableExist) AssertTableExist

Page 8: Windows Debugging Technique #2

ASSERT ASSERT 사용사용 Managed Managed 환경환경

Debug.Assert / Debug.TraceDebug.Assert / Debug.Trace Debug.Assert ( i > 3 )Debug.Assert ( i > 3 )

Native Native 환경환경 _ASSERTE / TRACE_ASSERTE / TRACE

ASSERT ( i > 3 )ASSERT ( i > 3 ) MFC MFC 환경환경

ASSERT_KINDOFASSERT_KINDOF Cobject::IsKindOf Cobject::IsKindOf 메서드의 래퍼메서드의 래퍼

ASSERT_VALIDASSERT_VALID 포인터가 포인터가 CObjectCObject 에서 파생된 클래스인지 에서 파생된 클래스인지

검증한다검증한다 ..

Page 9: Windows Debugging Technique #2

어설셜을 위한 헬퍼 함수들어설셜을 위한 헬퍼 함수들 IsBadCodePtrIsBadCodePtr

메모리 포인터를 실행할 수 있는지 검사한다메모리 포인터를 실행할 수 있는지 검사한다 .. IsBadReadPtrIsBadReadPtr

메모리 포인터가 특정한 바이트만큼 읽을 수 있는지 메모리 포인터가 특정한 바이트만큼 읽을 수 있는지 검사한다검사한다 ..

IsBadStringPtrIsBadStringPtr 문자열 포인터를 문자열 포인터를 null null 종결자가 나올 때까지 혹은 종결자가 나올 때까지 혹은

지정된 문자의 최대 수까지 읽을 수 있는 검사한다지정된 문자의 최대 수까지 읽을 수 있는 검사한다 .. IsBadWritePtrIsBadWritePtr

메모리 포인터에 지정된 바이트만큼 쓸 수 있는지 메모리 포인터에 지정된 바이트만큼 쓸 수 있는지 검사한다검사한다 ..

IsWindowIsWindow HWND HWND 매개 변수가 타당한 윈도우인지 검사한다매개 변수가 타당한 윈도우인지 검사한다 ..

Page 10: Windows Debugging Technique #2

Native DebuggingNative Debugging 기본적인 중단점 설정 방법기본적인 중단점 설정 방법 디버거 관련 창 사용 방법디버거 관련 창 사용 방법 고급 중단점 활용 방법고급 중단점 활용 방법

Page 11: Windows Debugging Technique #2

기본적인 디버깅 설정 방법기본적인 디버깅 설정 방법 중단점중단점 (BreakPoint)(BreakPoint)

프로그램의 실행을 중단시키기 위한 위치프로그램의 실행을 중단시키기 위한 위치 줄 단위로만 설정 가능줄 단위로만 설정 가능

VS .NETVS .NET 에서는 명령 별로 설정 가능에서는 명령 별로 설정 가능

중단점 설정중단점 설정 (F9)(F9) 버그가 발생되었다고 생각되는 부분 혹은 그 버그가 발생되었다고 생각되는 부분 혹은 그

주위에 중단점을 설정한다주위에 중단점을 설정한다 .. 중단점을 설정하기 전에 두뇌를 이용하여 중단점을 설정하기 전에 두뇌를 이용하여

중단점을 설정해야 하는 위치를 정확하게 중단점을 설정해야 하는 위치를 정확하게 파악하도록 한다파악하도록 한다 ..

Page 12: Windows Debugging Technique #2

디버깅 기본 기술디버깅 기본 기술 Step IntoStep Into

다른 루틴 호출 시 해당 루틴을 확인할 것인지 다른 루틴 호출 시 해당 루틴을 확인할 것인지 결정결정

Step OverStep Over 다른 루틴의 결과만을 확인할 것인지 결정다른 루틴의 결과만을 확인할 것인지 결정

Step OutStep Out 호출 스택에 있는 바로 이전 함수로 넘어감호출 스택에 있는 바로 이전 함수로 넘어감

Page 13: Windows Debugging Technique #2

디버거 관련 창 사용 방법 디버거 관련 창 사용 방법 - 1- 1 호출 스택호출 스택 (Call Stack) (Call Stack) 확인확인

문제가 발생한 함수를 호출한 함수 목록 확인문제가 발생한 함수를 호출한 함수 목록 확인 로컬로컬 (Local)(Local) 과 자동과 자동 (Auto) (Auto) 창 확인창 확인

문제가 발생한 위치에서 사용된 지역 변수들문제가 발생한 위치에서 사용된 지역 변수들 메모리메모리 (Memory)(Memory)

VC++ 6.0VC++ 6.0 에서는 오직 하나의 메모리 창만 에서는 오직 하나의 메모리 창만 지원지원

내가 정확히 알고 싶어하는 값이 무엇이며내가 정확히 알고 싶어하는 값이 무엇이며 , , 기대하는 값은 무엇인가를 명확하게 기대하는 값은 무엇인가를 명확하게 확인해야 한다확인해야 한다 ..

Page 14: Windows Debugging Technique #2

디버거 관련 창 사용 방법 디버거 관련 창 사용 방법 - 2- 2 조사식 창에서 지원하는 여러가지 조사식 창에서 지원하는 여러가지

형식기호형식기호 x, X : 16x, X : 16 진수진수

61541,x : 0x0000F06561541,x : 0x0000F065 c : c : 단일 문자단일 문자

0x0065,c : 101 ‘e’0x0065,c : 101 ‘e’ hr : HRESULT hr : HRESULT 또는 또는 Win32 Win32 오류 코드오류 코드

0x00000000,hr : S_OK0x00000000,hr : S_OK wc : Window wc : Window 클래스 플래그클래스 플래그

0x00000040,wc : WC_DEFAULTCHAR0x00000040,wc : WC_DEFAULTCHAR wm : Windows wm : Windows 메시지 번호메시지 번호

0x0010, wm : WM_CLOSE0x0010, wm : WM_CLOSE

Page 15: Windows Debugging Technique #2

Basic BPsBasic BPs

DemoDemo

Page 16: Windows Debugging Technique #2

디버깅 고급 기술 디버깅 고급 기술 - 1- 1 충돌 및 잘못된 연산으로 인한 오류의 충돌 및 잘못된 연산으로 인한 오류의

대부분은 대부분은 ‘‘ 포인터포인터’’ 의 사용으로 인한 오류의 사용으로 인한 오류 !! 메모리의 값이 변경될 때 중단점 활성화 메모리의 값이 변경될 때 중단점 활성화

방법방법 Breakpoints Breakpoints 창 실행창 실행 Data Data 탭에서 검사하고자 하는 메모리의 탭에서 검사하고자 하는 메모리의

주소나 변수 이름 입력주소나 변수 이름 입력 필요한 경우 필요한 경우 Advanced…Advanced… 에서 소스 코드와 에서 소스 코드와

함수 이름 입력함수 이름 입력

Page 17: Windows Debugging Technique #2

Data BPsData BPs

DemoDemo

Page 18: Windows Debugging Technique #2

디버깅 고급 기술 디버깅 고급 기술 - 2- 2 조건 중단점조건 중단점

조건이 맞을 때에만 중단점 활성화조건이 맞을 때에만 중단점 활성화 반복문에서 특히 유용반복문에서 특히 유용

내 프로젝트에서 로드하지 않은 내 프로젝트에서 로드하지 않은 DLLDLL 에 에 대해서도 직접 설정 가능대해서도 직접 설정 가능 {[function],[source file],[binary module]}{[function],[source file],[binary module]} Test.cpp Test.cpp 파일의 파일의 2020 번째 줄번째 줄

{,TEST.CPP,},20{,TEST.CPP,},20 참고참고

DLLDLL 이 이 exportexport 한 함수 목록 확인하기한 함수 목록 확인하기 Depends.exeDepends.exe Dumpbin /exportDumpbin /export

Page 19: Windows Debugging Technique #2

Conditional BPsConditional BPs

DemoDemo

Page 20: Windows Debugging Technique #2

Assembly Assembly 코드 보기코드 보기 x86 x86 아키텍처가 무엇인가아키텍처가 무엇인가 ?? 레지스터와 호출 규약레지스터와 호출 규약 플래그와 조건플래그와 조건 , , 데이터 형식데이터 형식 x86 x86 명령들명령들 x86 x86 디스어셈블리 예제디스어셈블리 예제

Page 21: Windows Debugging Technique #2

x86 x86 아키텍처가 무엇인가아키텍처가 무엇인가 ?? use complex instruction set computer use complex instruction set computer

(CISC) architecture(CISC) architecture modest number of special-purpose modest number of special-purpose

registersregisters Many peculiarities(Many peculiarities( 특성특성 ) in the x86 ) in the x86

instruction are due to the backward instruction are due to the backward compatibility with that processorcompatibility with that processor

Page 22: Windows Debugging Technique #2

레지스터와 호출 규약레지스터와 호출 규약 32bit registers32bit registers

eax : Accumulatoreax : Accumulator ebx : Base registerebx : Base register ecx : Count registerecx : Count register edx : Double-precision registeredx : Double-precision register esi : Source index registeresi : Source index register edi : Destination index registeredi : Destination index register ebp : Base pointer registerebp : Base pointer register esp : Stack pointeresp : Stack pointer

Non integer registersNon integer registers eip : instruction pointereip : instruction pointer flags : flagsflags : flags

Page 23: Windows Debugging Technique #2

레지스터와 호출 규약레지스터와 호출 규약

Page 24: Windows Debugging Technique #2

레지스터와 호출 규약레지스터와 호출 규약

Page 25: Windows Debugging Technique #2

레지스터와 호출 규약레지스터와 호출 규약 Calling conventionCalling convention

The register preservation rule is that functions must preserve all registers, The register preservation rule is that functions must preserve all registers, except for eax, ecx, and edx, which can be changed across a function call, except for eax, ecx, and edx, which can be changed across a function call, and esp, which must be updated. and esp, which must be updated.

The function return rule is that the eax register receives function return The function return rule is that the eax register receives function return values if the result is 32 bits or smaller. If the result is 64 bits, then the values if the result is 32 bits or smaller. If the result is 64 bits, then the result is stored in the edx:eax pair. result is stored in the edx:eax pair.

Win32 (Stdcall) : Function parameters are passed on the stack, pushed Win32 (Stdcall) : Function parameters are passed on the stack, pushed right to left, and the callee cleans the stack. right to left, and the callee cleans the stack.

Native C++ (Thiscall) : Function parameters are passed on the stack, Native C++ (Thiscall) : Function parameters are passed on the stack, pushed right to left, the "this" pointer is passed in the ecx register, and pushed right to left, the "this" pointer is passed in the ecx register, and the callee cleans the stack. the callee cleans the stack.

COM(Stdcall for C++) : Function parameters are passed on the stack, COM(Stdcall for C++) : Function parameters are passed on the stack, pushed right to left, then the "this" pointer is pushed on the stack, and pushed right to left, then the "this" pointer is pushed on the stack, and then the function is called. The callee cleans the stack. then the function is called. The callee cleans the stack.

Fastcall : The first two DWORD-or-smaller arguments are passed in the Fastcall : The first two DWORD-or-smaller arguments are passed in the ecx and edx registers. The remaining parameters are passed on the ecx and edx registers. The remaining parameters are passed on the stack, pushed right to left. The callee cleans the stack. stack, pushed right to left. The callee cleans the stack.

Cdecl : Function parameters are passed on the stack, pushed right to Cdecl : Function parameters are passed on the stack, pushed right to left, and the caller cleans the stack. The Cdecl calling convention is left, and the caller cleans the stack. The Cdecl calling convention is used for all functions with variable-length parameters. used for all functions with variable-length parameters.

Page 26: Windows Debugging Technique #2

플래그와 조건플래그와 조건 , , 데이터 형식데이터 형식 E, Z : If zero (or comparison equal)E, Z : If zero (or comparison equal) NE, NZ : If nonzero (or comparison unequal)NE, NZ : If nonzero (or comparison unequal) GE : If greater than or equal to zeroGE : If greater than or equal to zero LT, NGE : If less than zeroLT, NGE : If less than zero GT : If greater than zeroGT : If greater than zero LE, NGT : If less than zeroLE, NGT : If less than zero C : If carryC : If carry NC : If no carryNC : If no carry AE, NB : If above or equal (unsigned greater)AE, NB : If above or equal (unsigned greater) B, NAE : If below (unsigned less than)B, NAE : If below (unsigned less than) A, NBE : If above (unsigned greater or equal)A, NBE : If above (unsigned greater or equal) BE, NA : If below or equal (unsigned less than BE, NA : If below or equal (unsigned less than

or equal)or equal)

Page 27: Windows Debugging Technique #2

x86 x86 명령들명령들 LEA r, m : Load effective address. LEA r, m : Load effective address.

LEA eax, [esi+4] means eax = esi + 4.LEA eax, [esi+4] means eax = esi + 4. MOV r1/m, r2/m/#n : r1/m = r/m/#nMOV r1/m, r2/m/#n : r1/m = r/m/#n PUSH r/m/#n : Push value onto stack.PUSH r/m/#n : Push value onto stack. POP r/m : Pop value from stack.POP r/m : Pop value from stack. LEAVE : Tear down stack frameLEAVE : Tear down stack frame

mov esp, ebp mov esp, ebp pop ebp pop ebp

ADD, SUB, NEG, INC, DEC, CMP, MUL, IMUL, DIV, ADD, SUB, NEG, INC, DEC, CMP, MUL, IMUL, DIV, IDIVIDIV

AND, OR, XOR, NOT, TEST, SHL, SHR, SAR(sign-fill)AND, OR, XOR, NOT, TEST, SHL, SHR, SAR(sign-fill) JMP, CALL, RETJMP, CALL, RET NOP (0x90), INT 3 (0xCC)NOP (0x90), INT 3 (0xCC)

Page 28: Windows Debugging Technique #2

CallConventionCallConvention

DemoDemo

Page 29: Windows Debugging Technique #2

© 2004 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.