• Save
프로그램은 왜 실패하는가 1장
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 1,305 views

Why Programs Fail

Why Programs Fail

Statistics

Views

Total Views
1,305
Views on SlideShare
1,303
Embed Views
2

Actions

Likes
0
Downloads
0
Comments
0

2 Embeds 2

http://www.parkpd.x-y.net 1
http://www.slideshare.net 1

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    프로그램은 왜 실패하는가 1장 프로그램은 왜 실패하는가 1장 Presentation Transcript

    • 프로그램은 왜 실패하는가?
      1. 실패는 어떻게 일어나는가?
    • 최초의 버그
    • 프로그램은 왜 실패하는가?
      프로그래머가 잘 못 짰기 때문이다
      나는 너가 열심히 할 거라고 믿지만, 동시에 너가 분명 몇 개의 결함(defect) 을 만들어 낼 거라고 믿는다
    • 버그는 없다
      개발자는 결함(defect) 를 만들어 내는 거지, 저절로 어딘가에서 벌레(버그)가 들어오는 건 아니다
      물론 내가 짠 코드가 아닌 다른 코드, 라이브러리, 머신에서 생긴 결함을 만나게 되면, 버그처럼 느껴질 것이다
      모든 결함을 다 해결할 수 있고, 결함은 하나도 없을 거라는 자만을 먼저 버려라
      항상 ‘만약 ~라면’ 을 준비해라
    • 용어 정리
      결함(defect) : 부정확한 프로그램 코드
      사람이 만든 것
      감염(infection) : 부정확한 프로그램 상태
      실패(failure) : 관찰 가능한 부정확한 프로그램 행동
      발생 : 결함 -> 감염-> 실패
      찾기 : 실패 -> 감염 -> 결함
    • 프로그램 실패 단계
      프로그래머가 결함(defect)을 만든다
      결함이 감염(infection)을 일으킨다
      감염이 퍼진다
      감염이 실패(failure)를 일으킨다
    • TRAFFIC
      Track the problem : 문제점 추적
      Reproduce : 실패 재현
      Automate : 자동화, 단순화
      Find Origins : 감염원 찾기
      Focus : 진짜 감염원에 집중
      Isolate : 감염 사슬 격리
      Correct : 결함 정정
    • 검사의 저주
      모든 결함이 실패를 만들지는 않는다
      시한폭탄이 들어있는 코드
      테스트는 에러가 있다는 것만 증명할 뿐, 에러가 없다는 건 증명하지 못한다
      데이크스트라. 1972
    • 디버깅
      온전과 감염을 분리한다
      무엇을 먼저 볼 것인가
      관련이 있는 것과 없는 것을 분리한다
    • 디버깅 기법
      단순화된 입력
      프로그램 슬라이스 – 7장
      상태 관찰
      상태 감시
      단언
      비정상
      인과 사슬
    • 디버깅 사례
      int_tmain(intargc,_TCHAR*argv[]){
      // ...
      CVideo*p1=CreateVideo(1);
      wcout<<p1->m_nId;
      // ...
      return0;
      }
    • 디버깅 사례
      classCVideo:publicCObj{
      public:
      CVideo(intnId):m_nId(nId){
      AddRef();
      }
      ~CVideo(){
      wcout<<L"CVideo destructor ";
      }
      intm_nId;
      vector<int>m_TestData;// new added member
      };
      int_tmain(intargc,_TCHAR*argv[]){
      // ...
      CVideo*p1=CreateVideo(1);
      wcout<<p1->m_nId;
      // ...
      return0;
      }
    • 디버깅 사례
      classCVideo:publicCObj{
      public:
      CVideo(intnId):m_nId(nId){
      AddRef();
      }
      ~CVideo(){
      wcout<<L"CVideo destructor ";
      }
      intm_nId;
      vector<int>m_TestData;// new added member
      };
      typedefCSmartPtr<CVideo>CVideoSP;
      CVideoSPCreateVideo(intnId){
      returnnewCVideo(nId);
      }
      int_tmain(intargc,_TCHAR*argv[]){
      // ...
      CVideo*p1=CreateVideo(1);
      wcout<<p1->m_nId;
      // ...
      return0;
      }
    • 디버깅 사례
      classCObj{
      public:
      CObj():m_nRef(0){}
      virtual~CObj(){}
      intAddRef(){return++m_nRef;}
      boolRelease(){
      --m_nRef;
      if(0==m_nRef){
      //return_to_pool(this); // reason 3
      deletethis;
      returntrue;
      }elseif(m_nRef<0){
      //_ASSERT_EXPR(0, L"over release!"); // reason 4
      }
      returnfalse;
      }
      staticvoid*operatornew(size_tsize){
      //void *p=allocate_from_pool(size);
      void*p=malloc(size);
      returnp;
      }
      staticvoidoperatordelete(void*p){
      //_ASSERT_EXPR(0, L"don't delete CObj");
      free(p);
      }
      intm_nRef;
      };
      template<typenameT>
      classCSmartPtr{
      public:
      typedefCSmartPtr<T>this_type;
      CSmartPtr():m_p(NULL){}
      //explicit CSmartPtr(T* p) : m_p(p) {}
      CSmartPtr(T*p):m_p(p){}// reason 1
      ~CSmartPtr(){
      if(m_p){
      m_p->Release();
      }
      }
      T&operator*()const{
      return*m_p;
      }
      T*operator->()const{
      returnm_p;
      }
      operatorT*(){// reason 2
      returnm_p;
      }
      private:
      T*m_p;
      };
    • 디버깅 사례
      Track the problem
      Crash 위치 확인(하지만 일정하지 않음)
      Reproduce
      정확한 재현방법 없음
      Automate
      R 가 해결 안 되면 A 는 할 수 없다
    • 디버깅 사례
      Find Origins
      Crash 중 CVideo 의 m_TestData 소멸자가 자주 보였다
      Focus : 진짜 감염원에 집중
      저번 업데이트와 비교해 봤더니 m_TestData 가 추가된 것 밖에 바뀐 게 없었다
      Isolate : 감염 사슬 격리
      m_TestData 를 주석처리했더니 crash 현상이 2시간마다 발생하던 것이 3일마다 발생했다
      STL 의 버그인가? 메모리 풀에 버그가 있는 걸까?
      여전히 crash 현상은 있고, CVideo 의 데이터가 이상한 값이 저장된다는 새로운 실패(failure)가 올라왔다
    • 디버깅 사례
      Find Origins
      이전 업데이트 code 와 전체 code 를 diff
      Focus : 진짜 감염원에 집중
      추가된 코드 중에서 의심가는 부분이 있긴 한데, 코드가 몇 천줄이 넘었다
      copy & paste 를 한 코드 같아서, 원본 코드와 새로 작성한 코드를 diff 해 보았다
      대부분의 코드가 거의 비슷한데, 한 라인에서 리턴값을 smartptr 에 저장하지 않고, raw pointer 에 저장하고 있었다
    • 디버깅 사례
      Correct : 결함 정정
      암묵적 변환을 막기 위해 explicit 추가
      했더니 500 군데가 넘는 코드를 변경해 줘야 했지만, 결국 했다
      return new CVideo(nId);-> return CVideoPtr(new CVideo(nid));
      m_nRef 가 0 미만이면 로그만 남기는 것이 아니라 개발자에게 이메일을 쏘도록 변경
    • 그 후 달라진 점
      1 주일마다 code review
      매주 금요일마다 스터디하던 거 다시 시작
      심각한 버그 정리 및 기록