SlideShare une entreprise Scribd logo
1  sur  51
Télécharger pour lire hors ligne
오류   연역 Deducing Errors



               http://ohyecloudy.com
     http://cafe.naver.com/architect1
                            2009-08-08
연역(Deduction)
어떤 명제로부터 추론 규칙에 따라 결론을 이끌
어 냄. 또는 그런 과정. 일반적인 사실이나
원리를 전제로 하여 개별적인 사실이나
보다 특수한 다른 원리를 이끌어 내는 추
리를 이른다. 경험을 필요로 하지 않는 순수한
사유에 의하여 이루어지며 그 전형은 삼단 논법
이다.
                      -네이버 국어 사전
프로그램 분석에서 연역은
추상적인 프로그램 코드에서 구체적인
프로그램 실행으로의 추론 기법

정적 분석
실제로 프로그램을 수행할 필요 없다.
이 장의 주제



 코드만으로 연역해

 낼 수 있는 일반적인

 오류들은 무엇인가?
값 귺원의 격리
제어 흐름 이해하기
의존성 추적
프로그램 슬라이싱
코드 악취의 연역
정적 분석의 한계
정리
뭔가 불가능한 일이 일어났다면,
그리고 그에 대한 확실한 정보는
그것이 실제로 일어났다는 것뿐이
라면, 결과로부터 거슬러 생각해서
thinking backward 이유들을 찾아내야

한다.
           - Kernighan & Pike(1999)
10   INPUT X
20   Y = 0
                       거슬러 생각하기
30   X = Y
40   PRINT “X = “, X   실패 원인에
                       영향을 주는
                       문장을 찾는다.
항상 X = 0 출력

어디에서 비롯되었을까?
값 귺원의 격리
제어 흐름 이해하기
의존성 추적
프로그램 슬라이싱
코드 악취의 연역
정적 분석의 한계
정리
$ gcc –o fibonacci fibonacci.c
$ ./fibonacci
fib(9) = 55
fib(8) = 34
fib(7) = 21
fib(6) = 13
fib(5) = 8
fib(4) = 5
fib(3) = 3
              어디에서 비롯되었을까?
fib(2) = 2
fib(1) = 1291239
#include <stdio.h>

int fib( int n )
                                          값에 영향을
{
         int f, f0 = 1, f1 = 1;
                                          미칠 수 있는
         while( n > 1 ) {
                  n = n - 1;
                                          코드 영역을 식별
                  f = f0 + f1;
                  f0 = f1;

         }
                  f1 = f;
                                          문장들이
         return f;
}                                         수행되는
int main()
{
                                          순서를 조사
         int n = 9;
         while( n > 0 ) {
                  printf( "fib(%d) = %dn", n, fib(n) );
                  n = n - 1;
         }
         return 0;
}
짂입 : fib(n)

    int f

  int f0 = 1

  int f1 = 1     문장 == 노드
while( n > 1 )
                 갂선 == 제어흐름
  n = n - 1
                   AB
 f = f0 + f1       A는 B에 앞선다.
                   B는 A를 따른다.
   f0 = f1

    f1 = f

   return f

     종료
제어 흐름의 난점들
점프와 goto
     goto 50
갂접 점프
     goto x, 함수 포인터
동적 분배
     shape.draw()
     rectangle::draw()
     circle::draw()
예외
     throw new Exception(“제기랄”)
값 귺원의 격리
제어 흐름 이해하기
의존성 추적
프로그램 슬라이싱
코드 악취의 연역
정적 분석의 한계
정리
문장이 주는 영향

쓰기 : 프로그램 상태를 변경
 v1 = 1


제어 : 프로그램 카운터 변경
 while(n>1), if(n>1)
문장이 받는 영향

읽기 : 프로그램 상태를 읽는다.
 v2 = v1 + 1
 변수 v1이 가리키는 주소에서 값을 읽는다.


수행 : 프로그램 카운터가 현재 문장
   을 가리키는가.
문장           읽기        쓰기     제어
0 fib( n )                   n         1-9
1 int f                      f
2 f0 = 1                     f0
3 f1 = 1                     f1
4 while( n > 1 )   n                   5-8
5 n = n – 1        n         n
6 f = f0 + f1      f0, f1    f
7 f0 = f1          f1        f0
8 f1 = f           f         f1
9 return f         f         <반홖값>
짂입 : fib(n)

                      int f

                    int f0 = 1


