【问题标题】:different output for -fsanitize=address with clang++ vs g++-fsanitize=address 与 clang++ 与 g++ 的不同输出
【发布时间】:2018-08-09 19:04:44
【问题描述】:

在下面的代码中我有一个问题。当我给它一个仍然完全为空的向量时,代码会崩溃,因为 vector.size() - 1 不能为负数,因此它会环绕。因为vector是空的,所以访问container[0]是无效的。

using namespace std;

template<typename T, typename A>
std::string vec_to_python_list(
        const std::string& name,
        const vector<T, A>& container
        ) {
    std::stringstream stream(ios::out);
    stream << name << " = [" << '\n';
    for (typename vector<T, A>::size_type i = 0; i < container.size() - 1; i++)
        stream << "\t" << container[i] << ",\n";
    if (name.size() > 0)
        stream << "\t" << container[container.size() - 1] << "\n";
    stream << "]";
    return stream.str();
}

我的问题是关于它产生的输出。

如果我在 Ubuntu-16.04 上使用 g++ 编译

g++ -Wall -Wextra -std=c++14 -g -fsanitize=address -O0  -o test_kmeans test_kmeans.cpp

我得到下一个有用的信息:

#0 0x402a56 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > vec_to_python_list<double, std::allocator<double> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<double, std::allocator<double> > const&) /home/hetepeperfan/programming/cpp/kmeans/test_kmeans.cpp:46
#1 0x401f07 in main /home/hetepeperfan/programming/cpp/kmeans/test_kmeans.cpp:66
#2 0x7f393881f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#3 0x401ba8 in _start (/home/hetepeperfan/programming/cpp/kmeans/test_kmeans+0x401ba8)

但是,如果我使用 clang++ 编译(仍然在 Ubuntu-16.04 上)

clang++ -Wall -Wextra -std=c++14 -g -fsanitize=address -O0  -o test_kmeans test_kmeans.cpp

我得到的结果不太有用:

#0 0x4eecae  (/home/hetepeperfan/programming/cpp/kmeans/test_kmeans+0x4eecae)
#1 0x4ee056  (/home/hetepeperfan/programming/cpp/kmeans/test_kmeans+0x4ee056)
#2 0x7f6ed883a82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#3 0x419838  (/home/hetepeperfan/programming/cpp/kmeans/test_kmeans+0x419838)

我做错了什么,导致带有 -fsanitize=address 的 g++ 起作用,而 clang++ 没有产生有用的结果,似乎没有添加调试符号?

编辑 调试符号似乎存在,因为使用 gdb 我可以轻松地单步执行代码,并且使用 --tui gdb 选项我可以看到我的代码,所以这不是问题。

【问题讨论】:

  • 相关:this
  • @Ripi2 那是苹果的东西。 OP 正在使用 Ubuntu。
  • @melpomene,Ripi2 在撰写本文时并不知道,我稍后将此信息添加到问题中。

标签: c++ gcc clang address-sanitizer


【解决方案1】:

安装 llvm-symbolizer。 还将 ASAN_SYMBOLIZER_PATH 环境变量设置为类似

ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-5.0/bin/llvm-symbolizer

llvm 正在寻找一个名为llvm-symbolizer 而不是llvm-symbolizer-3.8 的可执行文件,这就是为什么环境变量必须指向llvm-symbolizer 一个没有版本号的文件名。如果所有符号的文件名中都有版本号,请创建一个没有版本号的符号链接。

【讨论】:

  • 嗨 michael,感谢您的回答,但是我认为我的路径上有 llvm-symbolizer:$which llvm-symbolizer-3.8 /usr/bin/llvm-symbolizer-3.8 如果我把它放在路径上,我会得到:==25910==ERROR :外部符号器路径设置为“/usr/bin/llvm-symbolizer-3.8”,这不是已知的符号器。请设置 llvm-symbolizer 二进制文件或其他已知工具的路径。
  • 显然,这还不够,因为 llvm 寻找的是llvm-symbolizer 而不是llvm-symbolizer-3.8
  • 感谢您的提示。它现在可以工作了似乎是 Ubuntu-16.04 上的一个小包装问题
  • 很高兴为您提供帮助。我在 YouTube 上 Jason Turner 的“C++ 周刊”中看到了这个技巧。
猜你喜欢
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
相关资源
最近更新 更多