C를 어떻게 할 것인가: 정적 방법을 통한 한층 더 심층적인 코드 분석

C-STAT은 혁신적인 정적 분석 툴로서, IAR Embedded Workbench에 완전히 통합되어 있습니다. 이번 기사에서는 이러한 C-STAT은 어떤 제품인지, 그리고 어떤 기능과 한계가 있는지에 대해 알아보겠습니다.

정적 분석 방법이란? 

예부터 전해 내려 오는 말에 이런 것이 있습니다 – ‘코드를 작성할 때에는 항상 그 코드를 관리해야 하는 사람이 당신의 주소를 알고 있는, 잔인한 사이코패스라고 생각하고 작성해야 한다.’ 정적 분석 기법은 모범적인 코드 작성 기준을 따르고, 향후 발생할 수 있는 문제를 미연에 방지해 주는 여러 기법 중의 하나입니다. 

정적 분석이라는 말은 보는 사람에 따라 그 의미가 달라질 수가 있습니다. 또, 정적 분석에 대한 정의도 여러 가지가 존재합니다. 이번 기사에서는 정적인 기법으로 코드를 분석하는 방법에 대해 알아 보겠습니다. 이 방법은 코드의 보안 취약성이나 하드웨어 포팅을 방해하는 바람직하지 못한 코딩 패턴이나 코드 상의 에러를 밝혀내는 데에 도움을 줍니다.  

정적인 분석 방법을 통하여 밝혀 낼 수 있는 잠재적 에러로는 컨버전 에러나 0으로 나누는 에러와 같은 산술적 문제, 그리고 메모리 누출이나 포인터 아웃오브바운드와 같은 메모리 관리 문제는 물론, 데드 코드(dead code)나 다른 이와 관련된 문제가 있습니다. MISRA C 등의 코딩 표준을 준수하는 부분, 그리고 CERT[1]나 CWE[2]에서 위험한 것으로 지적하고 있는 특정 코드 구조체 발생을 방지하는 것도 이러한 부분과 관련성을 지닙니다. 

이러한 맥락에서 정적인 분석을 정의해 주는 특성으로는 먼저 잠재적인 문제를 찾아 내기 위해 소스를 먼저 실행해야 하는 런타임 분석과는 달리, 소스 차원에서 분석이 이루어지는 점을 들 수 있습니다. 

이와 같은 종류의 정적 소스 코드 분석은 예를 들어 IAR Embedded Workbench에서 제공하고 있는 워스트 케이스 스택 뎁스 분석(worst case stack depth analysis)과는 반대되는 개념입니다. 이 역시 사전에 수행하는 정적 분석의 일종이기는 하지만, 최종 프로그램의 컴파일 및 링크 반영 완료 버전을 대상으로 분석을 진행한다는 점에서 차이가 있습니다. 

정적 분석 방식을 사용하였을 때 얻을 수 있는 가장 큰 이론적 장점 중의 하나는 시스템의 성능에 영향을 미치지 않는다는 점입니다. 코드 자체를 실행하는 일이 없기 때문입니다. 또한 정적 분석 방식은 테스트 프로그램의 품질에도 영향을 받지 않습니다. 결국, 실행중인 코드 상에서 에러를 발견해 내기 위해서는 특정한 데이터 세트를 보유하고 있는 프로그램이 실행되는 경로에 의존하게 됩니다. 하지만 정적 분석 툴에서는 적어도 이론적으로는 코드를 통하는 가능한 모든 경로를 검사하는 것이 가능합니다. 

