정적 분석

Static Analysis

방법

코드를 실행하지 않고 그대로 훑어서 버그 가능성과 보안 취약점, 규칙 위반을 찾아내는 검사입니다.

등장 배경

코드에서 문제를 찾는 방법이 오랫동안 둘뿐이었습니다. 돌려 보는 것과 사람이 읽는 것입니다.

두 방법 모두 놓치는 자리가 정해져 있습니다. 테스트는 실제로 밟은 경로만 확인해 줍니다. 열 갈래 중 셋을 밟는 테스트는 나머지 일곱에 무엇이 있는지 말해 주지 않습니다. 사람이 읽는 코드 리뷰는 합치기 전에 동료가 코드를 살펴보는 절차인데, 300줄이 넘어가면 집중이 떨어지고 같은 종류의 실수를 반복해서 놓칩니다.

그래서 흔히 나오는 장면이 이렇습니다. 리뷰를 통과하고 테스트도 전부 녹색인 코드가 운영에 올라간 뒤 값이 없는 경우에서 터집니다. 나중에 보면 그 경로는 테스트가 밟지 않았고 리뷰어도 스무 번째 파일에서 놓친 자리였습니다. 사람이 더 열심히 보는 것으로는 이 종류가 줄지 않습니다.

정적 분석은 실행 대신 코드의 구조를 기계가 훑어 이 빈틈을 메웁니다. 값이 없을 수 있는 변수를 검사 없이 쓰는 자리, 닫지 않은 자원, 바깥에서 들어온 값을 그대로 질의에 넣는 자리처럼 모양으로 알아볼 수 있는 문제를 전부 찾아냅니다.

사용 절차

무엇을 검사할지 고르는 것에서 시작합니다. 한 번에 다 켜면 경고가 수천 건 나와 아무도 읽지 않게 됩니다.

  1. 규칙 묶음을 고릅니다. 값이 없을 가능성 같은 타입 문제, 흔한 버그 모양, 보안 취약 패턴, 쓰고 있는 외부 코드의 라이선스 준수 가운데 지금 필요한 것부터 켭니다.
  2. 기존 코드에 한 번 돌려 기준선을 만듭니다. 2년 된 저장소에서 2,800건이 나오는 것은 정상입니다. 이걸 다 고치고 시작하려 하면 시작하지 못합니다.
  3. 새 코드에만 막는 규칙을 걸어 둡니다. 기존 2,800건은 목록으로 기록만 해 두고, 지금부터 추가되거나 고쳐지는 줄에서 심각도가 높은 항목이 나오면 합치기를 막습니다. 기존 코드는 그 파일을 손댈 때 함께 정리합니다.
  4. CI/CD에 붙입니다. 코드 변경을 자동으로 검증하고 배포까지 잇는 체계인데, 검사를 여기 넣어 두면 사람이 잊어도 돌아갑니다. 각자 컴퓨터에서만 돌리는 상태로 두면 바쁜 날에 건너뛰게 됩니다.
  5. 오탐을 처리합니다. 문제가 아닌데 걸린 자리에는 무시 표시를 달고 왜 괜찮은지를 한 줄로 적습니다. 이유 없는 무시 표시가 쌓이면 다음 사람이 그것을 지워도 되는지 알 수 없습니다. 오탐이 유독 많은 규칙은 그 규칙 자체를 끕니다.
  6. 분기마다 규칙을 한 단계 올립니다. 경고만 띄우던 항목을 막는 항목으로 바꾸거나 새 묶음을 켭니다. 처음부터 엄격하게 시작하는 대신 올려 가는 쪽이 유지됩니다.

적합한 상황과 한계

기계가 판정할 수 있는 종류에서 값을 합니다. 값이 없을 수 있는 자리, 도달할 수 없는 코드, 닫지 않은 파일, 바깥 입력을 검사 없이 질의에 넣는 자리가 그런 것들입니다. 코드가 커질수록 이득도 커집니다. 파일 3,000개짜리 저장소에서 사람이 전부 읽는 것은 불가능하지만 기계는 20분에 한 번씩 전부 읽습니다.

