본문 바로가기

Testing Tools

Mutation testing tool for general language(C/C++ 포함) - mull 설치

1. 개요

C/C++ 대상으로 Mutation Testing 엔진을 찾고 있었는데, 그 중 하나가 Mull 이다.

LLVM의 IR을 대상으로 하여 C/C++은 물론 다른 언어도 목표로 두고 있다.

관련 논문(Link)은 다음을 참고한다.

 

mull-project/mull

LLVM-based mutation testing for C and C++. Contribute to mull-project/mull development by creating an account on GitHub.

github.com

2. 사전조건

2.1. docker ubuntu18.04 이미지 설치

굳이 docker를 사용하지 않아도 된다. Ubuntu 18.04를 기준으로 진행하였다.

 

docker run --name mull_project -v /home/ppiazi:/media -it ubuntu:18.04 /bin/bash

 

2.2. 필수 설치 패키지

apt install libxml2-dev libtinfo-dev git cmake vim sqlite3 libsqlite3-dev wget

 

2.3. Precompiled 된 LLVM 받기(또는 소스코드)

 

LLVM Download Page

If you'd like access to the "latest and greatest" in LLVM development, please see the instructions for accessing the LLVM Git Repository. The major changes and improvements that the development version contains relative to the previous release are listed i

releases.llvm.org

  • 이번 설치 시에는 LLVM 7.0.1을 받았다.(Link)

 

2.4. 소스코드 다운로드

git clone https://github.com/mull-project/mull.git --recursive
cd mull
mkdir build.dir
cd build.dir
cmake -DPRECOMPILED_LLVM_DIR=path/to/llvm ..

cmake 과정

 

3. 설치

3.1. make all

  • make all 로 빌드한다. 시간이 꽤 걸린다.

 

  • 빌드간 발생한 오류가 아래와 같았다. patch를 만들어 놨으니 참고한다.

    • 1) /media/mull/include/mull/Mutators/MutatorKind.h:77:20: error: extra qualification not allowed [-fpermissive]

    • 2) /media/mull/lib/Reporters/SourceManager.cpp:22:8: error: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Werror=unused-result] fread(buffer, sizeof(char), lineLength, lineOffset.file);

    • 3) /mull/lib/SourceLocation.cpp:3:2: error: #import is a deprecated GCC extension [-Werror=deprecated] #import "mull/Path.h"

    • patch
더보기
diff --git a/include/mull/Mutators/MutatorKind.h b/include/mull/Mutators/MutatorKind.h
index 77130df..9934ab8 100644
--- a/include/mull/Mutators/MutatorKind.h
+++ b/include/mull/Mutators/MutatorKind.h
@@ -74,7 +74,8 @@ std::string MutationKindToString(MutatorKind mutatorKind);
 
 namespace std {
 
-template <> struct std::hash<mull::MutatorKind> {
+//template <> struct std::hash<mull::MutatorKind> {
+template <> struct hash<mull::MutatorKind> {
   std::size_t operator()(const mull::MutatorKind &k) const {
     return static_cast<std::size_t>(k);
   }
@@ -91,4 +92,4 @@ private:
   MutatorKindSet(std::unordered_set<mull::MutatorKind> mutators);
   std::unordered_set<mull::MutatorKind> mutators;
 };
-}
\ No newline at end of file
+}
diff --git a/lib/Reporters/SourceManager.cpp b/lib/Reporters/SourceManager.cpp
index 4561e26..1475b9d 100644
--- a/lib/Reporters/SourceManager.cpp
+++ b/lib/Reporters/SourceManager.cpp
@@ -19,7 +19,8 @@ std::string SourceManager::getLine(const SourceLocation &location) {
   uint32_t lineLength = lineEnd - lineBegine;
   fseek(lineOffset.file, lineBegin, SEEK_SET);
   char *buffer = new char[lineLength + 1];
-  fread(buffer, sizeof(char), lineLength, lineOffset.file);
+  int32_t ret = fread(buffer, sizeof(char), lineLength, lineOffset.file);
+  ret ++;
   buffer[lineLength] = '\0';
   auto line = std::string(buffer);
   free(buffer);
diff --git a/lib/SourceLocation.cpp b/lib/SourceLocation.cpp
index e7be093..868b82a 100644
--- a/lib/SourceLocation.cpp
+++ b/lib/SourceLocation.cpp
@@ -1,6 +1,7 @@
 #include "mull/SourceLocation.h"
 
-#import "mull/Path.h"
+//#import "mull/Path.h"
+#include  "mull/Path.h"
 
 #include <string>
 #include <utility>
  • 가상머신에서 간혹 아래와 같은 빌드 오류가 나던데 이유는 모르겠다. 재빌드하면 된다.
    • 증상은 SSD Disk 사용율이 100% 치며 가상머신이 먹통이 된다.
    • c++: Internal compiler error: killed (program cc1plue)

3.2. make install

/usr/local/bin에 빌드된 실행파일들이 복사된다.

4. 테스트

제대로 설치되었는지 확인한다.

4.1. clang 환경 확인

clang은 암묵적으로 헤더를 찾고 있기 때문에 mull 사용 시 명시적인 환경을 확인할 필요가 있다. 아래와 같이 확인 가능한다.

clang -x c -c /dev/null -v

 

clang++ -x c++ -c /dev/null -v

 

4.2. Examples: openssl

Openssl을 대상으로 mull을 테스트해보자.

아래와 같이 수행하라고 되어 있는데, 직접 수행해보면 gcc에 -fembed-bitcode 옵션을 인식하지 못한다.

git clone https://github.com/openssl/openssl.git
cd openssl
./config -no-asm -no-shared -g -O0 -fembed-bitcode
make all

기본 생성된 Makefile로 make하면 -fembed-bitcode 옵션을 인식못한다.

그래서 생성된 Makefile의 2229 / 2230 라인의 gcc / g++을 clang으로 바꿔준다.

(또는 아래와 같이 환경변수로 CC / CXX 를 clang과 clang++을 가르키게 할 수도 있다.

export CC=/media/work/llvm-7.0.1/bin/clang

export CXX=/media/work/llvm-7.0.1/bin/clang++)

 

수정 후 빌드를 시도한다.

 

mull-cxx를 사용하여 Mutation Testing을 시도해본다.

하지만 아래와 같이 특정 Shared Library를 찾지못한다.

shared library를 인식하지 못하여 warning 메시지

ldd를 사용하면 해당 실행파일이 참조하는 Shared Library를 확인할 수 있다.

ldd <실행파일> 을 통해 관련된 shared library 확인 가능

 

-ld-search-path 옵션을 추가하면 아래와 같이 Shared Library 관련 warning을 없앨 수 있다.

status: Crashed

 

 

그런데 정작 Crashed가 나서 결과를 확인하지 못했다.

이유는 아직 찾는 중...

 

4.3. Examples: HelloWorld

mull 프로젝트 하부에 예제로 HelloWorld를 확인할 수 있다. 이를 대상으로 mull을 테스트해보자.

mull/Examples/HelloWorld 에서 찾을 수 있다.

 

Makefile를 열어 아래 $(CXX)를 clang++ 으로 바꾸어주었다. (4.2와 같은 이유이다. -fembed-bitcode 를 g++이 인식하지 못함.)

또한, Shared Library path를 잡기 위해 -ld-search-path로 추가해주었다.

수정된 Makefile

 

콘솔에서 make run_cxx 를 수행하면 아래와 같은 결과를 얻을 수 있다.

HelloWorld에 대한 mull_cxx 결과