eyalz800 / zpp_throwing

Using coroutines to implement C++ exceptions for freestanding environments
MIT License
73 stars 4 forks source link

ASAN failure in destruction.with_exception with libc++-18 #10

Closed piotrrak closed 1 year ago

piotrrak commented 1 year ago

Hello again,

So, it seems we're allocating memory for an exception as throwing<void, void> but trying to free it as throwing<void, std::allocator<?>>?

I see we will be using std::allocator_traits<void> anyhow for promise allocation and how the exception is allocated by operator new, but don't see how exception_object_delete<void> does anything else than delete here.

Please see log below:

~/tinker/zpp_throwing-upstream/test  ➦ 5576687  ./out/debug/default/output --gtest_filter=destruction.with_exception --gtest_color=no
Running main() from src/gtest/src/gtest_main.cc
Note: Google Test filter = destruction.with_exception
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from destruction
[ RUN      ] destruction.with_exception
=================================================================
==7196==ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new vs free) on 0x504000002490
    #0 0x55cdead86ba6 in free (/home/prak/tinker/zpp_throwing-upstream/test/out/debug/default/output+0xe8ba6) (BuildId: 17a2985e6b792e85800559727365fceef932d013)
    #1 0x7f1f24db2134 in std::range_error::~range_error() (/lib/x86_64-linux-gnu/libc++abi.so.1+0x25134) (BuildId: 4a8d565301c3486aed798c5488475b519bc0a363)
    #2 0x55cdeadcbc66 in auto zpp::exit_condition<void, void>::exit_with_exception<std::runtime_error>(std::runtime_error&&)::exception_holder::~exception_holder() /home/prak/tinker/zpp_throwing-upstream/test/./include/../../zpp_throwing.h:787:50
    #3 0x55cdeadcbc66 in auto zpp::exit_condition<void, void>::exit_with_exception<std::runtime_error>(std::runtime_error&&)::exception_holder::~exception_holder() /home/prak/tinker/zpp_throwing-upstream/test/./include/../../zpp_throwing.h:787:50
    #4 0x55cdeadc5e16 in zpp::exception_object_delete<void>::operator()(zpp::exception_object*) /home/prak/tinker/zpp_throwing-upstream/test/./include/../../zpp_throwing.h:358:13
    #5 0x55cdeadc5e16 in std::__1::unique_ptr<zpp::exception_object, zpp::exception_object_delete<void>>::reset[abi:v180000](zpp::exception_object*) /usr/lib/llvm-18/bin/../include/c++/v1/__memory/unique_ptr.h:300:7
    #6 0x55cdeadc5e16 in std::__1::unique_ptr<zpp::exception_object, zpp::exception_object_delete<void>>::~unique_ptr[abi:v180000]() /usr/lib/llvm-18/bin/../include/c++/v1/__memory/unique_ptr.h:266:75
    #7 0x55cdeadc5e16 in void zpp::throwing<void, void>::catch_exception_object<destruction_with_exception_Test::TestBody()::$_0, void, false>(zpp::dynamic_object const&, destruction_with_exception_Test::TestBody()::$_0&&) /home/prak/tinker/zpp_throwing-upstream/test/./include/../../zpp_throwing.h:1469:17
    #8 0x55cdeadc5e16 in void zpp::throwing<void, void>::catches<destruction_with_exception_Test::TestBody()::$_0>(destruction_with_exception_Test::TestBody()::$_0&&) /home/prak/tinker/zpp_throwing-upstream/test/./include/../../zpp_throwing.h:1594:20
    #9 0x55cdeadc5e16 in decltype(auto) zpp::try_catch<destruction_with_exception_Test::TestBody()::$_1, destruction_with_exception_Test::TestBody()::$_0>(destruction_with_exception_Test::TestBody()::$_1&&, destruction_with_exception_Test::TestBody()::$_0&&) /home/prak/tinker/zpp_throwing-upstream/test/./include/../../zpp_throwing.h:1642:54
    #10 0x55cdeadc5e16 in destruction_with_exception_Test::TestBody() /home/prak/tinker/zpp_throwing-upstream/test/src/destruction.cpp:72:12
    #11 0x55cdeae2ecfd in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc
    #12 0x55cdeae2ecfd in testing::Test::Run() /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc:2706:5
    #13 0x55cdeae315ad in testing::TestInfo::Run() /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc:2885:11
    #14 0x55cdeae330a4 in testing::TestSuite::Run() /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc:3044:30
    #15 0x55cdeae680f8 in testing::internal::UnitTestImpl::RunAllTests() /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc:5903:44
    #16 0x55cdeae672fd in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc
    #17 0x55cdeae672fd in testing::UnitTest::Run() /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc:5470:10
    #18 0x55cdeae097e7 in RUN_ALL_TESTS() /home/prak/tinker/zpp_throwing-upstream/test/./include/gtest/gtest.h:2492:46
    #19 0x55cdeae097e7 in main /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest_main.cc:52:10
    #20 0x7f1f24a29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #21 0x7f1f24a29e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #22 0x55cdeaceb474 in _start (/home/prak/tinker/zpp_throwing-upstream/test/out/debug/default/output+0x4d474) (BuildId: 17a2985e6b792e85800559727365fceef932d013)

0x504000002490 is located 0 bytes inside of 42-byte region [0x504000002490,0x5040000024ba)
allocated by thread T0 here:
    #0 0x55cdeadc397d in operator new(unsigned long) (/home/prak/tinker/zpp_throwing-upstream/test/out/debug/default/output+0x12597d) (BuildId: 17a2985e6b792e85800559727365fceef932d013)
    #1 0x7f1f24e1820f in std::runtime_error::runtime_error(char const*) (/lib/x86_64-linux-gnu/libc++.so.1+0x5420f) (BuildId: 05f9ca9f6c44d20c9226bd7c33d1945445670c76)
    #2 0x55cdeae2ecfd in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc
    #3 0x55cdeae2ecfd in testing::Test::Run() /home/prak/tinker/zpp_throwing-upstream/test/src/gtest/src/gtest.cc:2706:5

SUMMARY: AddressSanitizer: alloc-dealloc-mismatch (/home/prak/tinker/zpp_throwing-upstream/test/out/debug/default/output+0xe8ba6) (BuildId: 17a2985e6b792e85800559727365fceef932d013) in free
==7196==HINT: if you don't care about these errors you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0
==7196==ABORTING
eyalz800 commented 1 year ago

I think this might be a libc++ bug look at the stack it’s from range_error that calls free directly, where runtime_error called operator new.

The call stack suggests it’s not the allocator but the destruction of the memory allocated by the std::runtime_error (probably for storing the error string)

eyalz800 commented 1 year ago

Closing due to being libc++ issue