02
2장: 문제점 추적
1. 문제점의 수명주기
* 사용자 -> 제작사 문제점 보고
* 문제점 재현
* 문제 상황 격리
* 코드에서 결함을 찾고 교정
* 교정 결과물을 사용자에게 돌려줌
--> 수명주기의 조직화 필요
1. 문제점이 드러나 있는지 (소프트웨어에 결함이 존재)
2. 가장 심각한 문제점은 무엇인지 (심각도 순서대로 교정 필요)
3. 과거 문제점 사례발생 여부 (기존의 해결책 이용 가능성)
[ 대규모 디버깅 공정을 어떻게 조직화할 것인가? ]
2. 문제점 보고
* 문제점 보고 (Problem Report) == 변경요청 == 버그리포트
* 문제점 보고에 쓸데없지 않은 것만 포함시켜야 함
--> 그러기 위해서 '유관사실'만을 판별하고, 구체적 항목으로 목록화
* 문제점 보고에 포함시켜야 할 내용 (기본원칙)
¤ 제품 릴리즈 (제품버전번호 or 기타 고유식별자)
¤ 운영 환경 (운영체제 버전) --> 일반화(다른 운영환경도 테스트)
¤ 시스템 자원 (CPU 부하,디스크 용량 , 메모리 ..)
¤ 문제점 내력(History)
¤ 기대되는 행동에 대한 서술 (~했어야 했는데, 안했다)
¤ 실제 일어난 행동(증상)
- 최대한 중립적
- 사실만을 기술
¤ 한 줄짜리 요약문 (문제의 핵심 포착)
- 개발자가 문제점 측정시의 심각도 기초
- 로그 파일 등
- 문제점: 사용자가 자신의 정보 유출을 꺼림
3. 문제점 관리
* 한번에 오직 한 사람만 문제점 문서를 다루어야 한다.
- 버전 관리 시스템에서는 분리 병합
* 이전의(교정된) 문제점에 대한 내력이 사라진다.
- 버전 관리 시스템에서는 변경 내력 유지 가능
* 규모 가변성이 없다.
- 하나의 통합된 문서 형태로 관리가 가능해야 함.
---> 그러기위해서, 문제점 데이터베이스에 모든 문제점 보고들을 저장
ex) BugZilla
4. 문제점 분류
# 각 애트리뷰트별로 문제점을 분류
* 심각도 (Severity) - '차단, 치명, 주요, 보통, 부차, 사소' 레벨이 부여
* 우선순위 (Priority) - 개발/문제해결 공정을 조절하는 핵심 기준
* 식별자 (identifier) - 특정 문제점 지칭용
* 주석 (comment) - 문제환경 정보 기입 / 해결책 논의
* 통지
- 문제점보고시 이메일주소 첨부 --> 문제점보고 변경시 자동통지 받음
# 이상적인 제품은 심각한 문제점을 모두 고친 후에 출시 되어야 함.
5. 문제점 처리
* Unconfirmed (아직 누구도 재현해 보지 않은 상태)
* New (문제점 보고가 있어야 유효함 , 유관 사실이 포함되어 있어야 함)
* Assigned (개발자에 배정됨)
* Resolved (해소됨)
* 처리결과
- fixed
- Invalid (문제점이 아니거나 유관 정보가 없음)
- Duplicate
- WONTFIX (교정 불가)
- WorksForme(재현 불가)
- VERIFIED (교정 후 검증 성공)
- Close (제품의 새 릴리즈가 만들어짐)
- Reopen (동일 문제 발생시는, new가 아닌 reopen)
6. '문제점 추적' 관리
* 문제점 정리/보관자는?
* 문제점 보고 분류자는?
* 우선순위 설정자는?
- 문제점 발생 가능성
- 영향을 받는 사용자수
- 피해 가능성
* 문제점 처리자는?
* 문제점 종결자는?
* 문제점 수명주기는?
7. '문제점 == 요구사항'
* 문제점은 개발 과정에서 사용 가능
* 요구사항이 주요 문제점
* 요구사항에 따른 중요도 선정
* 계통구조를 지원 해야 함 (세분화 지원)
8. 중복의 관리
* 최대한 많은 사실을 포함
* 중복을 찾기 위해서는 최대한 적은 사실들이 바람직
* 교정의지 없는 문제점: 개발자가 더이상 지원의사 없음 (BugZilla: Won't Fix)
- 오래된 딱 한번 발생한 문제점
- 오직 내부에서만 발생한 문제점
9. 문제점과 교정의 연계
* 개발자가 버전별 소스/도구를 사용가능 해야함
--> 그래야만 개발자 PC에서 재현 가능
* 임의의 구성(형상)을 언제라도 재현할 수 있어야 함
* 소프트웨어 형상관리는 버전 관리 시스템을 이용
10. 문제점과 테스트의 연계
* 실패한 테스트와 문제점을 어떻게 동기화할 것인가?
* 테스트 결과와 문제점 보고를 분리하도록 권장
- 테스트 결과는 자주 생성됨.
- 테스트는 결과를 굳이 어딘가에 저장할 필요가 없음
- 테스트 실패 시 만일 즉시 교정 가능하면 기록의 필요가 없음.
* 테스트 케이스들은 문제점 보고를 퇴물로 만든다.
* 문제점 발생시 재현 가능한 테스트 케이스를 작성
- 도구 -
벅질라 (www.bugzilla.org)
모질라의 벅질라 사용예 (bugzilla.mozilla.org)
phpBugTracker: 상대적으로 가벼운 버그추적 시스템 (phpbt.sf.net)
그밖에... Trac / IssueTracker / SourceForge / GForge ...
연습문제는 나~중에 실제로 디버깅 할 일 있을 때 직접 풀어보자 ~~~!
22
이것은 이번주 월요일까지 2주간 공부한 "프로그램은 왜 실패하는가"의 내용을 요약한 것입니다.. (1장~4장: 바로바로 복습하면서 계속 편집을 수정해가다 보니 게시물이 길어지기에.. 각 장별로 나누어야겠습니다^^)
아니 뭐... 사실은 다다음 스터디 때 발표해야 하기 때문에 연결되는 앞부분 내용을 이해하기 위해 간단히 복습하면서 정리만 한 것입니다.
요약은 이제껏 발표하신 분들이 올려주신 프리젠테이션 자료를 아주 조금 더 간추린 정도입니다.
저는 4월16일에 7장을 발표하는데, 큰일 났습니다. ㅎ_ㅎ;
잘 할 수 있을지...... 게다가 저는 실무자가 아닌데 디버깅 툴 동영상은 또 어찌 만들라는 ~~~... 시련입니다.
1장: 실패는 어떻게 일어나는가
1. 결함 ------> 실패
* 프로그래머가 결함(감염 발생할 수 있는 코드 일부)을 만듬
- 예측 불가능 / 복수의 모듈간에 인터페이스 비호환
* 결함에서 감염이 발생 (반드시 발생하는 건 아님, 가능성)
* 감염의 확산
* 실패의 발생 (실패: 프로그램 실행시 겉으로 드러나는 오류)
2. 시공의 디버깅
* 디버깅 7단계 (TRAFFIC)
Track (문제 추적)
Reproduce (실패 재현)
Automate (자동화, 단순화)
Find (감염원 탐색)
Focus (감염원 후보에 촛점)
Isolate (감염사슬 격리)
Correct (결함 정정)
- 문제를 추적하고 다시 일으켜보고, 자동화하여 탐색한 후 가능성있는 후보에 촛점을 맞추고 원인으로 보이는것을 격리한 후 정정한다.
* 실패 발생 원인은 F.F.I 에서 발견하게 된다.
* 시간/공간 조사 (온전-->감염으로 전이가 언제/어떻게? ; 디버깅 목표임)
- 변수/참조 수가 늘수록 탐색해야할 시공간 방대
- 확실한 지점 (온전한 초기점 / 일부가 감염된 지점)
- 온전과 감염의 분리, 유관과 무관의 분리
* 의존 사슬: 실패에서부터 이전 변수값들로 이어지는 의존 관계 사슬
* 프로그램 코드/상태 구조화: 함수,모듈,객체..
3. 프로그램이 이상해요
* 실패 경로: 결함(Defect) --> 감염(Infection) --> 실패(Failure)
* 최초 버그 1947.09.09 하바드 마크 II, 나방이 끼어 죽음
* 프로그램 결함은 프로그래머로 인함.
4. 실패 ---> 교정
* 문제점 추적: 문제보고서를 기록/보관하는 일
- 실패과정도 문제재현 절차에 포함
* 복잡한 프로그램의 경우, 실패 재현의 자동화 필요 (사람이 일일이 재현하기 힘듬) - (3장,5장)
* 감염원 후보 찾기
- 출력이 0이 되는 원인 찾는다
- 연역(7장)이 어려울 때는, 실패 과정 관찰(8장)
- 가능성의 영역을 좁혀나감 (수사 과정)
- 프로그램 실행 도중의 상태관찰 수단 필요
* 유력 후보 감염원에 촛점 맞추자
* 감염원 격리
* 결함 정정 : 이렇게 수정한 후 실패가 안 나타나면, 역시나 그 결함이 실패원인이었음이 입증됨.
5. 자동화 디버깅 기법
* 입력 단순화 (델타디버깅 - 5장)
* 프로그램 슬라이스 (오류 연역 - 7장): 프로그램 실행시 발생 가능/불가능한 사건을, 코드로부터 도출 (추상 ---> 구체)
* 상태 관찰 (사실 관찰 - 8장): 디버거 이용, 프로그램의 특정 상태에 정지시켜 관찰 가능 / 프로그램 변경이나 리컴파일 없이 실행중 관찰 가능
* 상태 감시 (8장): 상태 일부가 실행도중 어떻게 변하는지 관찰 (변수의 감염 순간 포착 가능)
* 단언 (기대의 단언 - 10장): 관찰값/의도값 비교, 함수나 프로그램 전체에서 성립해야 하는 불변식
* 비정상 (비정상 검출 - 11장): 정상/실패 실행간의 차이로부터 비정상을 식별해냄.
* 인과 사슬 (인과사슬의 격리 - 14장): 프로그램 상태에 델타디버깅 적용. 인과관계 원인이 반드시 오류는 아님, 실패요인을 좁혀나갈 수 있다.
* 여러 기법 종합 사용 (결함 고치기 - 15장): 앞의 언급한 다양한 기법들을 연동
* 기타 (실패추적-2장, 자동검사-3장, 실패재현-4장, 여러추론기법결합-6장, 실패원인체계적탐색-12장)
6. 용어 비교/차이
(1) 버그: 사람이 제어가능하거나, 사람에게 책임이 없는 '어떤 것' 암시 / 의미 불분명 / 프로그램의 부정확한 상태,코드,동작 모두를 구분없이 두루두루 지칭하여 혼동을 일으킴 (원인과 증상의 모호)
(2) 결함: 부정확 코드
(3) 감염: 부정확 상태
(4) 실패: 눈에 보이는 수행/동작 버그
# 코드 --> 상태 --> 실행 (버그 발견시, 버그 추적, 버그 교정)
따라서, 용어 의미 불분명으로 혼란스러움,, 아래와 같이 고치면...
# 결합 --> 감염 --> 실패 (실패 발견시, 감염 추적, 결함 교정)
(5) 결점: 전반적 설계/구조 결함 (결함보다 심각)
# 버그: 프로그래머가 그저 짜증스러움에서 대충 뭉뚱그려 사용하는 표현
- 정확한 용어선택으로 실패 근원을 구체화
- 버그라는 용어는 웬지 소프트웨어에 이유없이 자동발생하는 것처럼 느껴짐
- 오류/잘못: 웬지 명백한 인간만의 잘못인 듯한 뉘앙스
- 결함/감염: 반드시 인간의 실수만은 아닌 듯한 느낌, 불필요한 죄책감 모면
- 도구 -
Algorithmic and Automatic Debugging Home Page
http://www.cs.nmsu.edu/~jeffery/aadebug.html
여타의 모든 브라우저에서는 지정해준 margin 그대로 보입니다만, IE 에서는 지정해준 margin이 두배로 표현됩니다.
( float )
[ 일반 브라우저 ]
( float )
[ 인터넷 익스플로러 ]
// 빨간색 부유 박스에 정의된 스타일
.floatbox {
float: left;
width: 150px;
height: 150px;
margin: 5px 0 5px 100px;
/* 마지막 줄에는 왼쪽에 margin 값으로 100px이 정의되어 있습니다. */
}
버그가 발생하는 경우
이 버그가 항상 발생하지는 않습니다. float이 정의된 부유엘리먼트에 지정된 margin의 방향과 동일한 컨테이너(부유엘리먼트를 포함하는) 박스 방향에만 여백(margin)이 이중이 됩니다.
즉 위의 그림에서 보면, float는 left (왼쪽)로 지정되어 있기 때문에, 부모 엘리먼트와 인접한 그와 동일한 방향인 왼쪽의 margin만이 두배가 됩니다.
아무튼 부모 엘리먼트와 맨 첫번째로 인접해있는 부유엘리먼트에만 이중여백이 발생합니다.
버그 바로잡는 법
.floatbox {
float: left;
width: 150px;
height: 150px;
margin: 5px 0 5px 100px;
display: inline;
}
해결방법은 의외로 매우 간단합니다.
예제 스타일의 맨 마지막 줄처럼 display: inline;만 추가해주면 됩니다.
모든 엘리먼트는 1.블록-계층 엘리먼트 2.인라인 엘리먼트 로 나뉘는데, float을 정의해주면 (즉, 부유시키면) 자동으로 블록-계층 엘리먼트로 바뀌어 표현된다고 합니다. 따라서 표현 방식을 인라인 엘리먼트로 정의해주면 해결됩니다.
( float )
+
display: inline;
[ 'display: inline;'을 추가한 부유 엘리먼트 ]
설정: 유동 박스에는 float가 정의되어 부유된 상태이다. IE 6에서 보여지지만 않는다면 모두 멀쩡하다. 근데 IE 6에서 보면 버그가 발생한다. "어라? 내용이 어디갔지??!" 페이지를 새로고침 하면 내용이 다시 보인다. 아래로 스크롤하든지 다른 창으로 마우스를 이동하면, 다시 문제의 내용이 제대로 나온다.
이것을 일명, 깍꼭놀이 버그 (peek-a-boo bug; 숨어있다 갑자기 나타나서 어흥! 놀래키는 놀이에 비유함)라고 한다.
실험: div#floatholder (점선 테두리)는 margin으로 인해 가로로 늘어난 상태이며, 내용으로 인해 세로로 늘어난 상태다. div#float (굵은 갈색 테두리)는 왼쪽으로 부유된 상태이며, 실험용 링크가 들어있다.
그냥(일반) 텍스트 행 몇 줄에 시범 링크가 동시에 들어있으며, 몇개의 텍스트가 들어있는 div가 교대로 더 들어있다. 그 다음에는 부유해제된 div (분홍 테두리)가 오고, 그 다음에는 좀더 명확하게 하기 위한 div가 하나 더 나온다.
부유됨 (float)
실험용 링크
버그: 이러한 효과는 여러가지 상황에서 다른 형태로 나타날 수가 있다. 그 종류를 열거하자면 상당히 길어지므로 생략.
링크가지고 실험해보기: 각 시범 링크들을 클릭해보자. 그러면 스크롤시와 마찬가지로 사라졌던 내용이 나타날 것이다. 만약 부유 엘리먼트가 링크된 이미지라고 해도 마찬가지다. 하지만 div#floatholder에 들어있는 링크와 부유해제된 div보다 앞에 있는 링크들만 해당된다.
주의: div에 여러번 반복된 내용이 들어있을 경우, 버그가 매우 요상하게 발동이 걸리는 경우가 있다. 부유가 해제된 div로 인해 버그가 발동되는 것으로 보인다. 인위적으로 float를 해제할 경우, 아마도 float 적용 이후에 나온 그 앞의 내용이 div#floatholder(점선 테두리)의 배경에 다소 가려지는 것 같다.
따라서, div#float가 div#floatholder 앞에 온다 하더라도 이 버그는 발동될 것이며, 이러한 외부 float이 실제로 div#floatholder안에 포함된 float해제 div에 맞닿게 되는 것이다.
바로잡기: 세가지 방법으로 이 버그를 예방할 수 있다.
1. 부유해제 div를 부유 div에 닿지 않도록 하거나, 혹은 div#floatholder에 background 프로퍼티를 이용하지 말자.
2. div#floatholder (부유 엘리먼트)에 'width' 또는 'height' 프로퍼티를 정확하게 지정해주자. (확실한 방법임!)
3. div#floatholder와 div#float 둘 다에 'position: relative'를 정의해주자. 그리고 이 방법으로 확실히 버그가 해결되는지 테스트하자.
P.S : - -;;
다 작성해놓고 보니, 버그 효과가 안나타나는군요.
제가 zb5 수정할 때, IE 6 깍꼭놀이 버그도 고려해서, 부모엘리먼트들의 높이를 전부 명확히 지정해줘버려서 그런 것 같습니다 - -;; 예제가 헛게 됐네요.





