在以下代码中,我遇到了问题。当我给它一个仍然完全为空的向量时,代码会崩溃,因为vector.size()-1不能为负,因此它会回绕。由于向量为空,因此访问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选项,我可以看到我的代码,所以这不是问题。

最佳答案

安装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一个没有版本号的文件名的原因。如果您所有的符号化程序的文件名中都有版本号,请创建一个没有版本号的符号链接。

关于c++ - clang++与g++的-fsanitize = address的不同输出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51774151/

10-11 16:24