GCC:对“ __asan_init_v1”的未定义引用

时间:2019-03-25 10:04:32

标签: gcc cmake c99

我想用标志-fsanitize=address编译C99项目。我需要使用CMake并在Centos 7发行版上使用gcc进行编译。

我目前有 gcc 7.3.1 cmake 3.13.4

我在编译标志列表和链接器中添加了-fsanitize=address标志,但是仍然无法编译,并出现以下错误:

[ 6%] Building C object CMakeFiles/last.dir/src/ast/ast.c.o
[ 13%] Building C object CMakeFiles/last.dir/src/ast/ast_printer.c.o
[ 20%] Building C object CMakeFiles/last.dir/src/ast/cleaner.c.o
[ 26%] Linking C static library liblast.a
[ 26%] Built target last
[ 33%] Building C object CMakeFiles/lexecution.dir/src/execution/exec_parser.c.o
[ 40%] Building C object CMakeFiles/lexecution.dir/src/execution/exec_utils.c.o
[ 46%] Building C object CMakeFiles/lexecution.dir/src/execution/exec_func.c.o
[ 53%] Building C object CMakeFiles/lexecution.dir/src/execution/exec_parser_options.c.o
[ 60%] Linking C static library liblexecution.a
[ 60%] Built target lexecution
[ 66%] Building C object CMakeFiles/lutils.dir/tests/utils/utils.c.o
[ 73%] Linking C static library liblutils.a
[ 73%] Built target lutils
[ 80%] Building C object CMakeFiles/lhist.dir/src/history/history.c.o
[ 86%] Linking C static library liblhist.a
[ 86%] Built target lhist
[ 93%] Building C object CMakeFiles/42sh.dir/src/execution/exec_42sh.c.o
[100%] Linking C executable 42sh
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libasan_preinit.o:(.preinit_array+0x0) : undefined reference to « __asan_init_v1 »
CMakeFiles/42sh.dir/src/execution/exec_42sh.c.o : In function « _GLOBAL__sub_I_00099_1_flag » :
/home/lyro/Documents/customshell/src/execution/exec_42sh.c:304 : undefined reference to « __asan_init_v1 »
liblexecution.a(exec_parser.c.o) : In function « _GLOBAL__sub_I_00099_1_parser_new_from_string » :
/home/lyro/Documents/customshell/src/execution/exec_parser.c:1105 : undefined reference to « __asan_init_v1 »
liblexecution.a(exec_utils.c.o) : In function « _GLOBAL__sub_I_00099_0_get_args_array » :
/home/lyro/Documents/customshell/src/execution/exec_utils.c:242 : undefined reference to « __asan_init_v1 »
liblexecution.a(exec_func.c.o) : In function « _GLOBAL__sub_I_00099_1_exec_ast » :
/home/lyro/Documents/customshell/src/execution/exec_func.c:187 : undefined reference to « __asan_init_v1 »
liblexecution.a(exec_parser_options.c.o):/home/lyro/Documents/customshell/src/execution/exec_parser_options.c:149 : more undefined references to « __asan_init_v1 »
collect2: error: ld returned 1 execution state code
make[2]: *** [42sh] Error 1
make[1]: *** [CMakeFiles/42sh.dir/all] Error 2
make: *** [all] Error 2

这是我的CMakeLists.txt文件,我找不到我想要的文件。

cmake_minimum_required(VERSION 3.0)
project(42SH LANGUAGES C)
add_compile_options(-Wall -Wextra -Werror -pedantic -fsanitize=address -g -std=c99)

add_library(last ${CMAKE_SOURCE_DIR}/src/ast/ast.c ${CMAKE_SOURCE_DIR}/src/ast/ast_printer.c ${CMAKE_SOURCE_DIR}/src/ast/cleaner.c)
target_include_directories(last PUBLIC ${CMAKE_SOURCE_DIR}/src/ast)

