- 프로그램을 실행하지 않은 채로 소스 코드를 분석하여 버그나 안티패턴 등의 잠재적인 문제를 찾아내는 것
- 분석 종류
- 정적 분석: 프로그램을 실행하지 않고 소스 코드를 분석한다.
- 동적 분석: 프로그램을 실행하여 소스 코드를 분석한다.
- 오버플로를 일으키는 상수 표현식, 실행되지 않는 테스트, 실행하면 비정상 종료를 일으키는 잘못된 포맷의 문자열
- 구글은 정적 분석을 이용해 모범 사례를 코드에 널리 배포하고, 최신 API를 사용하게 하며, 기술 부채를 막거나 줄여준다.
- 새로운 분석 기법을 개발하고 특정 분석 기법을 구현하려는 연구는 수십 년 전부터 이루어져왓지만, 확장성과 유용성 측면의 연구는 상대적으로 최근에 시작되었다.
- 소프트웨어가 커지면서 분석에 걸리는 시간이 늘어나 개발 프로세스 전체가 느려지는 경향이 강해졌다. 이에따라 분석 도구들은 코드량이 많아져도 결과를 제때 내놓을 수 있도록 확장성에 집중하기 시작했다.
- 분석 유용성 측면에서는 사용자들의 비용-편익 트레이드오프(cost-benefit trade-off)를 고려해야 한다.
- 비용은 개발 시간과 코드 품질이 될 수 있다.
- 구글은 새로 추가되는 코드에서 발생하는 경고에 더 집중하고 잘 동작 중인 코드에 존재하던 이슈는 일반적으로 (보안이나 심각한 버그 등) 매주 중요할 때만 부각하고 수정한다.
- 자동을 수정할 수 있는 문제라면 뭐든 자동으로 해야 한다.
- 구글이 정적 분석 도구의 효과를 극대화하기 위해 시행착오를 겪으며 얻은 교훈
- 개발자 행복에 집중하자.
- 정적 분석을 개발자 워크플로에 반드시 끼워 넣자.
- 사용자가 기여할 수 있도록 하자.
- 분석 도구가 제 역할을 얼마나 잘 수행하는지 추적한다.
- 거짓 양성 비율(false positive rate)이 낮은 분석 도구만을 배포한다.
- 분석 도구 사용자와 도구 개발자 사이에 피드백 루프를 구축해 사용자 신뢰를 높이고 도구도 개선되는 선순환을 구축한다.
- 사용자 신뢰는 정적 분석 도구의 성공에 매우 중요하다.
- 거짓 음성(false negative): 분석 도구가 검출하도록 설계된 문제를 놓치는 것
- 거짓 양성(false positive): 문제가 없는데 문제를 찾았다고 보고하는 것
- 도구를 사용하고 싶은 마음을 이끌어내는 데는 거짓 음성보다 거짓 양성 비율을 낮추는 게 더 효과적이다.
- 유효 거짓 양성(effective false positive) 비율: 사용자가 거짓 양성이라고 인식하는 비율
- 구글은 정적 분석을 코드 리뷰 도구에 통합하여 핵심 워크플로에 녹였다.
- 도메인 전문가들이 새로운 분석 도구를 만들거나 기존 도구에 검사 로직을 추가하는 식으로 기여할 수 있다.
- 구글 정적 분석의 핵심
- 구글의 주 코드 리뷰 도구인 Critique에 통합되어 Critique의 diff 뷰어에 회색 댓글 상자로 경고를 표시해준다.
- 확장하기 쉽도록 마이크로서비스 아키텍처로 설계되었다.
- 구글의 개발자 모두는 Tricorder 분석기를 직접 작성하거나 기존 분석기에 검사 항목을 추가하는 식으로 기여할 수 있다.
- 검사 항목으로 추가하려면 네 가지 조건을 충족해야 한다.
- 이해하기 쉬움: 모든 엔지니어가 결과를 쉽게 이해할 수 있어야 한다.
- 실행 가능 및 수정 용이: 분석 결과는 컴파일러 검사보다 수정하는 데 시간, 고민, 노력이 더 들 수 있다. 따라서 결과에는 문제를 실제로 해결하는 방법을 알려주는 안내가 포함되어야 한다.
- 유효 거짓 양성 비율 10% 미만: 개발자들이 검사 항목의 적중률이 최소 90% 이상이라고 느껴야 한다.
- 코드 품질 개선에 크게 기여할 수 있는 잠재력: 정확성과는 관계가 없더라도 개발자가 심각하게 받아들이고 의식적으로 수정할 만한 문제를 짚어줘야 한다.
- Tricorder에는 다양한 유형의 정적 분석 도구들이 통합되어 있다.
- 개발자가 얼마나 행복해하는지를 추적하고 관리하려면 분석기 사용자와 분석기 작성자를 잇는 피드백 루프를 반드시 구축해야 한다.
- Tricorder는 분석 결과 각각에 not useful 버튼을 표시해준다.
- 코드 리뷰어는 Please fix 버튼을 클릭하여 분석 결과를 적절히 조치하도록 변경 작성자에게 요청할 수 있다.
- Tricorder팀은 리뷰어가 수정을 요청했는데 not useful 클릭 비율이 높은 분석기를 주시하다가 이 비율을 낮추려는 움직임이 보이지 않는 분석기는 비활성화 한다.
- 진단 메시지를 다듬으면 무엇이(what) 왜(why) 잘못되었고 어떻게(how) 수정해야 하는지를 가장 적절한 지점에서 바로 설명해줄 수 있다. 그렇게 하면 개발자는 메시지를 읽자마자 상황을 이해할 수 있을 것이다.
- Tricorder 검사 항목은 가능한 경우 어떻게 수정해야 하는지까지 제안해준다.
- 자동 수정은 메시지가 불분명할 때 도와주는 또 다른 문서자료 역할을 하여 정적 분석이 검출한 문제를 해결하는 비용을 낮춰준다.
- 기본 분석기 외에 프로젝트별로 선택적 분석기를 추가할 수 있게 했다.
- 코드 리뷰 시 표시되는 정적 분석 경고를 개발자가 무시할 수도 있다. 그래서 작성 중인 변경이 커밋되지 못하게 막는 분석기를 추가할 수 있도록 했다. 이를 프리서브밋 검사(presubmit check)라고 한다.
- 구글은 정적 분석을 가능한 한 컴파일러에 통합하려 노력한다.
- 컴파일러 검사는 빌드 속도가 느려지지 않도록 빠르게 수행되어야 한다. 그 외에 다음 세 가지 기준도 충족해야 한다.
- 쉽게 수정할 수 없음(가능한 한 기계적으로 적용할 수 있는 수정을 제안)
- 유효 거짓 양성이 발생하지 않음(올바른 코드의 빌드를 절대 가로막지 않음)
- (스타일이나 모범 사례가 아닌) 정확성 관련 문제만 보고
- 구글은 컴파일러 경고 0개를 목표로 한다. 컴파일러 경고를 무시하는 개발자가 많기 때문에 빌드를 중단시키지 않을 컴파일러 검사라면 애초에 꺼버린다.
- 정적 분석을 통합 개발 환경(IDE)에 통합할 수도 있다. 하지만 IDE에서는 분석을 빠르게 마쳐야 하므로 속도가 느린 분석기라면 통합하기 애매하다.
- 같은 분석을 모든 IDE에서 동일하게 수행해야 하는 문제도 있다.
- 적합한 분석기에 한정한다면 IDE도 정적 분석 결과를 보여주기에 좋은 후보이다.
- 정적 분석은 코드베이스를 개선하고 버그를 조기에 발견해준다.
- 코드 리뷰와 테스트처럼 비용이 비용이 더 많이 드는 활동에서는 기계적으로 검증할 수 없는 문제에 집중하도록 해주는 훌륭한 도구다.
- 개발자 행복에 집중하자. 구글은 분석기 사용자와 분석기 작성자를 이어주는 피드백 채널을 도구 안에 녹여내는 데 상당한 노력을 기울였으며, 거짓 양성 비율을 줄이기 위해 분석기들을 적극적으로 최적화했다.
- 정적 분석을 개발자 워크플로에 반드시 포함하자. 구글은 정적 분석을 개발자 워크플로에 긴밀하게 통합했다. 그중 가장 중요한 단계는 코드 리뷰다. 분석 도구가 수정을 제안하고 리뷰어도 문제를 함께 살펴보도록 해준다. 이 외의 통합 지점으로는 컴파일러 검사, 코드 커밋 게이트키핑, IDE, 코드 브라우징 시점이 있다.
- 사용자가 기여할 수 있도록 하자. 도메인 전문가들의 전문지식을 활용하면 분석 도구와 플랫폼을 구축하고 관리하는 일을 가속할 수 있다. 나아가 개발자라면 누구나 새로운 분석기와 검사 항목을 추가할 수 있는 길을 열어주면 모두의 삶과 코드베이스가 더 윤택해진다.