WIPIVERSE

동적 프로그램 분석

개요

동적 프로그램 분석(Dynamic Program Analysis)은 소프트웨어를 분석하는 방법론의 하나로, 프로그램을 실제 또는 가상의 프로세서에서 실행함으로써 그 특성을 관찰하고 평가하는 기법을 의미한다. 이는 프로그램을 실행하지 않고 소스 코드나 정적 구조만을 검토하는 정적 프로그램 분석(Static Program Analysis)과 대조된다.

동적 프로그램 분석은 소프트웨어의 행동(behavior), 테스트 커버리지(test coverage), 성능(performance), 보안(security) 등 다양한 측면을 분석 대상으로 삼는다. 분석이 효과적이기 위해서는 대상 프로그램이 충분한 테스트 입력으로 실행되어 가능한 입력·출력 범위를 충분히 다룰 수 있어야 한다.

개념적 배경

동적 프로그램 분석은 프로그램 분석(Program Analysis) 분야의 하위 개념으로, 컴퓨터 과학 및 소프트웨어 공학에서 널리 인정된 확립된 학술 개념이다. 프로그램 분석은 크게 실행 여부에 따라 정적 분석과 동적 분석으로 구분되며, 두 접근법을 결합한 혼합 방식도 존재한다.

동적 분석은 정적 분석이 다루기 어려운 실행 시점의 동적 특성(예: 동적 메모리 할당, 다형성, 동적 디스패치)을 보다 정밀하게 처리할 수 있는 장점이 있다. 반면, 분석 결과가 특정 입력과 실행 경로에 의존하므로 프로그램의 전체적 특성을 포괄적으로 파악하지 못하는 한계도 있다.

주요 유형

동적 프로그램 분석에 포함되는 대표적인 기법은 다음과 같다.

  • 기능 테스팅(Functional Testing): 유닛 테스트, 통합 테스트, 시스템 테스트 등 프로그램을 실행하여 기능의 정확성을 검증하는 기법.
  • 코드 커버리지(Code Coverage): 테스트가 실행한 코드의 범위를 측정하여 테스트되지 않은 코드를 식별하는 기법. 다만 커버리지 측정 자체는 테스트가 실제로 올바른 동작을 검증했는지 여부를 보장하지는 않는다.
  • 동적 테스팅(Dynamic Testing): 테스트 케이스 집합을 실행하여 프로그램의 동작을 검증하는 기법.
  • 메모리 오류 탐지(Memory Error Detection): 실행 중 발생하는 메모리 오염, 누수, 잘못된 할당·해제 등을 탐지하는 기법.
  • 퍼징(Fuzzing): 프로그램을 광범위한 입력(주로 무작위 생성)으로 실행하여 오류나 취약점을 발견하는 기법. 회색 상자 퍼저(gray-box fuzzer)는 코드 커버리지를 활용하여 입력 생성을 유도한다.
  • 동적 기호 실행(Dynamic Symbolic Execution, DSE): 구체적 입력으로 프로그램을 실행하면서 경로 제약 조건을 수집하고, 제약 해결기(SMT solver)를 통해 다른 제어 흐름 경로를 탐색하는 기법. 동시 실행(concolic execution)이라고도 한다.
  • 동적 데이터 흐름 분석(Dynamic Data-flow Analysis): 소스(source)에서 싱크(sink)로의 정보 흐름을 추적하는 기법. 동적 오염 분석(dynamic taint analysis)이 대표적이다.
  • 불변식 추론(Invariant Inference): 실행 중 관찰된 값들에서 항상 참으로 유지되는 속성을 추론하는 기법. Daikon이 대표적 구현이다.
  • 보안 분석(Security Analysis): 실행을 통해 보안 취약점을 탐지하는 기법.
  • 동시성 오류 탐지(Concurrency Error Detection): 경쟁 상태(race condition) 등 멀티스레드 환경에서 발생하는 오류를 탐지하는 기법.
  • 프로그램 슬라이싱(Program Slicing): 특정 동작을 재현하는 최소 형태로 프로그램을 축약하는 기법으로, 주로 디버깅에 활용된다.
  • 성능 분석(Performance Analysis): 대부분의 성능 분석 도구는 동적 프로그램 분석 기법을 사용한다.

기술적 구현 방식

대부분의 동적 프로그램 분석은 프로그램에 계측(instrumentation) 코드를 삽입하거나 변환(transformation)을 적용하는 방식을 사용한다. 계측 방식은 크게 두 가지로 구분된다.

  • 정적 바이너리 계측(Static Binary Instrumentation): 프로그램이 실행되기 전에 오브젝트 코드 또는 실행 코드를 재작성하는 방식.
  • 동적 바이너리 계측(Dynamic Binary Instrumentation): 프로그램의 런타임 실행 단계에서 계측을 수행하는 방식.

계측은 런타임 성능에 영향을 줄 수 있으므로, 테스트 결과를 해석할 때 이러한 영향을 고려하여 성능 문제를 잘못 식별하지 않도록 주의가 필요하다.

대표적인 도구

동적 프로그램 분석에 사용되는 주요 도구로는 다음이 알려져 있다.

  • Valgrind: 가상 프로세서에서 프로그램을 실행하여 메모리 오류와 멀티스레드 경쟁 상태를 탐지하는 도구.
  • Gcov: GNU 소스 코드 커버리지 측정 프로그램.
  • AddressSanitizer: LLVM의 일부로, 메모리 오류 탐지를 지원하는 도구.
  • Intel Inspector: C, C++, Fortran 애플리케이션의 동적 메모리 오류 및 스레딩 오류를 탐지하는 도구.
  • Daikon: 동적 불변식 탐지의 구현체.
  • IBM Rational AppScan: 웹 애플리케이션 보안 취약점을 위한 동적 분석 도구 제품군.
  • DynInst: 런타임 코드 패칭 라이브러리로, 컴파일된 실행 파일에 동적 분석 프로브를 적용하는 데 사용된다.
  • Purify: 메모리 오염 및 메모리 누수 탐지 도구.

정적 분석과의 비교

정적 프로그램 분석은 프로그램을 실행하지 않고 소스 코드를 검토하여 잠재적 결함이나 위험 요소를 식별하는 반면, 동적 프로그램 분석은 실제 실행을 통해 관찰 가능한 동작을 분석한다. 정적 분석은 실행 경로의 전부를 고려할 수 있으나 실행 시점의 동적 특성을 정밀하게 반영하기 어렵고, 동적 분석은 실제 실행 경로만을 관찰하므로 입력에 따라 결과가 달라질 수 있다. 두 방법론은 상호 보완적인 관계에 있으며, 실제 소프트웨어 품질 관리와 보안 분석 과정에서 함께 사용되는 경우가 많다.

참고 문헌

  • Myers, G. J. (1979). The Art of Software Testing. John Wiley and Sons.
  • Chen, Ting et al. (2013). "State of the art: Dynamic symbolic execution for automated test generation". Future Generation Computer Systems, 29(7), 1758–1773.
  • 위키백과 "동적 프로그램 분석" 문서
  • Wikipedia "Dynamic program analysis" 문서
둘러보기

더 찾아볼 만한 주제

    전체 문서 보기