(주)테스트마이다스 (TestMidas Co., Ltd)

Download Report

Transcript (주)테스트마이다스 (TestMidas Co., Ltd)

고객을 위한 코딩 자세
- bug free -
2009. 08
김준
This material is proprietary to TestMidas Co., Ltd.
Copyright © 2008 by TestMidas Co., Ltd. All rights reserved.
목차
•
•
•
•
회사 소개
SW 품질 관리 기법 분류
코딩 가이드 라인
코드 검증
회사 소개
회
대
회
사
표
이
사 이
명
(주)테스트마이다스 (TestMidas Co., Ltd)
사
김
력
준
 2008년
3월 5일
: 회사 설립
 2008년
7월
: 부설연구소 인가
 2008년 10월
: ETRI 연구소 기업 승인
 2009년 4월
: 벤처 승인
 2009년 6월
: ISO 9001 품질 인증
 제 3자 소프트웨어 시험 및 검증 서비스
주 사 업 분야
 소프트웨어 테스트 모니터링 서비스
 소프트웨어 품질 측정 및 개선 Consulting
 공개 SW 검증 서비스
인 력
현
황
11명 (R&D: 9명
ISTQB 자격증 6명, SPICE 심사 자격)
SW 품질 관리 기법 분류
Software Quality Assurance
Software Process
Improvement
CMMI
Product Quality
Improvement
INSPECTION
SPICE
Six Sigma
Testing
White-box
Testing
Black-box
Testing
코딩 가이드라인
개요
• 버그없는 코드 작성의 요구 조건
– 프로그래머들이 버그가 발견될때 마다, 고민을 생각해 본다면,
• 어떻게 하면 이 버그를 자동으로 발견할 수 있었을까?
• 어떻게 하면 이 버그를 막을 수 있었을까?
– 원론적인 답
• 더 철저한 검사  평이하고, 효과에서 미비
– 구체성 필요
• 방금 발견한 것과 같은 종류의 버그를 제거하는 특정 기법 도출
• 세미나 ......
– 모든 범주의 버그를 완전히 제거하거나 감소시키는 것으로 알려진
Technique and Guideline 제공
– 일반 코딩 습관과 상충 가능
• “아무도 그렇게 하지 않는다”.면 “왜 그런가.” 아직도 타당한가.” 따져보자.
– 지침을 무조건 따르라는 것은 아님. 지침은 법칙이 아님. 가급적......
개요
• 코딩에서 고객은 ?
– 시스템을 사용할 End User
– 자기 함수를 호출하여 사용하는 모듈 SW 개발자
– 추후 나의 프로그램을 수정할 자
• 개발자 특징
– 사용하기만 하는 소비자(사용자 고객) 고려
– 자기 코드를 호출하여 사용하거나, 자기 코드를 향후 수정할 사람들을
위해서는 보통 고려하지 않음
• 요약
– 코드 오류 발견 잘 되도록 하자.
– 남이 나의 코드를 잘못 사용할 가능성이 적도록 하자.
– 이해하기 쉽게 코딩하자.
 뻔한 소리이지만, 실행은 드물다.
 발표 내용은 “Writing Solid Code” by Steve Maguire (C Language) 요약
1. Compiler 기능 활용
• 개발 환경을 최대한 활용하자.
– 테스트를 통해, 오류를 발견하는 것은 노력이 많이 드는 활동
• 컴파일러가 모든 오류를 발견해 하면, 이상적
• 테스터들도 한계가 있다.  나름 체계적으로 진행 하지만......
버그를 자동으로 발견할 수 있는 기회 최대 이용하자.
• Techniques
– 모든 컴파일 warning option을 활성화하자. %gcc -Wall
(Null Statement, wrong assignment, check protoype)
– 코드를 check-in 하기 전에, lint를 사용하자.
– 간단한 변경  unit test 후  checkin
• 코드 수정이 적으면, 문제없다고 생각하기 쉽다. 보통 시험 건너뜀
– 기타 tool이 있으면 활용하라.
2. ASSERT 사용
• ASSERT 사용
– 프로그램이 정상적으로 작동하면, 결코 발생하지 않아야 하는 것
• 예:
– 함수 인수 검증
– 정의되지 않은 부분은 검증
• Library 경우, 조건에 따라 동작이 정의되어 있지 않은 부분 존재
 But, 정의되지 않은(undefined) 부분은 가능하면 제거