C/C++ 개발자들이 사용할 수 있는 정적 분석 도구는 다양하게 존재합니다. 그 중 일부는 코드 상에서 특정한 문제 만을 찾아내는 단순한 검색 기능 만을 가진 것도 있는데, 이것들은 소위 말하는 허위 판정이 상당히 많이 이루어지기 때문에 결과가 깔끔하지는 않습니다. 이 부분에 대해서는 나중에 다시 설명하도록 하겠습니다. 이와 반대로 매우 복잡한 도구도 존재하는데, 이런 툴들은 상당히 고가로, 결과를 얻기 위해 몇 시간이고 프로그램을 계속 실행시켜야 할 수도 있습니다. 이와 같은 고급 툴의 경우 결과는 위에서 말한 단순한 툴에 비해서는 훨씬 더 정확하지만, 그래도 여전히 걸러 내야 하는 결과도 많이 포함됩니다. 이와 함께 생각해 두어야 하는 부분이 바로 대부분의 분석 툴은 소스 내에 존재하는, 특정한 형식의 문제점을 모두 다 찾아낼 수 있다고 보장하지는 못한다는 점이며, 따라서 소위 말하는 허위 음성 결과를 눈치 채지 못하고 그냥 넘어갈 수도 있습니다. 이는 특정한 종류의 에러를 그야 말로 하나도 빠짐없이 찾아내려고 한다면 용량이 폭증해 프로그램의 확장성이 매우 나빠집니다. 그래서 용량이 그다지 않은 프로그램을 분석하는 데에도 한 번에 며칠씩 걸릴 수도 있습니다. 해당하는 종류의 에러를 모두 찾아낼 수 있다고 주장하는 툴도 반드시 쓸 데가 있기는 합니다만, 빡빡한 일정 가운데에 하루 단위로 새로운 기능을 추가해야 하는 프로젝트 환경에는 그다지 어울리지 않을 것입니다.(애초에 가격이 터무니없이 비싸며, 그러고 나서도 여전히 허위 판정을 걸러 내기 위해 고생을 하게 됩니다.) 

임베디드 업계에서 일반 정적 분석 툴을 사용할 때 또 한 가지 현실적으로 다가오는 문제점은 바로 이러한 툴들을 구입 후 바로 그대로 사용할 수 있는 경우는 거의 없으며, 자기 빌드 환경에 맞추어 상당히 많은 설정에 손을 대야 한다는 것입니다. 그래야 비로소 파일의 위치를 찾는 것에서부터 결과를 이해하고, 하드웨어에 좀 더 근접한 효율적인 프로그래밍을 위한 언어 확장 문제를 처리할 수 있습니다. 

 

비교의 기준은? 

서로 다른 정적 분석 툴을 비교하는 것은 결코 쉽지 않습니다. 모든 툴은 서로 다른 가정을 기반으로 하여 개발되어 있으며, 초점이 되는 분야도 서로 다릅니다. 그러므로 벤치마크 시험을 실시한다고 하더라도 실질적으로는 비교 대상이 된 모든 툴이 같은 코드에서 저마다 다른 문제점을 지적해 낼 것입니다. 이와 같은 상황을 한층 더 어렵게 만드는 사실이 있으니, 바로 특정 툴은 다른 어떠한 탐지 기능도 없이, 특정한 범주에 속하는, 매우 특정한 종류의 에러 만을 탐지해 낼 수 있도록 되어 있다는 점입니다. 그 좋은 예가 미국 NIST에서 진행했던 SAMATE³ 프로젝트입니다. 여기서는 정기적으로 SATE³라 불리는 정적 분석 툴 비교 행사를 개최하고 있는데, 각각의 툴 업체들 참여해 고도로 정형화된 방식으로 툴의 평가를 받는 행사입니다. 

C-STAT의 등장 

그렇다면 IAR 시스템즈가 여기서 보여줄 수 있는 것은 무엇일까요? 저희 IAR이 처음 고객을 위한 정적 분석 툴 개발에 착수했을 때 저희가 금새 알게 된 사실은 바로 가격이 합리적이면서도 툴 통합 문제가 전혀 없이 간편하게 사용할 수 있는 툴이 시장에 존재하지 않는다는 점이었습니다. 뿐만 아니라, 당사는 탐지가 가능한 다양한 종류의 문제를 지원하는 한 편, MISRA 표준 등 좀 더 정형화된 코드 표준을 지원할 수 있는 기능도 갖추고자 하였습니다. 

이와 같은 당사의 노력으로 탄생한 것이 바로 IAR Embedded Workbench의 애드온 제품인 C-STAT 입니다. C-STAT는 IDE 내에 완전히 통합되어 있으며, 일반 빌드 툴과 마찬가지로 사용이 간편합니다. 복잡한 툴 설정 과정을 따로 거칠 필요가 없으며, 언어 지원 문제 및 일반 빌드 문제로 골머리를 썩일 필요도 없습니다. 뿐만 아니라, 빌드 환경을 직접 관리하고자 하는 사용자를 위해 커맨드 라인에서도 똑같은 혜택을 누리며 사용자의 코드를 분석해 낼 수 있는 기능도 갖추었습니다. 

