-fsanitize=address 使用 clang++ 与 g++ 的不同输出
different output for -fsanitize=address with clang++ vs g++
在下面的代码中我遇到了问题。当我给它一个仍然完全为空的向量时,代码崩溃,因为 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 选项我可以看到我的代码,所以这不是问题。
安装 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
没有版本号的文件名的原因。如果所有符号器的文件名中都有版本号,请制作一个没有版本号的符号 link。
在下面的代码中我遇到了问题。当我给它一个仍然完全为空的向量时,代码崩溃,因为 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 选项我可以看到我的代码,所以这不是问题。
安装 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
没有版本号的文件名的原因。如果所有符号器的文件名中都有版本号,请制作一个没有版本号的符号 link。