临时字符串上的std :: string_view - 由ASan捕获

vla*_*don 16 c++ sanitizer address-sanitizer c++17

这是悬空指针|参考示例:

#include <string>
#include <string_view>
#include <iostream>

std::string foo() {
    return "test";
}

int main() {
    std::string_view bar = foo(); // bar is pointed to destructed string
    std::cout << bar << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

地址清理程序无法捕获它,至少使用默认选项.是否有可能通过地址消毒剂捕获此类错误?

UPD.

报告了这个bug:

yug*_*ugr 3

我的猜测(您没有提供编译器版本)是operator <<外部实现的,因此 Asan 无法清理它并检测错误(除非您使用 Asan 重建 libstdc++)。这是我使用 GCC 6.2 得到的结果(我稍微修改了重现,因为我无权访问c++1z):

  call    operator delete(void*)
.L17:
  movq    %rbx, %rsi
  movl    std::cout, %edi
  call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
  call    std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
Run Code Online (Sandbox Code Playgroud)

  • @vladon 这是非常不同的情况。只要字符串长度超过 16 个字符,它就适用于我(即报告“释放后堆使用”)。对于较短的字符串,您可以获得 SSO,即数据保留在堆栈上,因此 Asan 无法再检测堆错误。 (2认同)