【问题标题】:clang crashes with char * exception in std::asyncclang 在 std::async 中因 char * 异常而崩溃
【发布时间】:2019-11-29 18:41:22
【问题描述】:

我在使用 clang++ 编译以下代码时遇到了崩溃:

#include <future>
#include <iostream>

int main() {
    auto job = [] { throw "failed"; };

    auto f = std::async(std::launch::deferred, job);

    try {
        f.get();
    } catch (const char *&e) {
        std::cout << "boom! " << e << '\n';
    }
}

我必须说我看不出有什么不好的,并且使用 g++ 编译并将 valgrind 传递给 resutling 二进制文件是可以的。

也就是说,使用 clang 编译时:

clang++ sample.cpp -pthread -Wall -Werror

我没有收到任何错误,但 valgrind 抱怨:

==10241== Invalid read of size 8
==10241==    at 0x401E74: main (in /tmp/a.out)
==10241==  Address 0x5d67e90 is 0 bytes after a block of size 112 alloc'd
==10241==    at 0x4C2EE3B: malloc (vg_replace_malloc.c:309)
==10241==    by 0x4ECCE31: __cxa_allocate_dependent_exception (in /usr/lib64/libstdc++.so.6.0.25)
==10241==    by 0x4ECDF46: std::rethrow_exception(std::__exception_ptr::exception_ptr) (in /usr/lib64/libstdc++.so.6.0.25)
==10241==    by 0x405075: std::__basic_future<void>::_M_get_result() const (in /tmp/a.out)
==10241==    by 0x404F6C: std::future<void>::get() (in /tmp/a.out)
==10241==    by 0x401E10: main (in /tmp/a.out)
==10241== 
boom! ==10241== 

当我使用 libc++ 编译时,二进制文件崩溃了:

clang++ -stdlib=libc++ sample.cpp -pthread -Wall -Werror

$ ./a.out 
Segmentation fault (core dumped)

而 valgrind 说:

==10334== 
==10334== Invalid read of size 8
==10334==    at 0x401834: main (in /tmp/a.out)
==10334==  Address 0x60c02a0 is 0 bytes after a block of size 128 alloc'd
==10334==    at 0x4C3147C: memalign (vg_replace_malloc.c:908)
==10334==    by 0x4C31589: posix_memalign (vg_replace_malloc.c:1072)
==10334==    by 0x5121AA0: ??? (in /usr/lib64/libc++abi.so.1.0)
==10334==    by 0x5123BFA: __cxa_rethrow_primary_exception (in /usr/lib64/libc++abi.so.1.0)
==10334==    by 0x4E7D678: std::rethrow_exception(std::exception_ptr) (in /usr/lib64/libc++.so.1.0)
==10334==    by 0x4E7E0F4: std::__1::__assoc_sub_state::copy() (in /usr/lib64/libc++.so.1.0)
==10334==    by 0x4E7E425: std::__1::future<void>::get() (in /usr/lib64/libc++.so.1.0)
==10334==    by 0x4017D0: main (in /tmp/a.out)
==10334== 
==10334== Invalid read of size 1
==10334==    at 0x4C32256: strlen (vg_replace_strmem.c:461)
==10334==    by 0x403DA4: std::__1::char_traits<char>::length(char const*) (in /tmp/a.out)
==10334==    by 0x40373B: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) (in /tmp/a.out)
==10334==    by 0x40183F: main (in /tmp/a.out)
==10334==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10334== 
==10334== 
==10334== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==10334==  Access not within mapped region at address 0x0
==10334==    at 0x4C32256: strlen (vg_replace_strmem.c:461)
==10334==    by 0x403DA4: std::__1::char_traits<char>::length(char const*) (in /tmp/a.out)
==10334==    by 0x40373B: std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) (in /tmp/a.out)
==10334==    by 0x40183F: main (in /tmp/a.out)
==10334==  If you believe this happened as a result of a stack
==10334==  overflow in your program's main thread (unlikely but
==10334==  possible), you can try to increase the size of the
==10334==  main thread stack using the --main-stacksize= flag.
==10334==  The main thread stack size used in this run was 8388608.
boom! ==10334== 

这里有什么问题? 在异步中使用 const char * 异常可以吗

附加信息:

$ clang++ --version
clang version 6.0.1 (tags/RELEASE_601/final)

更新: 我用各种版本的clang进行了测试,它总是在clang中崩溃。 最后测试的版本是 10.0.0,仍然崩溃...

【问题讨论】:

  • 对我来说看起来像一个铿锵虫。对我来说,当它没有崩溃时,它只会打印“boom!”没有“失败”。

标签: c++ c++11 exception


【解决方案1】:

在安装 clang 之后,我和 n.m 的情况相同(谁知道重新安装可能是一个解决方案)。 至于未打印的消息“失败!”,我已将第 11 行替换为以下内容:

    } catch (const char* e) {

【讨论】:

  • 感谢您的解决方法,但这是否意味着我的代码有误?
  • 其实只是因为 const char* e 已经是一个指针了。所以添加一个引用 (const char* &e) 会给出一个不是 const char* 的其他对象。仅供参考,我使用 clang 版本 8.0.0。
  • “谁知道重新安装可能是一个解决方案” - 为什么重新安装是一个解决方案?除非您知道具体原因为什么这会解决任何问题,否则这只是猜测(这不是解决问题的方法)。解决问题的方法是找出问题的根本原因,然后根据实际的知识进行修复。请不要只猜测修复。
猜你喜欢
  • 2014-04-10
  • 1970-01-01
  • 2013-10-08
  • 2022-01-08
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
相关资源
最近更新 更多