【问题标题】:GCC : undefined reference to "__asan_init_v1"GCC:对“__asan_init_v1”的未定义引用
【发布时间】:2019-03-25 10:04:31
【问题描述】:

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

我目前有 gcc 7.3.1cmake 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"
)

【问题讨论】:

    标签: gcc cmake c99


    【解决方案1】:

    您的工具链对于它是哪个版本的 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
    

    显示调用与-fsanitize=address 的链接的gcc 链接了地址清理程序初始化代码 从您安装的 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 并且确实定义了__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 版本混搭的——据我所知,这可能是一个打包错误——但是 您必须修复它才能解决这些链接故障。

    【讨论】:

    • 感谢这个非常准确和清晰的答案。我刚刚在我的笔记本电脑上卸载了所有 gcc 版本并完成了 gcc 的全新安装,现在效果很好。
    • @Louis'LYRO'Dupont 很高兴听到这个消息。
    猜你喜欢
    • 2018-05-07
    • 2017-10-26
    • 1970-01-01
    • 2019-08-10
    • 2015-08-23
    • 1970-01-01
    • 2014-04-21
    • 2012-12-12
    • 2019-05-05
    相关资源
    最近更新 更多