20
프프프프프 프 프프 프프프 ? 10 프 프프프 프프 프프프

프로그램은 왜 실패 하는가

  • Upload
    -

  • View
    782

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 프로그램은 왜 실패 하는가

프로그램은 왜 실패 하는가 ?

10 장 기대의 단언

김홍준

Page 2: 프로그램은 왜 실패 하는가

기대의 단언

• 단언 : [ 명사 ] 주저하지 아니하고 딱 잘라 말함 .

• 관찰만 가지고는 디버깅이 힘들다 .

Page 3: 프로그램은 왜 실패 하는가

기대의 단언

• 단언 (assertion) 의 기법을 이용하여 비교를 자동화 하는 방법

Page 4: 프로그램은 왜 실패 하는가

장점

• 규모가변성–사람은 몇 개 vs 컴퓨터는 많이 많이 많이

• 지속성–한번 해두면 두고 두고 두고 두고–재사용성

Page 5: 프로그램은 왜 실패 하는가

단언

• 감염을 점검하는 코드를 프로그램에 삽입

if (divisor == 0) { printf("Division by zero!"); abort();}

Page 6: 프로그램은 왜 실패 하는가

단언assert (divisor != 0);

void assert (int x){ if (!x) { printf("Assertion failed!\n"); abort(); }}

$ my-programAssertion failed!Abort (core dumped)$

Page 7: 프로그램은 왜 실패 하는가

단언#ifndef NDEBUG#define assert(ex) \((ex) ? 1 : (cerr << __FILE__ << ":" <<

__LINE__ \ << ": assertion ‘" #ex "’ failed\n", \ abort(), 0))#else#define assert(x) ((void) 0)#endif

$ my-programdivide.c:37: assertion ‘divisor != 0’ failedAbort (core dumped)$ _

Page 8: 프로그램은 왜 실패 하는가

단언의 주요한 용도

• 자료의 무결성을 보장하는 자료 불변식

• 함수의 정확성을 보장하는 전제 조건과 사후조건

Page 9: 프로그램은 왜 실패 하는가

불변식 단언

• 수행 전체에서 반드시 성립해야 하는 성질

• 유효한 시간은 00:00:00~23:59:60

class Time {public: int hour(); // 0..23 int minutes(); // 0..59 int seconds(); // 0..60 (incl. leap seconds) void set_hour(int h); …}

Page 10: 프로그램은 왜 실패 하는가

불변식 단언• 객체의 불변식이 성립함에 따라 그 객체의 상태가 감염 되지

않았음을 보장

void Time::set_hour(int h){ assert (sane()); // 전제조건 … 실제 코드 assert (sane()); // 사후조건}

bool Time::sane(){ return (0 <= hour() && hour() <= 23) && (0 <= minutes() && minutes() <= 59) && (0 <= seconds() && seconds() <= 60);}

Page 11: 프로그램은 왜 실패 하는가

정확성의 단언

• 어떠한 함수가 일을 제대로 하는지 보장하는 것– 사후조건 : 함수의 끝에서 상태에 대해 반드시

성립해야 하는 조건

void Time::set_hour(int h){ // 실제코드 assert (hour() == h); }

Page 12: 프로그램은 왜 실패 하는가

정확성의 단언

–전제조건 : 함수의 시작에서 상태에 대해 성립해야 하는 조건

void Time::set_hour(int h){ assert (0 <= h && h <= 23); // 실제코드 }

Page 13: 프로그램은 왜 실패 하는가

정확성의 단언• Eiffel 언어

– 계약에 의한 설계• 호출자 ( 의뢰자 )• 함수 ( 제공자 )

set_hour (h: INTEGER) is -- h 로 시간을 설정 require sane_h: 0 <= h and h <= 23 ensure hour_set: hour = h minute_unchanged: minutes = old minutes second_unchanged: seconds = old seconds

Page 14: 프로그램은 왜 실패 하는가

명세로서의 단언

• 자연어“Set_hour(h) 는 현재 시간을 h 로 설정한다 여기서 h 는 0~23

범위의 정수”

– 읽기는 쉽우나 애매함

• 형식 시스템

z 명세

– 불변식 & 전제 /사후조건을 쉽게 파악

Page 15: 프로그램은 왜 실패 하는가

명세로서의 단언

• 두 접근 방법의 공통점–명세와 코드가 분리

• 일반적인 소프트웨어에서는 대다수의 실행들에서 단언들이 성립하는것으로 충분

Page 16: 프로그램은 왜 실패 하는가

단언에서 검증으로• JML(java modeling language) + 문서화 , 단위테스트 , 불변식 검출 , 정적

정검 , 검증

/*@ requires 0 <= h && h <= 23 @ ensures hours() == h && @ minutes() == \old(minutes()) && @ seconds() == \old(seconds()) @*/void Time::set_hour(int h) …

Page 17: 프로그램은 왜 실패 하는가

기준실행

• 기준 프로그램에 대해 프로그램을 점검하기 위해서 상대적 디버깅을 사용

• p1 이 p0 의 새버전 또는 변종인 경우

Page 18: 프로그램은 왜 실패 하는가

사례

• 파일 오픈 경로

FopenCFileDialogFopen ?

Page 19: 프로그램은 왜 실패 하는가

사례

• 원인CFileDialog 대화상자를 호출한 후 c:\\sample\\ 이동 ,OK 버튼을 눌렀다면 이제부터 작업 경로는c:\\work\\ 가 아니라 c:\\sample\\ 인 것입니다 . 

-_-……

Page 20: 프로그램은 왜 실패 하는가

사례• 해결char path[MAX_PATH] = {0}; // 현재의 작업경로를 얻어와 저장 한다 .GetCurrentDirectory(MAX_PATH, path);

CFileDialog dlg(FALSE);if(dlg.DoModal()==IDOK){ // 가장 마지막에 저장해 두었던 작업경로로 다시금 세팅한다 . SetCurrentDirectory(path); // 하고픈 작업코드 .....}