5 minute read

정적 분석, 축지법과 좁히기

프로그램 정적 분석 (static analysis) 이란, 간략하게 표현하자면 프로그램을 직접 실행하여 실제로 어떤 입력에 대해 어떤 일이 발생하는지 확인하지 않고도 어떤 기능을 하고 어떤 결과를 만들어 내며 또 어떤 문제를 일으킬 수 있을지 분석하는 과정이다. 학술적으로는 주로 요약 해석 (abstract interpretation) 이라는 도구를 통해 수학적으로 안전함 (soundness) 이 보장되는 정적 분석을 다룬다. 이 때 안전하다는 것은 최소한 정적 분석 결과 알게 된 정보에 모든 실제로 벌어질 수 있는 상황이 포함되어 있다는 의미로, 만약 안전한 정적 분석기가 어떤 프로그램에 대해 실행 중 메모리 오류를 일으킬 리 없다고 분석하면, 그 프로그램은 무슨 일이 있어도 실제 실행 중 메모리 오류를 일으키지 않음이 보장되는 것이다.

요약 해석을 통해 안전한 프로그램 정적 분석을 할 때, 마치 편법처럼 느껴지지만 반드시 필요한 과정이 있다. 축지법 (widening) 과 좁히기 (narrowing) 라 불리는 이 과정들은 분석기의 안전성을 잃지 않으면서 분석이 반드시 유한 시간 안에 끝나도록 해준다. 이 두 과정이 왜 필요하고, 어떻게 진행되는지는 다음 문단을 참조하자.

정적 분석은 실제로 프로그램을 실행해보지 않고 유한 시간 안에 모든 가능성을 판단해야 하기 때문에 프로그램의 상태를 요약하여 만약 실행한다면 어떤 상태를 가지게 될지 어림잡는다. 프로그램의 상태를 요약하는 방식에는 여러가지가 있는데, 대표적으로 메모리 안에서 각 변수가 가질 수 있는 값이 실제로는 정수형 값이라면 이를 단순히 양수인지 음수인지 0인지 세 가지 경우로만 요약하여 분석을 할 수도 있다 (이를 부호 도메인sign domain 으로 요약한다고 표현한다). 이렇게 되면 필연적으로 정말 그 변수가 가질 수 있는 값에 비해 정확도가 많이 떨어지는 분석 결과를 얻지만, 대신 굉장히 가볍고 빠르게 분석 결과를 얻어낼 수 있을 것이다. 만약 값을 조금 더 정확하고 세밀하게 분석하고 싶다면 “몇 이상 몇 이하이다”와 같이 범위로 표현할 수도 있다 (이를 구간 도메인interval domain 이라고 표현한다). 이렇게 되면 그저 부호 정도만 파악할 수 있었던 부호 도메인과 달리 각 변수가 어떤 범위 안에서 값을 가지게 될지 알 수 있기 때문에 더 정확한 분석 결과를 얻을 수 있을 것이다.

그런데 여기서 문제가 발생한다. 이렇게 더 세밀한 요약을 하게 되면 요약의 형태가 무한해진다. 부호 도메인에서는 음수, 0, 양수에 “무슨 값이든 가능하다” 와 “어떤 값도 올 가능성이 없다” 까지 총 다섯 종류로만 요약이 되는 데에 비해, 구간 도메인에서는 0 이상 1 이하일 수도, 0 이상 2 이하일 수도, 0 이상 3 이하일 수도,…, 0 이상의 모든 정수가 가능할 수도 있기에 무한한 종류가 존재하게 되는 것이다. 이를 요약 도메인 (abstract domain) 이 무한한 길이의 사슬 (chain) 을 가지게 된다고 표현을 한다. 이런 상황에서 전통적인 방식으로는 분석기가 유한한 계산 안에 최종적인 분석 결과인 고정점 (fixed point) 에 도달하지 못할 수도 있게 된다.

이를 해결하기 위해 등장한 기술이 축지법과 좁히기이다. 축지법을 통해 특정 지점에서 메모리가 가질 수 있는 요약된 값 (abstract value) 을 과격하게 큰 범위로 잡고, 이후 다시 좁혀가며 유한한 계산만에 고정점에 도달할 수 있도록 해주는 것이다. 예를 들어 프로그램 안에 반복문이 존재해 그 반복문을 진입하기 이전에 변수 i의 값을 0으로 할당하고, 반복문 안에서 i의 값을 1씩 증가시켜 준다고 해보자. 물론 프로그램은 언젠가 목적을 달성하면 결과를 내주고 종료를 하거나 다른 기능을 수행해야 하기에 특정 조건에서 (이를테면 i의 값이 10이 되는 순간) 반복을 멈추도록 코드가 작성되어 있을 것이다. 그러나 분석기는 프로그램을 실제로 실행하지 않기에 i가 어떤 범위 안에서만 값을 가지게 될지 요약하여 분석해야 하고, 반복문 안에서 i에 1을 더한다는 것을 알 수 있기에 분석기는 i가 가질 수 있는 값의 범위를 “0 이상 0 이하”로 시작하여 “0 이상 1 이하”, “0 이상 2 이하” 이런 식으로 점점 늘려갈 것이다. 그러나 그냥 범위를 1씩 늘려주는 식으로는 코드의 형태에 따라 i가 최종적으로 어떤 범위의 값을 가지는지 영영 계산하지 못할지도 모른다. 이 때 축지법을 쓰는 것이다. 변수 i의 값이 0 이상 0 이하인 줄 알았는데, 반복문에 의해 0 이상 1 이하가 될 수 있다는 걸 아는 순간 분석기는 i가 가질 수 있는 값을 0 이상 무한대 이하, 즉 0 이상의 모든 값이라고 생각해 버린다. 이렇게 되면 실제로 어떤 조건에 의해 반복을 종료하고 i가 어떤 값을 가지게 될지와 관계 없이 분석기는 i의 값의 범위를 한 번에 계산해 낼 수 있는 것이다. 그러나 이 결과는 당연히 너무 과격하기에 정확도가 매우 떨어질 수가 있다. 여기서 정확도를 높여주기 위해 분석기는 좁히기를 수행한다. 만약 반복문에서 i의 값이 10이 되는 순간 반복을 종료한다는 조건식이 있다면, 이를 통해 i가 가질 수 있는 값의 범위를 0 이상 10 이하로 다시 좁혀주는 것이다.