add_library(lutils ${CMAKE_SOURCE_DIR}/tests/utils/utils.c)
target_include_directories(lutils PUBLIC ${CMAKE_SOURCE_DIR}/tests/utils)
target_link_libraries(lutils -fsanitize=address lexecution)

add_library(lexecution ${CMAKE_SOURCE_DIR}/src/execution/exec_parser.c ${CMAKE_SOURCE_DIR}/src/execution/exec_utils.c ${CMAKE_SOURCE_DIR}/src/execution/exec_func.c ${CMAKE_SOURCE_DIR}/src/execution/exec_parser_options.c)
target_include_directories(lexecution PUBLIC ${CMAKE_SOURCE_DIR}/src/ast)
target_link_libraries(lexecution -fsanitize=address last)

add_library(lhist ${CMAKE_SOURCE_DIR}/src/history/history.c)
target_include_directories(lhist PUBLIC ${CMAKE_SOURCE_DIR}/src/history)

add_executable(42sh src/execution/exec_42sh.c)
target_link_libraries(42sh -fsanitize=address lexecution)
target_link_libraries(42sh -fsanitize=address lutils)
target_link_libraries(42sh -fsanitize=address last)
target_link_libraries(42sh -fsanitize=address lhist)

add_custom_target(submit
    COMMENT "Compiled for submission. Sanitizers ON."
    COMMENT "Don't use Valgrind on this executable. It will not work."
    DEPENDS 42sh
)

add_custom_target(tests
    COMMAND pytest ${CMAKE_SOURCE_DIR}/tests
    COMMENT "Running testsuite..."
    DEPENDS 42sh
)

add_custom_target(doc
    COMMENT "Compiling  documentation"
    COMMAND doxygen ${CMAKE_SOURCE_DIR}/doc/Doxyfile
    COMMENT "Compiled documentation"
)

1 个答案:

答案 0 :(得分:2)

您的工具链对于GCC是哪个版本以及 链接失败是这种混乱的结果。

您告诉我们您使用的是GCC 7.3.1,但是未解析的对__asan_init_v1的引用中的第一个:

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libasan_preinit.o:(.preinit_array+0x0) : undefined reference to « __asan_init_v1

表明调用gcc的链接的-fsanitize=address链接了地址修饰符初始化代码 从安装GCC 4.8.5开始。

在GCC 7中,文件libasan_preinit.o没有引用__asan_init_v1,如 我现在正在使用的笔记本电脑:

$ nm /usr/lib/gcc/x86_64-linux-gnu/7/libasan_preinit.o
                 U __asan_init
0000000000000000 D __local_asan_preinit

它调用__asan_init,它确实在工具链的libasan中定义:

$ nm -D /usr/lib/gcc/x86_64-linux-gnu/7/libasan.so | grep __asan_init
00000000000ecdb0 T __asan_init

另一方面,在GCC 4.8.5中,libasan并未 定义函数__asan_init did 定义__asan_init_v1

:~/Downloads/gcc-4.8.5$ grep -r '__asan_init_v'
gcc/ChangeLog:  * sanitizer.def: Rename __asan_init to __asan_init_v1.
gcc/sanitizer.def:DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v1",
libsanitizer/asan/asan_interface_internal.h:  void __asan_init_v1() SANITIZER_INTERFACE_ATTRIBUTE;
libsanitizer/asan/asan_interface_internal.h:  #define __asan_init __asan_init_v1

那里,__asan_init只是内部#define的别名,它是实函数__asan_init_v1的别名,例如 每个libsanitizer/asan/asan_interface_internal.h,但在that file in GCC 7

  // This function should be called at the very beginning of the process,
  // before any instrumented code is executed and before any call to malloc.
  SANITIZER_INTERFACE_ATTRIBUTE void __asan_init();

它是一个实函数,如nm所述。

因此,证据的重点是您与GCC 7.3.1的libasan相关联 而且还链接了GCC 4.8.5的库初始化代码。我看不到 就我所知,您是如何参与此GCC版本混搭的-可能是打包错误-但 您必须解决该问题才能解决这些链接失败。