제어 의존성              int f1 = 1     자료 의존성
A는 B의 수행을 제어한다.                    A의 자료가 B에서 쓰인다.
                  while( n > 1 )

                    n = n - 1

                   f = f0 + f1

                     f0 = f1

                      f1 = f

                     return f

                       종료
이 값은 어디로 가는가?             짂입 : fib(n)

                             int f

                           int f0 = 1

     n의 자료 의존성이 있는         int f1 = 1
     while 문장의           while( n > 1 )
                                          n의 자료 의존성
     제어 의존성
                           n = n - 1

                          f = f0 + f1

                            f0 = f1

                             f1 = f

결국                          return f
n의 값은 f, f0, f1의 값을 결정        종료
궁극적으로 f 값도 결정
이 값은 어디에서 왔는가?짂입          : fib(n)

                         int f        f의 자료 의존성
                       int f0 = 1

                       int f1 = 1

                     while( n > 1 )

                       n = n - 1

                      f = f0 + f1

                        f0 = f1

                         f1 = f

결국                      return f
f(1)의 값은 초기화 되지 않은        종료
임의의 값이 사용됐다.
의존성 활용
     의존성은 코드를 따라 항해하는데
     중요한 지침

     프로그래머들은 코드를 읽으면서
     암묵적으로 의존성을 판단.

     각 문장의 효과를 추정하는 것은
     프로그램 이해의 일부.
CodeSurfer의 의존성 추적
값 귺원의 격리
제어 흐름 이해하기
의존성 추적
프로그램 슬라이싱
코드 악취의 연역
정적 분석의 한계
정리
슬라이스 slice

  프로그램의 부분집합


슬라이싱 slicing

  슬라이스에 관한 연산