내 인생도 분석기가 있다면

사람이 살아가며 가지게 되는 목표와 계획이라는 것도 어찌 보면 정적 분석일 것이다. 우리는 살아가며 좋든 싫든, 자의건 타의건 간에 조금씩은 목표를 가지고 계획을 세우게 된다. 실제로 행동에 옮기기 전에, 또 그 행동으로 인해 어떤 일이 일어나기 전에 예측하고 분석하여 앞으로의 삶을 설계해 나간다. 사소하게는 내일 점심 메뉴를 고르기 위해 나의 동선과 통장 잔고, 식당의 위치와 가격 및 메뉴별 선호도까지 분석할 수도 있고, 크게는 언제까지 연구를 진행하여 논문을 작성하고 어느 학회나 저널에 제출할지 계획하기 위해 학회 제출 기한과 연구 진행 상황을 요약하여 분석하기도 한다.

목표와 계획을 세우다 보면 점점 골치만 아파지는 경우도 부지기수이다. 더 정확하고 세밀한 인생 계획을 위해 인생 도메인을 키워나가다 보면, 우리가 상상할 수 없을 만큼 방대한 상황을 고려해야 하기에 아무리 잘 요약하더라도 무한한 길이의 사슬을 가지리란 것도 명백하다. 아직 진행중인 연구의 끝을 짐작하기란 여간 쉬운 일이 아니며, 최종적으로 해결하고자 하는 문제의 어느 정도를 정말로 해결할 수 있을지도 쉽게 단정할 수 없다. 이런 도메인에서 연구를 끝내고 논문을 작성해 제출하게 될 학회를 정한다는 것은 나를 끝없는 고뇌와 망설임의 굴레로 빠지게 하곤 한다. 아마 누구든 조금이라도 정확하면서도 안전한 미래를 만들기 위해 머리를 싸맨 경험이 있을 것이다.

매번 고민만 하고 있을 수는 없기에, 우리는 목표를 정할 때 축지법을 사용할 필요가 있다. 삶의 목표를 넓고 높게 가지는 것이다. 최소한 내가 향하고 있는 방향과 연결되어 있는, 즉 사슬의 끝에 있는 목표라면 얼마든지 이룰 수 있다고 믿어보자. 내일 점심으로 6천원짜리 학식을 먹게 될 수도 있지만, 대전 최고의 이탈리안 레스토랑 ‘음식이 있는 풍경’에 가게 될 지도 모른다. 진행 중인 있는 연구의 끝에 어떤 결과물이 기다리고 있을지는 모르지만, 그 결과물이 상용 프로그램의 치명적인 버그를 발견하여 그에 대한 보상으로 구글에서 상금을 줄 수도 있는 일이다.

축지법이 끝난 뒤에는 내 목표를 새기고 되돌아보며 정말 의미와 실체를 가질 법한 미래을 바라볼 수 있도록 좁히기를 하면 된다. 더 현실적이고 구체적인 계획을 세워나가는 것이다. 통장 잔고를 보아하니 내일 점심 이탈리안 레스토랑에 갈 수 없음을 알게 된다면, 은행이 허락하는 한도 내에서 가장 맛있는 학식을 먹기로 하면 된다. 놀랍게도, 잘 정의된 축지법과 좁히기는 수학적으로 안전성을 보장해 준다. 잘 설정한 목표와 계획은, 설령 허황돼 보여도 우리의 삶을 안전하면서도 올바르게, 또 풍요롭게 만들어 줄 것이다.

지금 하고 있는 연구의 목표를 크게 잡았다. 어떤 장애물이 나의 연구를 방해할지 모르지만, 일단 연구에서 하고자 하는 바를 불완전하게라도 수행하는 툴을 설계해 완성하고자 한다. 그 툴을 완성해나가며 연구 문제를 더 견고히 하고 명확히 해나갈 수 있을 것이라 기대한다. 또 그렇게 해결한 문제가 실제 세계에서도 큰 의미와 영향력을 가질 수 있으리라 믿는다. 그리고 그 결과물을 최고의 소프트웨어 엔지니어링 학회, 또는 프로그래밍 언어 학회에 발표할 것이다. 나의 다음 포스트 제목이 “XXX 학회 발표를 다녀와서” 가 되길 바란다.