使用clang和libc++时无法链接libFuzzer.a

3
我正在尝试链接以下内容:
  • 使用clang++-5.0和-std=c++11编译的libFuzzer.a
  • 使用clang++-5.0和-std=c++11 -stdlib=libc++编译的我的fuzz driver
  • 使用clang-5.0编译的libcurl
具体而言,执行以下链接器命令:

/bin/bash ../../libtool --silent --tag=CXX --mode=link clang++-5.0 -I../../include -I../../lib -I../../lib -I../../tests/fuzz -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -std=c++11 -stdlib=libc++ -o curl_fuzzer curl_fuzzer-curl_fuzzer.o ../../lib/libcurl.la /root/checkouts/Fuzzer/libFuzzer.a -lssh2 -lssl -lcrypto -lssl -lcrypto -lz -lpthread -lm

执行此命令将输出以下结果:
/bin/bash ../../libtool --silent --tag=CXX   --mode=link clang++-5.0 -I../../include -I../../lib -I../../lib -I../../tests/fuzz -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -std=c++11 -stdlib=libc++   -o curl_fuzzer curl_fuzzer-curl_fuzzer.o ../../lib/libcurl.la /root/checkouts/Fuzzer/libFuzzer.a  -lssh2 -lssl -lcrypto -lssl -lcrypto -lz -lpthread -lm > /tmp/cat.txt 2>&1; head -20 /tmp/cat.txt
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `fuzzer::FileToVector(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, bool)':
/root/checkouts/Fuzzer/./FuzzerIO.cpp:34: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:40: undefined reference to `std::istream::seekg(long, std::_Ios_Seekdir)'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:41: undefined reference to `std::istream::tellg()'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:47: undefined reference to `std::istream::seekg(long, std::_Ios_Seekdir)'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:49: undefined reference to `std::istream::read(char*, long)'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ifstream':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `VTT for std::basic_ifstream<char, std::char_traits<char> >'
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ios':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/basic_ios.h:282: undefined reference to `std::ios_base::~ios_base()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ifstream':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `VTT for std::basic_ifstream<char, std::char_traits<char> >'
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ios':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/basic_ios.h:282: undefined reference to `std::ios_base::~ios_base()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `fuzzer::FileToString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
/root/checkouts/Fuzzer/./FuzzerIO.cpp:54: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ifstream':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `VTT for std::basic_ifstream<char, std::char_traits<char> >'
<snip>

我已尝试以下方法来解决此问题:

  • 添加-lc++ - 没有任何作用
  • 添加-lc++abi - 没有任何作用

感觉好像漏掉了什么显而易见的东西,但我不确定是什么...

我的clang-5.0安装来自于clang-5.0/kali-rolling


在某些情况下,可以在同一个程序中同时使用libc++和libstdc++...但是您必须确保大多数类型永远不会跨越边界传递。 - o11c
但是说真的,只需使用libstdc++。除了苹果,没有人使用libc++。 - o11c
3个回答

1
你已经使用libstdc++和libc++编译了代码的一部分。当你将它们链接在一起(使用libc++)时,那些引用到libstdc++的部分无法解析。
例如,std::__cxx11::basic_string明显是一个libstdc++符号。

0

看起来由于某种原因,Kali 的 clang-5.0 版本无法正确地将二进制文件链接到 libc++。 我使用 Google 的 ossfuzz 版本的 clang(clang-6.0)测试了相同的代码,一切都成功地链接在了一起。


0

原帖中提到(2017年):

不知是何原因,kali版本的clang-5.0无法正确地将二进制文件与libc++链接起来。
我使用谷歌的ossfuzz版本的clang(clang-6.0)测试了相同的代码,一切都成功地链接在一起。

当时需要使用libstdc++
但现在,根据当前LibFuzzer文档(2021年3月)

最新版本的Clang(从6.0开始)已包含libFuzzer,无需额外安装。

作为对这种新用法(“新”指的是“CLang 5”之后)的说明,Git 2.31.1(2021年第一季度)引用了相同的LibFuzzer 11.0文档部分

请查看 提交 68b5c3a(2021年3月8日)由Andrzej Hunt (ahunt)提交。
(由Junio C Hamano -- gitster --合并于提交 af10702,2021年3月19日)

Makefile:更新“make fuzz-all”文档以反映现代clang

签署者:Andrzej Hunt

Clang不再生成libFuzzer.a
相反,您可以使用-fsanitize=fuzzer来包含libFuzzer。
因此,在构建模糊测试器的示例命令中,我们应该使用它。
我们还将-fsanitize-coverage=trace-pc-guard删除,因为它已被弃用,并在CFLAGS中添加-fsanitize=fuzzer-no-link以确保在编译git 1时添加所有必需的插装。
我恰好使用LLVM 11进行了测试,但是-fsanitize=fuzzer似乎适用于各种相当现代的clang版本。
(在我的系统上:曾经的libFuzzer.a现在位于以下路径下,对于像我这样的新手来说有些棘手但并非不可能找到:
/usr/lib64/clang/11.0.0/lib/linux/libclang_rt.fuzzer-x86_64.a)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接