libstdc++ 文件系统中未初始化的用法?
Uninitialized Usage in libstdc++ filesystem?
考虑以下代码:
#include <filesystem>
int main() {
std::filesystem::path p{"/"};
}
当使用带有标志 -std=c++17 -fsanitize=memory -g -O1 -stdlib=libstdc++
的 clang10 进行编译时,编译完全没问题,但是当 运行 时,内存清理器发现以下错误:
==166467==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x560e38eafc41 in std::basic_ostream<char, std::char_traits<char> >& std::__detail::operator<<<char, std::char_traits<char>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::basic_ostream<char, std::char_traits<char> >&, std::__detail::_Quoted_string<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char> const&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/quoted_string.h:124:32
#1 0x560e38eaf03c in std::basic_ostream<char, std::char_traits<char> >& std::filesystem::__cxx11::operator<<<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::filesystem::__cxx11::path const&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/fs_path.h:441:7
#2 0x560e38eaecdb in main ~/test/test.cpp:15:15
#3 0x7f5d0fa58001 in __libc_start_main (/usr/lib/libc.so.6+0x27001)
#4 0x560e38e3033d in _start (~/test/a.out+0x2133d)
SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/quoted_string.h:124:32 in std::basic_ostream<char, std::char_traits<char> >& std::__detail::operator<<<char, std::char_traits<char>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::basic_ostream<char, std::char_traits<char> >&, std::__detail::_Quoted_string<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char> const&)
Exiting
当使用 -stdlib=libc++
编译时,它工作得很好。另请参阅 godbolt(遗憾的是,那里的 msan 输出有点非描述性)。
内存清理程序是过分热心还是出了什么问题?我简要地查看了有问题的文件和代码
for (auto __c : __str._M_string)
{
if (__c == __str._M_delim || __c == __str._M_escape) // <- line 124
__ostr << __str._M_escape;
__ostr << __c;
}
对我来说似乎没问题(__str
是 std::__detail::_Quoted_string<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&
类型,它只有一个用户定义的构造函数,该值从参数初始化所有三个成员。
clang++ -v
的输出:
clang version 10.0.0
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
这是误报。
您应该将其报告为 Sanitizer 错误;它似乎类似于 issue 1238.
考虑以下代码:
#include <filesystem>
int main() {
std::filesystem::path p{"/"};
}
当使用带有标志 -std=c++17 -fsanitize=memory -g -O1 -stdlib=libstdc++
的 clang10 进行编译时,编译完全没问题,但是当 运行 时,内存清理器发现以下错误:
==166467==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x560e38eafc41 in std::basic_ostream<char, std::char_traits<char> >& std::__detail::operator<<<char, std::char_traits<char>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::basic_ostream<char, std::char_traits<char> >&, std::__detail::_Quoted_string<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char> const&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/quoted_string.h:124:32
#1 0x560e38eaf03c in std::basic_ostream<char, std::char_traits<char> >& std::filesystem::__cxx11::operator<<<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::filesystem::__cxx11::path const&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/fs_path.h:441:7
#2 0x560e38eaecdb in main ~/test/test.cpp:15:15
#3 0x7f5d0fa58001 in __libc_start_main (/usr/lib/libc.so.6+0x27001)
#4 0x560e38e3033d in _start (~/test/a.out+0x2133d)
SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/quoted_string.h:124:32 in std::basic_ostream<char, std::char_traits<char> >& std::__detail::operator<<<char, std::char_traits<char>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::basic_ostream<char, std::char_traits<char> >&, std::__detail::_Quoted_string<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char> const&)
Exiting
当使用 -stdlib=libc++
编译时,它工作得很好。另请参阅 godbolt(遗憾的是,那里的 msan 输出有点非描述性)。
内存清理程序是过分热心还是出了什么问题?我简要地查看了有问题的文件和代码
for (auto __c : __str._M_string)
{
if (__c == __str._M_delim || __c == __str._M_escape) // <- line 124
__ostr << __str._M_escape;
__ostr << __c;
}
对我来说似乎没问题(__str
是 std::__detail::_Quoted_string<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&
类型,它只有一个用户定义的构造函数,该值从参数初始化所有三个成员。
clang++ -v
的输出:
clang version 10.0.0
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
这是误报。
您应该将其报告为 Sanitizer 错误;它似乎类似于 issue 1238.