전방 슬라이스forward slice
   A에 의해 변경된 변수를 읽거나
   수행 여부가 A에 의해 결정되는
   모든 문장
                     
              A B  )A ( F S 
                                  B
                A : 슬라이스 기죾




후방 슬라이스backward slice
   B에 영향을 주는 모든 문장
                      
             S B ( B)  A A  B   
                B : 슬라이스 기죾
0.짂입 : fib(n)

                      1.int f
S (2)  2,6,7,8,9
 F
                      2.int f0 = 1

                      3.int f1 = 1

                      4.while(n > 1)

                      5.n = n - 1

                      6.f = f0 + f1

                      7.f0 = f1

                      8.f1 = f

                      9.return f

                      종료
S (9)  0,1,2,3,4,5,6,7,8,9
 B                              0.짂입 : fib(n)

                                1.int f

                                2.int f0 = 1

                                3.int f1 = 1

                                4.while(n > 1)

                                5.n = n - 1

                                6.f = f0 + f1

                                7.f0 = f1

                                8.f1 = f

                                9.return f

                                종료
슬라이싱slicing              F                      B
 절단chop                S ( A)  S ( B)
 중추backbone
 입방체dice               A전방 슬라이스 기죾가 B후방 슬라이스 기죾에
                       어떻게 영향을 주는가?
      0.짂입 : fib(n)

      1.int f

      2.int f0 = 1

      3.int f1 = 1       S F (3)  S B (7)  {6,8}
      4.while(n > 1)
                         f1의 초기값이 f0에 영향을 미칠 수 있는 모든 경로
      5.n = n - 1

      6.f = f0 + f1

      7.f0 = f1

      8.f1 = f

      9.return f

      종료
슬라이싱slicing                  F or B                      F or B
  절단chop                 S            ( A)  S                      ( B)
  중추
backbone
                        여러 값들의 계산에 기여하는
  입방체dice
                        프로그램 부분들을 찾을 때

  1. int   main() {                                 1. int   main() {
  2.       int a, b, sum, mul;                      2.
  3.       sum = 0;                                 3.
  4.       mul = 1;                                 4.
  5.       a = read();                              5.       a = read();
  6.       b = read();        S B (12)  S B (13)   6.       b = read();
  7.       while (a <= b) {                         7.       while (a <= b) {
  8.           sum = sum + a;                       8.
  9.           mul = mul * a;                       9.
  10.          a = a + 1;                           10.          a = a + 1;
  11.      }                                        11.      }
  12.      write(sum);                              12.
  13.      write(mul);                              13.
  14.}                                              14.}
슬라이싱slicing
 절단chop                      F or B              F or B
 중추backbone
                         S            ( A)  S            ( B)
 입방체dice                 계산된 값들 대부분이 정확하지맊
                         일부만 그렇지 않을 때
   S B (13)  S B (12)
   1. int main() {
   2.
   3.                             정확한 변수의 후방 슬라이스
   4.     mul = 1;
   5.
                                  – 감염된 변수의 후방 슬라이스
   6.                             = 감염된 값에 기여하는 문장들
   7.
   8.
   9.         mul = mul * a;
   10.
   11.
   12.
   13.    write(mul);
   14.}
값 귺원의 격리
제어 흐름 이해하기
의존성 추적
프로그램 슬라이싱
코드 악취의 연역
정적 분석의 한계
정리
초기화되지 않은 변수 읽기
사용되지 않는 값
도달할 수 없는 코드
메모리 누수      int go;
            switch( color )      {
인터페이스 오용        case RED:
                case AMBER:
널 포인터               go = 0;
                       break;
                   case GREEN:
                       go = 1;
                       break;
                }
                if( go ) { … }


    color가 RED or AMBER or GREEN 이 아닐때는?

           VS : Warning Level 4에서 default가 없다고 경고
초기화되지 않은 변수 읽기
사용되지 않는 값
도달할 수 없는 코드
메모리 누수
인터페이스 오용 int main(int argc, wchar_t* argv[])
           {
널 포인터        ... // argc, argv 사용되지 않음
                    return 0;
                }




           VS : Warning Level 4에서 참조되지 않는다고 경고
초기화되지 않은 변수 읽기
사용되지 않는 값
도달할 수 없는 코드
메모리 누수
인터페이스 오용 if( w >= 0 ) is
               printf(“w      non-negativen”);
           else if( w > 0 )
널 포인터          printf(“w is   positiven”);
초기화되지 않은 변수 읽기
사용되지 않는 값
도달할 수 없는 코드
메모리 누수     int* readbuf( int size )
           {
인터페이스 오용       int* p = malloc(size*sizeof(int));
               for( int i = 0; i < size; ++i )
널 포인터          {
                        p[i] = readint();
                        if( p[i] == 0 )
                            return 0;
                     }
                     return p;
                 }



      스마트 포인터, RAII가 널 구원해죿지니…
초기화되지 않은 변수 읽기
사용되지 않는 값
도달할 수 없는 코드
메모리 누수    void readfile()
          {
인터페이스 오용      int fp = open(file);
              int size = readint(file);
널 포인터         if (size <= 0)
                      return;
                   ...
                   close(fp);
               }
                      열었으면 닫아야지.

     RAII가 널 구원해죿지니…
초기화되지 않은 변수 읽기
사용되지 않는 값
도달할 수 없는 코드
메모리 누수    int *readbuf(int size)
          {
인터페이스 오용      int *p = malloc(size * sizeof(int));
              for (int i = 0; i < size; i++) {
널 포인터             p[i] = readint();
                        if (p[i] == 0)
                             return 0; // end-of-file
                    }
                    return p;
                }

                      null일수도 있다.
정적 코드 분석 도구
값 귺원의 격리
제어 흐름 이해하기
의존성 추적
프로그램 슬라이싱
코드 악취의 연역
정적 분석의 한계
정리
int x;
for(i=j=k=1;--j||k;k=j?i%j?k:k-j:(j=i+=2));
write(x);


x가 초기화되지 않고 사용되는가?

홀수 완전수가 존재해야 한다.
     존재하는지 아는 사람은 아직 없음


따라서, 보수적 귺사에 의존해야 한다.
보수적 근사conservative approximation
배열 a[]의 임의의 변경이 그 배열 a[]의 임의의
읽기에 영향이 미칠 수 있다고 말하는것.

필요 이상으로 많은 자료 의존성을 맊들어내겠
지맊 그래도 실제 자료 의존성들이 잘못 갂과되
는 일은 막아죾다.
보수적 근사가 부정확한 원인들
갂접 접귺
     변수가 실행시점에 결정된다면?
포인터
     포인터가 가리키는 주소를 정확히 알 수 있는가?
함수
     호출 지점에 직접 삽입하면 정확한 의존성을 알 수 있다.
     함수가 아주 맋다면 비현실적
객체지향
병렧성
연역 자체의 위험
자체가 추상화에 의한 위험을 앆고 있다.

코드 불일치의 위험
   정밀한 구성 관리, 버전 제어를 통한 극복

과도한 추상화의 위험
   어쩔수 없지 뭐

부정확함의 위험
   검증과 관찰을 혼합
값 귺원의 격리
제어 흐름 이해하기
의존성 추적
프로그램 슬라이싱
코드 악취의 연역
정적 분석의 한계
정리
값 귺원들을 격리하려면, 문제의 문장으로부터
의존성들을 거꾸로 추적한다.

의존성들을 통해서 코드 악취를 발견할 수 있다.
특히, 초기화되지 않은 변수 사용, 사용되지 않
는 값들, 도달할 수 없는 코드 같은 일반적인 오
류들을 찾을 수 있다.

디버깅을 시작하기 전에 자동적인 검출 도구(컴
파일러 등)가 보고한 코드 악취를 제거할 것
프로그램을 슬라이싱할 때에는, 문장 S로부터
의존성을 따라가면서 다음과 같은 문장들을 모
두 찾는다.
 – S에 영향을 받을 수 있는 문장들(전방 슬라이스)
 – S에 영향을 죿 수 있는 문장들(후방 슬라이스)

연역맊을 사용한다면 코드 불일치, 관렦 세부사
항의 과도한 추상화, 부정확 같은 위험이 생긴
다.

어떤 종류의 연역도 멈춤 문제에 제한을 받으며,
그러면 보수적 근사에 의지해야 한다.
부록


기억에 남는 디버깅
디버그 모드에서는 제대로 작동.

릴리즈 모드에서맊 작업의 오차가 생
긴다.

차라리 프로그램이 죽으면 좋으렦맊.

추적 결과 오류 문장을 찾음.
float f;
…
int a = static_cast<int>(f);
왜!
float  int 캐스팅인데
소수 부분    fractional part 을

버리는 게 아니고
반올림을 하지???
컴파일러 옵션에   /QIfist   가 있었다.


_ftol()를 사용해서 변홖하는게 아니라
FPU(Floating-Point Unit)의
기본 rounding 모델인 반올림을 수행
[Why Programs Fail] Deducing Errors, 오류 연역

Contenu connexe

Tendances

C Language For Arduino
C Language For ArduinoC Language For Arduino
C Language For Arduino영욱 김
 
C++ 타입 추론
C++ 타입 추론C++ 타입 추론
C++ 타입 추론Huey Park
 
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...Seok-joon Yun
 
python 수학이해하기
python 수학이해하기python 수학이해하기
python 수학이해하기Yong Joon Moon
 
[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3Chris Ohk
 
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준Seok-joon Yun
 
HI-ARC ACM ICPC TF #5 (ADVANCED DFS)
HI-ARC ACM ICPC TF #5 (ADVANCED DFS)HI-ARC ACM ICPC TF #5 (ADVANCED DFS)
HI-ARC ACM ICPC TF #5 (ADVANCED DFS)Jae-yeol Lee
 
Pure Function and Rx
Pure Function and RxPure Function and Rx
Pure Function and RxHyungho Ko
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1Chris Ohk
 
2. c언어의 기본
2. c언어의 기본2. c언어의 기본
2. c언어의 기본SeonMan Kim
 
C수업자료
C수업자료C수업자료
C수업자료koominsu
 
자료구조 그래프 보고서
자료구조 그래프 보고서자료구조 그래프 보고서
자료구조 그래프 보고서mil23
 
Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버Jaejin Yun
 
자료구조 05 최종 보고서
자료구조 05 최종 보고서자료구조 05 최종 보고서
자료구조 05 최종 보고서pkok15
 
[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식은식 정
 

Tendances (20)

C Language For Arduino
C Language For ArduinoC Language For Arduino
C Language For Arduino
 
C++ 타입 추론
C++ 타입 추론C++ 타입 추론
C++ 타입 추론
 
Equation Solving
Equation SolvingEquation Solving
Equation Solving
 
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
 
python 수학이해하기
python 수학이해하기python 수학이해하기
python 수학이해하기
 
[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3[C++ Korea] Effective Modern C++ Study, Item 1 - 3
[C++ Korea] Effective Modern C++ Study, Item 1 - 3
 
Erlang
ErlangErlang
Erlang
 
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
 
HI-ARC ACM ICPC TF #5 (ADVANCED DFS)
HI-ARC ACM ICPC TF #5 (ADVANCED DFS)HI-ARC ACM ICPC TF #5 (ADVANCED DFS)
HI-ARC ACM ICPC TF #5 (ADVANCED DFS)
 
Pure Function and Rx
Pure Function and RxPure Function and Rx
Pure Function and Rx
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
 
2. c언어의 기본
2. c언어의 기본2. c언어의 기본
2. c언어의 기본
 
C수업자료
C수업자료C수업자료
C수업자료
 
자료구조 그래프 보고서
자료구조 그래프 보고서자료구조 그래프 보고서
자료구조 그래프 보고서
 
Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버
 
2012 Ds 01
2012 Ds 012012 Ds 01
2012 Ds 01
 
5 swift 기초함수
5 swift 기초함수5 swift 기초함수
5 swift 기초함수
 
자료구조 05 최종 보고서
자료구조 05 최종 보고서자료구조 05 최종 보고서
자료구조 05 최종 보고서
 
[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식[C++ korea] effective modern c++ study item8~10 정은식
[C++ korea] effective modern c++ study item8~10 정은식
 
Ch07
Ch07Ch07
Ch07
 

En vedette

[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅종빈 오
 
게임서버프로그래밍 #6 - 예외처리 및 로깅
게임서버프로그래밍 #6 - 예외처리 및 로깅게임서버프로그래밍 #6 - 예외처리 및 로깅
게임서버프로그래밍 #6 - 예외처리 및 로깅Seungmo Koo
 
게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링
게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링
게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링Seungmo Koo
 
게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP Adv게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP AdvSeungmo Koo
 
사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)
사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)
사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)Seungmo Koo
 
게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가Seungmo Koo
 
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델Seungmo Koo
 

En vedette (7)

[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅
 
게임서버프로그래밍 #6 - 예외처리 및 로깅
게임서버프로그래밍 #6 - 예외처리 및 로깅게임서버프로그래밍 #6 - 예외처리 및 로깅
게임서버프로그래밍 #6 - 예외처리 및 로깅
 
게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링
게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링
게임서버프로그래밍 #3 - 메모리 및 오브젝트 풀링
 
게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP Adv게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP Adv
 
사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)
사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)
사설 서버를 막는 방법들 (프리섭, 더이상은 Naver)
 
게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가
 
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델
 

Plus de 종빈 오

트위터 봇 개발 후기
트위터 봇 개발 후기트위터 봇 개발 후기
트위터 봇 개발 후기종빈 오
 
적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0종빈 오
 
페리 수열(Farey sequence)
페리 수열(Farey sequence)페리 수열(Farey sequence)
페리 수열(Farey sequence)종빈 오
 
내가 본 미드 이야기
내가 본 미드 이야기내가 본 미드 이야기
내가 본 미드 이야기종빈 오
 
비트 경제와 공짜
비트 경제와 공짜비트 경제와 공짜
비트 경제와 공짜종빈 오
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해종빈 오
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스종빈 오
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개종빈 오
 
2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템종빈 오
 
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81종빈 오
 
[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments종빈 오
 
넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우종빈 오
 
[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합종빈 오
 
LevelDB 간단한 소개
LevelDB 간단한 소개LevelDB 간단한 소개
LevelDB 간단한 소개종빈 오
 
[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline종빈 오
 
[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당종빈 오
 
[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary종빈 오
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬종빈 오
 
[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명종빈 오
 
[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering종빈 오
 

Plus de 종빈 오 (20)

트위터 봇 개발 후기
트위터 봇 개발 후기트위터 봇 개발 후기
트위터 봇 개발 후기
 
적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0
 
페리 수열(Farey sequence)
페리 수열(Farey sequence)페리 수열(Farey sequence)
페리 수열(Farey sequence)
 
내가 본 미드 이야기
내가 본 미드 이야기내가 본 미드 이야기
내가 본 미드 이야기
 
비트 경제와 공짜
비트 경제와 공짜비트 경제와 공짜
비트 경제와 공짜
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개
 
2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템
 
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
 
[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments
 
넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우
 
[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합
 
LevelDB 간단한 소개
LevelDB 간단한 소개LevelDB 간단한 소개
LevelDB 간단한 소개
 
[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline
 
[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당
 
[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
 
[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명
 
[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering
 

[Why Programs Fail] Deducing Errors, 오류 연역

  • 1. 오류 연역 Deducing Errors http://ohyecloudy.com http://cafe.naver.com/architect1 2009-08-08
  • 2. 연역(Deduction) 어떤 명제로부터 추론 규칙에 따라 결론을 이끌 어 냄. 또는 그런 과정. 일반적인 사실이나 원리를 전제로 하여 개별적인 사실이나 보다 특수한 다른 원리를 이끌어 내는 추 리를 이른다. 경험을 필요로 하지 않는 순수한 사유에 의하여 이루어지며 그 전형은 삼단 논법 이다. -네이버 국어 사전
  • 3. 프로그램 분석에서 연역은 추상적인 프로그램 코드에서 구체적인 프로그램 실행으로의 추론 기법 정적 분석 실제로 프로그램을 수행할 필요 없다.
  • 4. 이 장의 주제 코드만으로 연역해 낼 수 있는 일반적인 오류들은 무엇인가?
  • 5. 값 귺원의 격리 제어 흐름 이해하기 의존성 추적 프로그램 슬라이싱 코드 악취의 연역 정적 분석의 한계 정리
  • 6. 뭔가 불가능한 일이 일어났다면, 그리고 그에 대한 확실한 정보는 그것이 실제로 일어났다는 것뿐이 라면, 결과로부터 거슬러 생각해서 thinking backward 이유들을 찾아내야 한다. - Kernighan & Pike(1999)
  • 7. 10 INPUT X 20 Y = 0 거슬러 생각하기 30 X = Y 40 PRINT “X = “, X 실패 원인에 영향을 주는 문장을 찾는다. 항상 X = 0 출력 어디에서 비롯되었을까?
  • 8. 값 귺원의 격리 제어 흐름 이해하기 의존성 추적 프로그램 슬라이싱 코드 악취의 연역 정적 분석의 한계 정리
  • 9. $ gcc –o fibonacci fibonacci.c $ ./fibonacci fib(9) = 55 fib(8) = 34 fib(7) = 21 fib(6) = 13 fib(5) = 8 fib(4) = 5 fib(3) = 3 어디에서 비롯되었을까? fib(2) = 2 fib(1) = 1291239
  • 10. #include <stdio.h> int fib( int n ) 값에 영향을 { int f, f0 = 1, f1 = 1; 미칠 수 있는 while( n > 1 ) { n = n - 1; 코드 영역을 식별 f = f0 + f1; f0 = f1; } f1 = f; 문장들이 return f; } 수행되는 int main() { 순서를 조사 int n = 9; while( n > 0 ) { printf( "fib(%d) = %dn", n, fib(n) ); n = n - 1; } return 0; }
  • 11. 짂입 : fib(n) int f int f0 = 1 int f1 = 1 문장 == 노드 while( n > 1 ) 갂선 == 제어흐름 n = n - 1 AB f = f0 + f1 A는 B에 앞선다. B는 A를 따른다. f0 = f1 f1 = f return f 종료
  • 12. 제어 흐름의 난점들 점프와 goto goto 50 갂접 점프 goto x, 함수 포인터 동적 분배 shape.draw() rectangle::draw() circle::draw() 예외 throw new Exception(“제기랄”)
  • 13. 값 귺원의 격리 제어 흐름 이해하기 의존성 추적 프로그램 슬라이싱 코드 악취의 연역 정적 분석의 한계 정리
  • 14. 문장이 주는 영향 쓰기 : 프로그램 상태를 변경 v1 = 1 제어 : 프로그램 카운터 변경 while(n>1), if(n>1)
  • 15. 문장이 받는 영향 읽기 : 프로그램 상태를 읽는다. v2 = v1 + 1 변수 v1이 가리키는 주소에서 값을 읽는다. 수행 : 프로그램 카운터가 현재 문장 을 가리키는가.
  • 16. 문장 읽기 쓰기 제어 0 fib( n ) n 1-9 1 int f f 2 f0 = 1 f0 3 f1 = 1 f1 4 while( n > 1 ) n 5-8 5 n = n – 1 n n 6 f = f0 + f1 f0, f1 f 7 f0 = f1 f1 f0 8 f1 = f f f1 9 return f f <반홖값>
  • 17. 짂입 : fib(n) int f int f0 = 1 제어 의존성 int f1 = 1 자료 의존성 A는 B의 수행을 제어한다. A의 자료가 B에서 쓰인다. while( n > 1 ) n = n - 1 f = f0 + f1 f0 = f1 f1 = f return f 종료
  • 18. 이 값은 어디로 가는가? 짂입 : fib(n) int f int f0 = 1 n의 자료 의존성이 있는 int f1 = 1 while 문장의 while( n > 1 ) n의 자료 의존성 제어 의존성 n = n - 1 f = f0 + f1 f0 = f1 f1 = f 결국 return f n의 값은 f, f0, f1의 값을 결정 종료 궁극적으로 f 값도 결정
  • 19. 이 값은 어디에서 왔는가?짂입 : fib(n) int f f의 자료 의존성 int f0 = 1 int f1 = 1 while( n > 1 ) n = n - 1 f = f0 + f1 f0 = f1 f1 = f 결국 return f f(1)의 값은 초기화 되지 않은 종료 임의의 값이 사용됐다.
  • 20. 의존성 활용 의존성은 코드를 따라 항해하는데 중요한 지침 프로그래머들은 코드를 읽으면서 암묵적으로 의존성을 판단. 각 문장의 효과를 추정하는 것은 프로그램 이해의 일부.
  • 22. 값 귺원의 격리 제어 흐름 이해하기 의존성 추적 프로그램 슬라이싱 코드 악취의 연역 정적 분석의 한계 정리
  • 23. 슬라이스 slice 프로그램의 부분집합 슬라이싱 slicing 슬라이스에 관한 연산
  • 24. 전방 슬라이스forward slice A에 의해 변경된 변수를 읽거나 수행 여부가 A에 의해 결정되는 모든 문장   A B  )A ( F S  B A : 슬라이스 기죾 후방 슬라이스backward slice B에 영향을 주는 모든 문장  S B ( B)  A A  B  B : 슬라이스 기죾
  • 25. 0.짂입 : fib(n) 1.int f S (2)  2,6,7,8,9 F 2.int f0 = 1 3.int f1 = 1 4.while(n > 1) 5.n = n - 1 6.f = f0 + f1 7.f0 = f1 8.f1 = f 9.return f 종료
  • 26. S (9)  0,1,2,3,4,5,6,7,8,9 B 0.짂입 : fib(n) 1.int f 2.int f0 = 1 3.int f1 = 1 4.while(n > 1) 5.n = n - 1 6.f = f0 + f1 7.f0 = f1 8.f1 = f 9.return f 종료
  • 27. 슬라이싱slicing F B 절단chop S ( A)  S ( B) 중추backbone 입방체dice A전방 슬라이스 기죾가 B후방 슬라이스 기죾에 어떻게 영향을 주는가? 0.짂입 : fib(n) 1.int f 2.int f0 = 1 3.int f1 = 1 S F (3)  S B (7)  {6,8} 4.while(n > 1) f1의 초기값이 f0에 영향을 미칠 수 있는 모든 경로 5.n = n - 1 6.f = f0 + f1 7.f0 = f1 8.f1 = f 9.return f 종료
  • 28. 슬라이싱slicing F or B F or B 절단chop S ( A)  S ( B) 중추 backbone 여러 값들의 계산에 기여하는 입방체dice 프로그램 부분들을 찾을 때 1. int main() { 1. int main() { 2. int a, b, sum, mul; 2. 3. sum = 0; 3. 4. mul = 1; 4. 5. a = read(); 5. a = read(); 6. b = read(); S B (12)  S B (13) 6. b = read(); 7. while (a <= b) { 7. while (a <= b) { 8. sum = sum + a; 8. 9. mul = mul * a; 9. 10. a = a + 1; 10. a = a + 1; 11. } 11. } 12. write(sum); 12. 13. write(mul); 13. 14.} 14.}
  • 29. 슬라이싱slicing 절단chop F or B F or B 중추backbone S ( A) S ( B) 입방체dice 계산된 값들 대부분이 정확하지맊 일부만 그렇지 않을 때 S B (13) S B (12) 1. int main() { 2. 3. 정확한 변수의 후방 슬라이스 4. mul = 1; 5. – 감염된 변수의 후방 슬라이스 6. = 감염된 값에 기여하는 문장들 7. 8. 9. mul = mul * a; 10. 11. 12. 13. write(mul); 14.}
  • 30. 값 귺원의 격리 제어 흐름 이해하기 의존성 추적 프로그램 슬라이싱 코드 악취의 연역 정적 분석의 한계 정리
  • 31. 초기화되지 않은 변수 읽기 사용되지 않는 값 도달할 수 없는 코드 메모리 누수 int go; switch( color ) { 인터페이스 오용 case RED: case AMBER: 널 포인터 go = 0; break; case GREEN: go = 1; break; } if( go ) { … } color가 RED or AMBER or GREEN 이 아닐때는? VS : Warning Level 4에서 default가 없다고 경고
  • 32. 초기화되지 않은 변수 읽기 사용되지 않는 값 도달할 수 없는 코드 메모리 누수 인터페이스 오용 int main(int argc, wchar_t* argv[]) { 널 포인터 ... // argc, argv 사용되지 않음 return 0; } VS : Warning Level 4에서 참조되지 않는다고 경고
  • 33. 초기화되지 않은 변수 읽기 사용되지 않는 값 도달할 수 없는 코드 메모리 누수 인터페이스 오용 if( w >= 0 ) is printf(“w non-negativen”); else if( w > 0 ) 널 포인터 printf(“w is positiven”);
  • 34. 초기화되지 않은 변수 읽기 사용되지 않는 값 도달할 수 없는 코드 메모리 누수 int* readbuf( int size ) { 인터페이스 오용 int* p = malloc(size*sizeof(int)); for( int i = 0; i < size; ++i ) 널 포인터 { p[i] = readint(); if( p[i] == 0 ) return 0; } return p; } 스마트 포인터, RAII가 널 구원해죿지니…
  • 35. 초기화되지 않은 변수 읽기 사용되지 않는 값 도달할 수 없는 코드 메모리 누수 void readfile() { 인터페이스 오용 int fp = open(file); int size = readint(file); 널 포인터 if (size <= 0) return; ... close(fp); } 열었으면 닫아야지. RAII가 널 구원해죿지니…
  • 36. 초기화되지 않은 변수 읽기 사용되지 않는 값 도달할 수 없는 코드 메모리 누수 int *readbuf(int size) { 인터페이스 오용 int *p = malloc(size * sizeof(int)); for (int i = 0; i < size; i++) { 널 포인터 p[i] = readint(); if (p[i] == 0) return 0; // end-of-file } return p; } null일수도 있다.
  • 38. 값 귺원의 격리 제어 흐름 이해하기 의존성 추적 프로그램 슬라이싱 코드 악취의 연역 정적 분석의 한계 정리
  • 39. int x; for(i=j=k=1;--j||k;k=j?i%j?k:k-j:(j=i+=2)); write(x); x가 초기화되지 않고 사용되는가? 홀수 완전수가 존재해야 한다. 존재하는지 아는 사람은 아직 없음 따라서, 보수적 귺사에 의존해야 한다.
  • 40. 보수적 근사conservative approximation 배열 a[]의 임의의 변경이 그 배열 a[]의 임의의 읽기에 영향이 미칠 수 있다고 말하는것. 필요 이상으로 많은 자료 의존성을 맊들어내겠 지맊 그래도 실제 자료 의존성들이 잘못 갂과되 는 일은 막아죾다.
  • 41. 보수적 근사가 부정확한 원인들 갂접 접귺 변수가 실행시점에 결정된다면? 포인터 포인터가 가리키는 주소를 정확히 알 수 있는가? 함수 호출 지점에 직접 삽입하면 정확한 의존성을 알 수 있다. 함수가 아주 맋다면 비현실적 객체지향 병렧성
  • 42. 연역 자체의 위험 자체가 추상화에 의한 위험을 앆고 있다. 코드 불일치의 위험 정밀한 구성 관리, 버전 제어를 통한 극복 과도한 추상화의 위험 어쩔수 없지 뭐 부정확함의 위험 검증과 관찰을 혼합
  • 43. 값 귺원의 격리 제어 흐름 이해하기 의존성 추적 프로그램 슬라이싱 코드 악취의 연역 정적 분석의 한계 정리
  • 44. 값 귺원들을 격리하려면, 문제의 문장으로부터 의존성들을 거꾸로 추적한다. 의존성들을 통해서 코드 악취를 발견할 수 있다. 특히, 초기화되지 않은 변수 사용, 사용되지 않 는 값들, 도달할 수 없는 코드 같은 일반적인 오 류들을 찾을 수 있다. 디버깅을 시작하기 전에 자동적인 검출 도구(컴 파일러 등)가 보고한 코드 악취를 제거할 것
  • 45. 프로그램을 슬라이싱할 때에는, 문장 S로부터 의존성을 따라가면서 다음과 같은 문장들을 모 두 찾는다. – S에 영향을 받을 수 있는 문장들(전방 슬라이스) – S에 영향을 죿 수 있는 문장들(후방 슬라이스) 연역맊을 사용한다면 코드 불일치, 관렦 세부사 항의 과도한 추상화, 부정확 같은 위험이 생긴 다. 어떤 종류의 연역도 멈춤 문제에 제한을 받으며, 그러면 보수적 근사에 의지해야 한다.
  • 47. 디버그 모드에서는 제대로 작동. 릴리즈 모드에서맊 작업의 오차가 생 긴다. 차라리 프로그램이 죽으면 좋으렦맊. 추적 결과 오류 문장을 찾음.
  • 48. float f; … int a = static_cast<int>(f);
  • 49. 왜! float  int 캐스팅인데 소수 부분 fractional part 을 버리는 게 아니고 반올림을 하지???
  • 50. 컴파일러 옵션에 /QIfist 가 있었다. _ftol()를 사용해서 변홖하는게 아니라 FPU(Floating-Point Unit)의 기본 rounding 모델인 반올림을 수행