못 잡는 것도 뚜렷합니다. 실행해 봐야 아는 문제는 이 방식의 밖에 있습니다. 두 번째 화면이 느린 이유, 실제 데이터에서만 나오는 계산 오류, 요구사항을 잘못 이해해 만든 기능이 그렇습니다. 문법이 완벽하고 규칙을 다 지켰는데 엉뚱한 것을 만든 코드는 통과합니다.

오탐과 미탐도 한계입니다. 걸린 것의 20퍼센트가 실제로는 문제가 아니면 사람들은 전체를 무시하기 시작하고, 그때부터 검사는 돌지만 아무 일도 하지 않습니다. 반대로 모양만 보기 때문에 실행 흐름을 따라가야 알 수 있는 문제는 조용히 지나갑니다.

역할이 겹치는 도구와는 범위가 다릅니다. 린터는 코드 규칙 위반을 자동으로 잡아 주는 도구로 정적 분석의 한 갈래이고, 포매터는 코드 모양을 정해진 규칙대로 맞춰 주는 도구라서 옳고 그름을 판정하지 않습니다. 설계가 이 문제에 맞는지, 이 기능이 꼭 필요한지 같은 판단은 여전히 코드 리뷰의 몫입니다.

실무 용례

"정적 분석에서 값 없음 경고가 열두 개 나와서 합치기가 막혔습니다."

검사에 걸려 진행이 멈췄다는 보고입니다.

"기존 경고는 목록으로 두고 새 코드만 막는 쪽으로 설정했습니다."

한 번에 다 고치는 대신 늘지 않게 막는 방식을 택했다는 말입니다.

"이 규칙은 오탐이 너무 많아서 끄는 게 낫습니다."

검사를 신뢰하지 못하게 만드는 규칙은 없애자는 제안입니다.

페이지덱에서는 태오가 도입 첫날 2,800건을 보고 되돌릴까 고민했습니다. 전부 고치려면 두 주가 필요했고 그 두 주에 다른 일을 멈춰야 했습니다. 대신 기존 건수를 목록으로 저장해 두고 새로 바뀐 줄에서만 심각도 높은 항목을 막도록 설정했습니다.

넉 달 뒤 남은 경고는 2,800건에서 1,900건으로 줄었습니다. 따로 정리 기간을 두지 않았고, 기능을 고치러 파일을 열 때마다 그 파일의 경고를 함께 처리한 결과였습니다. 같은 기간에 운영에서 값 없음으로 터진 오류는 한 달 평균 6건에서 1건으로 내려갔습니다.

흔한 오해

검사를 통과하면 안전하다고 읽는 경우가 가장 많습니다. 전부 녹색으로 보이니 그렇게 느껴집니다. 그런데 통과했다는 것은 이 도구가 아는 모양의 문제가 없다는 뜻뿐입니다. 요구사항을 잘못 이해한 기능, 실제 사용량에서만 드러나는 병목, 두 기능이 함께 돌 때 생기는 충돌은 검사 대상이 아닙니다. 정적 분석과 테스트와 코드 리뷰는 서로 다른 종류를 잡는 그물이라 하나로 나머지를 대신할 수 없습니다.

경고를 0으로 만들어야 한다고 보는 것도 흔합니다. 숫자가 보이니 목표처럼 읽힙니다. 하지만 오래된 저장소에서 0을 만들려면 기능 개발을 멈춰야 하고, 멈출 수 없으니 대개 규칙을 느슨하게 조정해 0을 만듭니다. 그러면 숫자는 0인데 잡히는 문제도 없어집니다. 실무에서 보는 값은 남은 건수가 아니라 새로 늘어난 건수입니다.

자주 헷갈리는 용어

용어무엇을 보는가정적 분석과의 차이
린터정해 둔 코드 규칙의 위반정적 분석의 한 갈래입니다. 규칙에 맞는지를 보는 쪽이고, 정적 분석은 값이 없을 가능성이나 보안 취약 패턴처럼 실행 결과를 추론해 판정하는 범위까지 갑니다

같이 보면 좋은 페이지

  • 코드 품질

    이 검사가 어느 활동의 수단인지 먼저 봅니다

  • 린터

    같은 방식 안에서 가장 먼저 붙이는 도구입니다

  • 라이선스 준수

    같은 검사로 확인하는 법무 쪽 항목입니다

마지막 업데이트 2026-09-16