– ASSERT 문 이해가 어려우면, 주석 달것.
• 주석은 쉽고, 핵심적인 표현으로.(다른 사람 시간 절약)
• ASSERT는 에러 체크가 아님
3. 견고한 함수(1/3)
• 함수 규격을 정의할 때
– 프로그래머가 잘못 사용할 수 있는 사항은 무엇일까?
– 그러한 사항이 발생한 경우, 자동으로 발견할 수 있게 하는 방안은?
• 예:
– malloc, free, realloc 개발한다고 할때
• 할당받은 메모리를 초기화하지 않은 채, 그 내용을 접근한다면,
• 메모리를 반납하고 난뒤에도, 그 메모리를 계속 접근한다면,
• realloc으로 메모리 확장뒤, 이전 메모리 위치의 내용으로 접근한다면,
• 메모리 경계를 넘어서, 읽기/쓰기를 하는 경우에는
 이렇게 잘못 사용할 수 있다고 생각하고,
사용한다면, 자동으로 발견할 수 있는 방안을 고민하며, 코딩해야 한다.
– 생각할 점
• 상기 오류는 많이 실수하는 형태임.
• 오류 잡기까지는 시간이 많이 소요되는 현상들임.
3. 견고한 함수(2/3)
• Techniques
– 불분명하게 발생하는 요소는 제거하고, 버그는 잘 발생하게.
• 예: malloc
– 불분명한 동작
» 블록 요구 크기가 “0”, - assert
» 블럭할당 쓸모없는 값, 추후 블록값이 쓸모 유무 체크 – assert 불가
– 초기화하자. 특별한 값으로(0xCC, 0xA3, ...)
– 반납한것에 대해서도 Garbarge 값이 없도록:
• 예: free
– 쓸모 없는 것으로 보이게 하자(특정 값) – 오용 방지용 파괴
– 실수 가능성: 트리 구조, 노드 반납, 주위 링크 정보 실수로 유지
– 드물게 일어나는 현상은 자주 발생하게
• 예: realloc에서 메모리 확장 부분은 초기화되지 않는다. 초기화하라
3. 견고한 함수(3/3)
• Techniques
– 디버거용 부가 정보 유지하면, 오류 발견 용이.
• 예: memory management 만들기(메모리 관리 정보 유지)
– 테스트 Routine 만들어, 수시로 체크
• 자신 자료 구조의 일관성을 체크하는 시험 코딩과 수시 점검
– 예: dangling pointer  자동적으로 버그 잡기?  일관성 체크 루틴
• 테스트용 루틴도 고민하여, 효과를 높여라
– 예: 초기화 값 하나도 어떤 값이 좋은지 고민하자? O, A3, ...
– 테스트 루틴 자체로 코드의 성능/크기에 문제있다고 생각하지마라
• 예: Release Version 대상이 아님. Debug Version 대상임
주요 포인터: 버그 잡는것이 촛점
 Library 함수를 안전하게 하려면, Cover Function 만들어 사용하자.
 이러한 디버깅 테스트를 했더라면,