C-STAT의 주요 장점을 살펴 보면 다음과 같습니다:

  • C 및 C++ 언어를 지원하는 정적 분석 툴로, IAR Embedded Workbench에 관련되는 모든 언어 구조체를 지원합니다. 또한, 빌드 툴 체인 내에서 지원되어 하드웨어에 직접적으로 인터페이스를 구성하는 코드의 개발 과정을 좀 더 간편하게 해 줍니다.  
  • 단순히 문제가 의심되는 코드에서부터 확실한 문제가 관측되는 코드에 이르기까지 다양한 코드 패턴을 탐지해 낼 수 있는 첨단 기술을 바탕으로 하는 정적 분석 기능으로, 버퍼 오버플로우, 산술 및 컨버전 문제, 힙 관리의 일시적 특성 등이 여기에 해당됩니다. 
  • C-STAT은 혁신적 기술을 갖추어 모델의 점검과 제약요소 해소를 바탕으로 허위 양성 판정을 거부 및 관리합니다. 
  • C-STAT은 대략 250가지 고유 검사 기능을 지원합니다. 이들은 서로 다른 코딩 표준 및 규정집 속하는 대략 600 가지의 규칙과 매핑되어 있으며, 여기에는 CERT 및 CWE 표준, MISRA C:2012, MISRA C++:2008, MISRA C:2004 등도 포함되어 있습니다.  여기서 MISRA C:2004 (및 MISRA C:1998)는 대부분의 IAR C/C++ 컴파일러가 직접적으로 지원하고 있으므로 참고 하시기 바랍니다. 이러한 분석은 서로 다른 기술에 바탕으로 두고 있으므로, 따라서 C-STAT 분석을 아주 잘 보완해 주고 있습니다. 
  • C-STAT는 사용자가 어떠한 규칙 및 검사를 사용할 것인지에 대해 매우 정밀하게 제어할 수 있도록 해 줍니다. 
  • 모듈 간 분석을 통하여 이득을 볼 수 있는 검사의 경우, C-STAT는 모듈 간의 경계를 넘어 정보를 전파합니다. C-STAT는 또한 복수 파일 컴필레이션 모드에서도 실행이 가능합니다. 이 모드에서는 모든 소스 코드가 하나의 모듈로서 분석 대상이 되며, 이를 통해 일부 검사의 분석 정확도를 높일 수가 있습니다. 

결론적으로 C-STAT는 사용자로 하여금 코드에 대한 완전한 통제권을 지니도록 해 주며, 개발 과정에서 코드의 품질을 높일 수 있도록 합니다.  이렇게 코드 품질 검사를 모든 개발자들이 일상 업무로서 수행하는 경우, 기업에 상당한 이득이 있을 것으로 생각됩니다. 초기에 문제를 발견해 냄으로써 최종 제품에 미치는 영향을 줄일 수 있을 뿐 아니라, 프로젝트의 일정 상에 발생하는 영향도 마찬가지로 줄어듭니다. 그리고 코드를 관리하는 담당자가 실제로 잔인한 사이코패스인 경우 일신의 안전을 유지하는 데에도 도움이 될 것입니다. 



¹ CERT C/C++ 보안 코딩 표준은 컴퓨터 비상 대응팀(CERT)이 발표한 표준으로, C/C++  프로그래밍 언어로 작성된 코드의 보안 확립을 위한 규칙을 제시하고 있습니다. 추가 상세 정보는 www.cert.org을 참고하시기 바랍니다. 

² CWE(Common Weakness Enumeration)는 커뮤니티에 의해 개발된 소프트웨어 취약점 및 약점 목록입니다. 추가 상세 정보는 cwe.mitre.org/를 참고하시기 바랍니다. 

³ AMATE 관련 추가 상세 정보는 samate.nist.gov/Main_Page.html를 참고하십시오. 

죄송하지만, 당사 사이트에서는 Internet Explorer를 지원하지 않습니다.보다 편안한 사이트를 위해 Chrome, Edge, Firefox 등과 같은 최신 브라우저를 사용해 주시길 부탁드립니다.