備注:在安裝klee調(diào)試版本的過程中永高,遇到很多問題,將其略微整理了下库物,供后來人參考粘茄。
安裝LLVM等配套軟件
- 此過程詳見文檔Building KLEE (LLVM 3.4)
- 以下只記錄在操作"Working with KLEE source code"中"Setting up a debug build of KLEE"一節(jié)時(shí),我遇到的問題.
配置configure
- configure的前后可以添加什么參數(shù),其實(shí)是可以在configure文件中查到的
- 執(zhí)行configure配置命令
configure命令:
CXXFLAGS="-g -O0" CFLAGS="-g -O0" LDFLAGS="-ldl -pthread -ltinfo" ./configure with_llvm_build_mode="check" LLVM_BUILD_MODE="Debug" --with-llvmsrc=../llvm-3.4-src --with-llvmobj="/home/ccc/program/llvm-3.4-build/" --with-stp=../stp --with-llvmcxx=/home/ccc/program/llvm-3.4-install/bin/clang++ --with-llvmcc=/home/ccc/program/llvm-3.4-install/bin/clang --with-uclibc=/home/ccc/program/klee-uclibc --enable-posix-runtime --with-runtime=Debug+Asserts
出錯(cuò) "configure: error: Could not autodetect build mode",在configure文件中搜索相應(yīng)的字符串,找到如下代碼
if test X${with_llvm_build_mode} = Xcheck ; then
llvm_configs="`ls -1 $llvm_obj/*/bin/llvm-config 2>/dev/null | head -n 1`"
if test -x "$llvm_configs" ; then
llvm_build_mode="`$llvm_configs --build-mode`"
else
as_fn_error $? "Could not autodetect build mode" "$LINENO" 5
fi
else
llvm_configs="`echo $llvm_obj/*/bin/llvm-config`"
if test -x "$llvm_obj/$with_llvm_build_mode/bin/llvm-config" ; then
llvm_build_mode=$with_llvm_build_mode
else
as_fn_error $? "Invalid build mode: $llvm_build_mode" "$LINENO" 5
fi
fi
這是由于"ls -1 $llvm_obj/*/bin/llvm-config 2" 無法返回正確結(jié)果,修改為"ls -1 $llvm_obj/bin/llvm-config 2"
再次執(zhí)行configure命令,出現(xiàn)錯(cuò)誤"checking C LLVM Bitcode compiler works... configure: error: Could not find llvm-dis
",搜索該字符串,根據(jù)相關(guān)的if邏輯,找到代碼:
if test -x "$llvm_obj/$llvm_build_mode/bin/llvm-dis" ; then
這是由于我機(jī)器上的$llvm_obj的目錄機(jī)構(gòu)中,bin文件夾上層沒有$llvm_build_mode目錄,為此替換所有的"$llvm_build_mode/bin/"為"bin/"
再次執(zhí)行configure命令,無報(bào)錯(cuò)結(jié)束.
編譯連接過程make
發(fā)現(xiàn)生成的是Release+Asserts文件夾,而不是我期望的Debug+Asserts,并且出現(xiàn)"/home/ccc/program/klee-ccc/Makefile.rules:934: *** llvm-config --libs failed. Stop.",去Makefile.rules的934行,根據(jù)邏輯上溯,發(fā)現(xiàn)
LLVMLibDir := $(LLVM_OBJ_ROOT)/$(LLVM_BUILD_MODE)/lib
LLVMToolDir := $(LLVM_OBJ_ROOT)/$(LLVM_BUILD_MODE)/bin
LLVMExmplDir:= $(LLVM_OBJ_ROOT)/$(LLVM_BUILD_MODE)/examples
這還是和之前遇到找不到llvm-config一樣的問題,修改為
LLVMLibDir := $(LLVM_OBJ_ROOT)/lib
LLVMToolDir := $(LLVM_OBJ_ROOT)/bin
LLVMExmplDir:= $(LLVM_OBJ_ROOT)/examples
再次make,成功編譯,但出現(xiàn)鏈接錯(cuò)誤
...
make[2]: Entering directory `/home/ccc/program/klee-ccc/tools/klee'
llvm[2]: Compiling Debug.cpp for Release+Asserts build
llvm[2]: Compiling main.cpp for Release+Asserts build
llvm[2]: Linking Release+Asserts executable klee (without symbols)
/home/ccc/program/llvm-3.4-build/lib/libLLVMSupport.a(DynamicLibrary.cpp.o): In function `llvm::sys::DynamicLibrary::getPermanentLibrary(char const*, std::string*)':
/home/ccc/program/llvm-3.4-src/lib/Support/DynamicLibrary.cpp:60: undefined reference to `dlopen'
/home/ccc/program/llvm-3.4-src/lib/Support/DynamicLibrary.cpp:62: undefined reference to `dlerror'
/home/ccc/program/llvm-3.4-src/lib/Support/DynamicLibrary.cpp:79: undefined reference to `dlclose'
/home/ccc/program/llvm-3.4-build/lib/libLLVMSupport.a(DynamicLibrary.cpp.o): In function `llvm::sys::DynamicLibrary::getAddressOfSymbol(char const*)':
/home/ccc/program/llvm-3.4-src/lib/Support/DynamicLibrary.cpp:87: undefined reference to `dlsym'
/home/ccc/program/llvm-3.4-build/lib/libLLVMSupport.a(DynamicLibrary.cpp.o): In function `llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(char const*)':
/home/ccc/program/llvm-3.4-src/lib/Support/DynamicLibrary.cpp:128: undefined reference to `dlsym'
/home/ccc/program/llvm-3.4-build/lib/libLLVMSupport.a(Process.cpp.o): In function `terminalHasColors':
/home/ccc/program/llvm-3.4-src/lib/Support/Unix/Process.inc:273: undefined reference to `setupterm'
/home/ccc/program/llvm-3.4-src/lib/Support/Unix/Process.inc:291: undefined reference to `tigetnum'
/home/ccc/program/llvm-3.4-src/lib/Support/Unix/Process.inc:295: undefined reference to `set_curterm'
/home/ccc/program/llvm-3.4-src/lib/Support/Unix/Process.inc:296: undefined reference to `del_curterm'
/home/ccc/program/llvm-3.4-build/lib/libLLVMSupport.a(Signals.cpp.o): In function `llvm::sys::PrintStackTrace(_IO_FILE*)':
/home/ccc/program/llvm-3.4-src/lib/Support/Unix/Signals.inc:278: undefined reference to `dladdr'
/home/ccc/program/llvm-3.4-src/lib/Support/Unix/Signals.inc:290: undefined reference to `dladdr'
collect2: error: ld returned 1 exit status
make[2]: *** [/home/ccc/program/klee-ccc/Release+Asserts/bin/klee] Error 1
make[2]: Leaving directory `/home/ccc/program/klee-ccc/tools/klee'
make[1]: *** [klee/.makeall] Error 2
make[1]: Leaving directory `/home/ccc/program/klee-ccc/tools'
make: *** [all] Error 1
這些鏈接的庫其實(shí)再configure命令中其實(shí)已經(jīng)賦值了,該命令會修改Makefile.config相應(yīng)變量為"LDFLAGS := -ldl -pthread -ltinfo -g",為什么還有這個(gè)錯(cuò)誤,說明makefile之間的連接存在問題(這是經(jīng)過1天半時(shí)間不斷的折騰才發(fā)現(xiàn)的),去往tools/klee/makefile,在文件中添加"LIBS += $(LDFLAGS)"
再次make,發(fā)現(xiàn)tools/klee連接聰哥了,但是tools/kleaver出現(xiàn)了同樣的鏈接錯(cuò)誤,去往tools/kleaver/makefile,在文件中添加"LIBS += $(LDFLAGS)",再次make,成功!,再次回到上面遺留的一個(gè)問題,為什么生成了完整的Release+Asserts文件夾,而Debug+Asserts文件夾中只有l(wèi)ib文件夾,lib文件夾中的文件還是殘缺的,Release+Asserts中klee程序是release版還是debug版?
-
Debug版在哪?
- 首先這是鏈接過程配置問題,根據(jù)make輸出中的"(without symbols)"信息,我們搜索此字符串,在Makefile.rules中發(fā)現(xiàn)代碼段
ifndef KEEP_SYMBOLS Strip := $(PLATFORMSTRIPOPTS) StripWarnMsg := "(without symbols)" Install.StripFlag += -s endif
查看KEEP_SYMBOLS的繼承關(guān)系,通過打印"$(info $(ENABLE_OPTIMIZED))",發(fā)現(xiàn)該值有時(shí)候?yàn)?,有時(shí)候?yàn)?,在Makefile.common中有"override ENABLE_OPTIMIZED := $(RUNTIME_ENABLE_OPTIMIZED)",在configure文件中會根據(jù)${with_runtime} 給其賦值
# Check whether --with-runtime was given. if test "${with_runtime+set}" = set; then : withval=$with_runtime; else withval=default fi if test X"${withval}" = Xdefault; then with_runtime=Release+Asserts fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking runtime configuration" >&5 $as_echo_n "checking runtime configuration... " >&6; } if test X${with_runtime} = XRelease; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: Release" >&5 $as_echo "Release" >&6; } RUNTIME_ENABLE_OPTIMIZED=1 RUNTIME_DISABLE_ASSERTIONS=1 RUNTIME_DEBUG_SYMBOLS= elif test X${with_runtime} = XRelease+Asserts; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: Release+Asserts" >&5 $as_echo "Release+Asserts" >&6; } RUNTIME_ENABLE_OPTIMIZED=1 RUNTIME_DISABLE_ASSERTIONS=0 RUNTIME_DEBUG_SYMBOLS= elif test X${with_runtime} = XDebug; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: Debug" >&5 $as_echo "Debug" >&6; } RUNTIME_ENABLE_OPTIMIZED=0 RUNTIME_DISABLE_ASSERTIONS=1 RUNTIME_DEBUG_SYMBOLS=1 elif test X${with_runtime} = XDebug+Asserts; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: Debug+Asserts" >&5 $as_echo "Debug+Asserts" >&6; } RUNTIME_ENABLE_OPTIMIZED=0 RUNTIME_DISABLE_ASSERTIONS=0 RUNTIME_DEBUG_SYMBOLS=1 else as_fn_error $? "invalid configuration: ${with_runtime}" "$LINENO" 5 fi
但是打印$withval,結(jié)果是"Debug+Asserts",繼續(xù)找RUNTIME_ENABLE_OPTIMIZED和ENABLE_OPTIMIZED的值定義,在Makefile.common中發(fā)現(xiàn)include $(LLVM_OBJ_ROOT)/Makefile.config,在該文件中發(fā)現(xiàn)
# When ENABLE_OPTIMIZED is enabled, LLVM code is optimized and output is put
# into the "Release" directories. Otherwise, LLVM code is not optimized and
# output is put in the "Debug" directories.
#ENABLE_OPTIMIZED = 1
ENABLE_OPTIMIZED=1
原來該llvmobj直接設(shè)置為了優(yōu)化模式,這也是KLEE官方文檔"Working with KLEE source code"中提到的
Note that KLEE depends on LLVM and STP. If you need to debug KLEE’s calls to that code, then you will need to build LLVM/STP with debug support too
我其實(shí)早注意這句,也重新編譯過LLVM,并且在本llvmobj中bin目錄下運(yùn)行l(wèi)lvm-config --build-mode,返回的也是"Debgu"值,這2者為什么不一致?這個(gè)問題先放一放,將上面的ENABLE_OPTIMIZED=1修改為0,重新make,成功生成完整的Debug+Asserts.
補(bǔ)充點(diǎn)知識
在configrue文件中打印語句:
echo ==============1=============
echo $變量
在makefile中打印
$(info $(VARNAME))
$(warning
$(error
$(echo )