몇년동안 그렇게 애먹었던 realloc의 버그도
몇시간 또는 며칠만에 잡혔을 것이다. By Steve Maguire
4. 코드 살핌(1/2)
• 코드 추적의 필요성
– assert 사용, test routine 으로만 체크하기에는 한계
– 직접 코드를 따라가 보면서, 확인하는 것 방법과 함께 사용 필요
– 모든 제어 흐름을 테스트루틴으로 커버하기 어려움에 따라,
Debug Tool로 다양한 Path 실행
• Error Handling Code에 대한 테스트 루틴 작성보다, 추적 방법 용이
• 추적 시점:
– 코드를 새로 추가 또는 수정 직후  “변경은 곧 버그 발생 근거”
• Techniques
– (컴파일 직후) 코드를 추적하면서 확인
• 예: %gdb  next, step (breakpoint)
– 모든 코드를 확인한다.
• If, switch, &&, ||, ?: 2가지 경로 모두 추적
4. 코드 살핌(2/2)
• Techniques(con’t)
– 코드를 추적할 때는, 데이터 흐름에 초점
• 데이터 값 변화 중심(breakpoint)
• 다음 버그 종류 발견에 도움
–
–
–
–
–
–
–
–
overflow, underflow bug
data convension bug
off-by-one bug
NULL pointer bug
쓸모없는 메모리를 사용한 버그(Free memory에 value setting)
‘==‘ 대신 ‘=‘ 사용한 대입 버그(assignment bug)
우선 순위 버그(precedence bug)
논리상의 버그
• 특징
– 개발자에게 부하가 많고, 기존 개바 문화의 차이로 거부감 많음
– 매니저 강요가 요구됨
• 습관되면 별 문제 없다.
• 코드 수정 습관 좋아짐(테스트 용이하게, 적게 수정)
5. 명료한 함수 규격(1/2)
• 함수사이 입출력 창구 역할을 명확히
– 예1: 리턴 값에 오류와 정상 값을 혼용해서 사용하지 말것
• malloc: return Value  정상(주소값), 오류(NULL)
– 예2: 함수 이름으로 직관적으로 이해할 수 있게
• getchar: 직관적으로 char 반환으로 생각, 실제는 int 리턴(비직관적)
– 예3: 사용자 함수 사용시, 실수 방지
• realloc: 기존 크기보다 작거나, 커짐에 상관없이, 항상 기존 포인터로 유지
• 함수 기능은 가급적 세분화
– 예: realloc
• IF 주소 인자가 NULL, then “malloc” 효과
• IF 크기 인자가 0, then “free” 효과
메모리의 모든 기능을 지원하는 함수(메모리 관리 해결사 함수)
함수 인자를 검증할 수 없음(모두 합법하기 때문에)
But, NULL, 0은 인자 입력은 사용자 실수 가능성이 높지만(malloc,free 사용),
함수 입장에서는 옳다고 판정할 수 밖에 없음
원인: 처음 규격에서 하나씩 기능을 추가하다 보니, 다기능 함수 현상 발생
5. 명료한 함수 규격(2/2)
• 함수 입력 값은 엄격히 정의하여, assert를 최대한 활용
– 엄격하면, ASSERT를 활용할 수 있다.
• 입력값이 정당하면, 오류없는 함수로 설계하자
– 가능하다면, 에러가 일어날 상황을 줄이자.
• 함수 내부는 assert로 적용
• 오류 리턴이 없을수록, 호출함수도 그만큼 체크 루틴이 적어진다.
• 함수의 Readability를 높이자.
– 가급적 boolean 값을 사용하지 말자.
– 예:
• if(fseek(fpDoc, offset, 1) == 0)  X
• if(fseek(fp,offset,SEEK_CUR)== ERR_NONE)  O
– 한 함수 인수의 boolean 값에 의해 기능이 달리하는 것보다,
함수 이름을 다르게해서 2개로 만들자.
• 주의를 요하는 부분은 반드시 코멘트 달기
– 예: getchar
• char로 리턴되는 것이 아니라, int로 리턴되는 함수임을 주의시켜야 한다면,
함수 사용 부분에 올바른 “사용 예”를 작성하여, 코멘트화 하라.
6. 위험 요소 자제(1/2)
• 배경
– SW 버그가 프로젝트 성공여부에 중요성하다는 인식이 낮다.
• 나중 버그 발견에 놀라지 않음, 버그 수정 시간은 많다는 인식
• 프로그래머들에 대한 교육 필요
– 기능을 지원하는 함수만 구현하면 된다는 생각에서,
함수 설계, 함수 구현에서 얼마나 위험한지 생각을 해야 함
• Techniques
– 가능하면, 이식성이 있는 코드를 작성하자
• 예: 정확하게 정의된 데이터 형(type) 사용
– 오브플로우 또는 언더플로우 발생할지 체크
• 코드 추적으로 해결
– 불필요한 IF 문을 제거하라.
– ?: 연산자 사용 자제
6. 위험 요소 자제(2/2)
• Techniques(con’t)
– 똑같은 검사 중복하지 않도록, 함수 설계시 고민하기
– 위험한 구문은 사용 자제
• 예: 비트 연산자를 통해 곱하기,나누기, .... 피하자.
– 다른 종류 연산자 함께 사용하지 말것
• 예: 우선순위는 모두 외우지 못한다.
차리리 괄호를 사용하라.
– 에러를 리턴하는 함수를 사용하지 마라.
• 부득이 한 경우, 에러 처리 코드를 추적 확인
7. 보편적 코드(1/2)
• 배경
– 프로그래머들 중에는 코딩에 특별함을 보이려고 하는 경향 존재
– 버그를 줄이는 데는 지향해야 할 자세임.
• Techniques
– 자기 메모리 공간만 접근할 것
• 성능에 집착하다 보면, 가끔 실수 가능
• 반납한 메모리는 재 사용하지 말것
– 호출 함수에 전달할 공간(인수)를 자신의 작업 공간으로 사용 금지
– 데이터를 정적 메모리, 전역 메모리로 반환 자제
• 대부분 기능적으로 자신의 함수 자체는 문제없지만, 호출하는 함수에
서 문제 발생 가능
7. 보편적 코드(2/2)
• Techniques(con’t)
– 다른 함수 호출은 규격만 보고 사용하라.
• 내부 알고리즘에 영향을 받지 않도록 함수를 호출하라.
– 수치 연산에 논리값을 대입시키지 말것
– 코딩을 짧게 하지 말것
• 풀어쓰는 것이 오히려 이해하기 쉽다.
• 짧다고 항상 성능면에 효과적이지는 않다.
– 남이 보아도, 직관적으로 이해할 수 있도록 코딩하자.
• 고객에 대한 배려이며,
• 현재의 코드는 영원히 당신만 보는 코드가 아니다.
8. 자세와 습관(1/3)
• 배경
– 앞선 방법으로 사전에 오류 해결 부족
– 옳은 자세와 습관 필요
• Techniques
– 버그는 저절로 사라지지 않음
• 버그가 이유없이 없을질 때, 일반적 판단
– Bug Report 오류
– 다른 프로그래머가 버그 수정했다고 생각은 잘못
• 반드시 원인을 반드시 밝혀야 함
– 버그는 발견 즉시, 원인 파악하여, 고칠것
•
•
•
•
개발자는 기능 구현 완료에 부담감 가짐.
따라서 버그 수정은 뒷전
문제점: 뒤에 SW 버그가 몰림에 따라, 제품 Release 시기 예측 힘듬
즉시 수정하면:
– 개발자들의 똑같은 실수를 조기에 방지함.
– 제품 Release 시기 예측이 가능함. 단계별 기능 추가 가능
8. 자세와 습관(3/3)
• Techniques(con’t)
– 오류의 원인을 찾아 해결, 현상만 발생하지 않도록 조치하지 말것
– 중요하지 않으면, 사소한것에 대해서도 코드를 정리하지 말것
• 이전에 코딩한 개발자도 고민을 많이 한 코드임
– 기능 추가는 신중히 할것
• 기능 추가의 기준은 “기능 추가를 쉽게 할 수 있다”가 기준이 아니라,
제품의 성패에 중요한 것인가? 가 기준이 되어야 함.
• 추가는 새로운 구현이기 때문에, 시험을 모두 해야 함.
– 문제 발생 시, 주위의 단순 코멘트에 의해 시도하지 말것
• 한번 해 보는 것은 자제, 해결책 정확히 파악하는 자세 필요
– 업무는 작은 단위로 나누어, 코딩과 테스트를 반복할것
– 자신의 코딩에 어디에 우선해야 할 지를 생각하고, 코딩할것.
마무리
• Recomments:
– 프로젝트에서 사용하는 라이브러리를 분석하여, 프로젝트용 Cover
Function을 만들어 사용하자. 자동 검사는 코드 검증 도구를 통하여...
– 개발자들에게 간단한 예제를 통하여, 앞선 코딩 규칙의 자세와 습관을 익
히도록 실습하고, 상호 토의해 보자.
• Conclusions:
– 원칙은 특별한 것이 아니다.
– 습관이 되어 있지 않을 뿐이다.
– 버그 발견 비용이, 코딩 지침 실천으로 많이 해소할 수 있다면, ......
결정은 당신 몫
• Considering: (항상 개선하는 자세 필요)
– 여러분은 자신이 일으킨 버그를 나중에 분석해 본적이 있는가?
– 어떻게 하면 이러한 버그를 재발하지 않을까 하는 관점에서......
코드 검증(Code Inspector)
코드 검증
• 목표
– 분야별 국제 표준 및 best practice를 기반으로 SW 코딩 가이드라인을 확립하고 코
드 검사를 자동화
• 의의
– 자동화 된 코드 인스펙션은 투입비용 대비 최고의 코드 품질 향상 효과를 제공함
– 조직의 개발 노하우를 표준화하고 공유함으로써 품질 균일화
– 코드에 대한 잠재적 오류 또는 유지 관리 비용을 낮추기 위해, 규칙을 기반으로 자
동 위배 코드 발견
• 활용 사례:
– SW 선진국에서는 자사 SW 코딩 규칙에 따라 모든 코드 적용
(규칙을 위배하는 경우에는 근거 제시)
– 안전성을 요구하는 분야에는 표준 제정: MISRA
• 도구:
– 종류:
• 국내: Code Inspector, 스패로우,RESORT
• 국외: Prevent, ......
– 비교 포인터:
• 서비스 지원 여부
• 잠재 오류 체크 범주
• False Alarm 비율