1. 개요
C/C++ 대상으로 Mutation Testing 엔진을 찾고 있었는데, 그 중 하나가 Mull 이다.
LLVM의 IR을 대상으로 하여 C/C++은 물론 다른 언어도 목표로 두고 있다.
관련 논문(Link)은 다음을 참고한다.
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 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 ..
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의 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를 찾지못한다.
ldd를 사용하면 해당 실행파일이 참조하는 Shared Library를 확인할 수 있다.
-ld-search-path 옵션을 추가하면 아래와 같이 Shared Library 관련 warning을 없앨 수 있다.
그런데 정작 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로 추가해주었다.
콘솔에서 make run_cxx 를 수행하면 아래와 같은 결과를 얻을 수 있다.