Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indirect memory leaks in binder #1083

Closed
acquamarin opened this issue Nov 30, 2022 · 0 comments
Closed

Indirect memory leaks in binder #1083

acquamarin opened this issue Nov 30, 2022 · 0 comments
Assignees

Comments

@acquamarin
Copy link
Collaborator

We are using shared_ptrs to wrap expressions in the binder. However, some expressions may form a circular dependency and results in indirect memory leak.
We should consider using either raw pointers in the binder, or fix the circular dependency issue.

Here is a part of the log produced by memory santizier:

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7faa5f6ec587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x55cb75bb02f8 in __gnu_cxx::new_allocator<std::shared_ptr<kuzu::binder::Expression> >::allocate(unsigned long, void const*) /usr/include/c++/9/ext/new_allocator.h:114
    #2 0x55cb75bad4ba in std::allocator_traits<std::allocator<std::shared_ptr<kuzu::binder::Expression> > >::allocate(std::allocator<std::shared_ptr<kuzu::binder::Expression> >&, unsigned long) /usr/include/c++/9/bits/alloc_traits.h:443
    #3 0x55cb75ba9c01 in std::_Vector_base<std::shared_ptr<kuzu::binder::Expression>, std::allocator<std::shared_ptr<kuzu::binder::Expression> > >::_M_allocate(unsigned long) /usr/include/c++/9/bits/stl_vector.h:343
    #4 0x55cb75ba41e0 in void std::vector<std::shared_ptr<kuzu::binder::Expression>, std::allocator<std::shared_ptr<kuzu::binder::Expression> > >::_M_range_initialize<std::shared_ptr<kuzu::binder::Expression> const*>(std::shared_ptr<kuzu::binder::Expression> const*, std::shared_ptr<kuzu::binder::Expression> const*, std::forward_iterator_tag) (/data0/kuzu/build/debug/test/runner/e2e_delete_create_transaction_test+0x8491e0)
    #5 0x55cb75b9f8f3 in std::vector<std::shared_ptr<kuzu::binder::Expression>, std::allocator<std::shared_ptr<kuzu::binder::Expression> > >::vector(std::initializer_list<std::shared_ptr<kuzu::binder::Expression> >, std::allocator<std::shared_ptr<kuzu::binder::Expression> > const&) (/data0/kuzu/build/debug/test/runner/e2e_delete_create_transaction_test+0x8448f3)
    #6 0x55cb75ea674d in kuzu::binder::Expression::Expression(kuzu::common::ExpressionType, kuzu::common::DataType, std::shared_ptr<kuzu::binder::Expression> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /data0/kuzu/src/include/binder/expression/expression.h:37
    #7 0x55cb75ea80eb in kuzu::binder::PropertyExpression::PropertyExpression(kuzu::common::DataType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<unsigned long, unsigned int, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned int> > >, std::shared_ptr<kuzu::binder::Expression> const&) /data0/kuzu/src/include/binder/expression/property_expression.h:16
    #8 0x55cb75eae1b4 in std::_MakeUniq<kuzu::binder::PropertyExpression>::__single_object std::make_unique<kuzu::binder::PropertyExpression, kuzu::common::DataType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<unsigned long, unsigned int, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned int> > >, std::shared_ptr<kuzu::binder::Expression>&>(kuzu::common::DataType&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<unsigned long, unsigned int, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned int> > >&&, std::shared_ptr<kuzu::binder::Expression>&) /usr/include/c++/9/bits/unique_ptr.h:857
    #9 0x55cb75e9cb2b in kuzu::binder::ExpressionBinder::bindInternalNodeIDExpression(std::shared_ptr<kuzu::binder::Expression>) /data0/kuzu/src/binder/expression_binder.cpp:323
    #10 0x55cb75e9c54e in kuzu::binder::ExpressionBinder::bindInternalIDExpression(std::shared_ptr<kuzu::binder::Expression>) /data0/kuzu/src/binder/expression_binder.cpp:310
    #11 0x55cb76686ca1 in kuzu::binder::Binder::createQueryNode(kuzu::parser::NodePattern const&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:147
    #12 0x55cb76685f7e in kuzu::binder::Binder::bindQueryNode(kuzu::parser::NodePattern const&, kuzu::binder::QueryGraph&, kuzu::binder::PropertyKeyValCollection&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:130
    #13 0x55cb766820b9 in kuzu::binder::Binder::bindPatternElement(kuzu::parser::PatternElement const&, kuzu::binder::PropertyKeyValCollection&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:28
    #14 0x55cb76681d3d in kuzu::binder::Binder::bindGraphPattern(std::vector<std::unique_ptr<kuzu::parser::PatternElement, std::default_delete<kuzu::parser::PatternElement> >, std::allocator<std::unique_ptr<kuzu::parser::PatternElement, std::default_delete<kuzu::parser::PatternElement> > > > const&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:19
    #15 0x55cb766a6578 in kuzu::binder::Binder::bindMatchClause(kuzu::parser::ReadingClause const&) /data0/kuzu/src/binder/bind/bind_reading_clause.cpp:25
    #16 0x55cb766a618c in kuzu::binder::Binder::bindReadingClause(kuzu::parser::ReadingClause const&) /data0/kuzu/src/binder/bind/bind_reading_clause.cpp:11
    #17 0x55cb76693984 in kuzu::binder::Binder::bindSingleQuery(kuzu::parser::SingleQuery const&) /data0/kuzu/src/binder/bind/bind_query.cpp:33
    #18 0x55cb76693214 in kuzu::binder::Binder::bindQuery(kuzu::parser::RegularQuery const&) /data0/kuzu/src/binder/bind/bind_query.cpp:13
    #19 0x55cb75e7e4e5 in kuzu::binder::Binder::bind(kuzu::parser::Statement const&) /data0/kuzu/src/binder/binder.cpp:21
    #20 0x55cb75b8affd in kuzu::main::Connection::prepareNoLock(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /data0/kuzu/src/main/connection.cpp:80
    #21 0x55cb75b8a68c in kuzu::main::Connection::query(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /data0/kuzu/src/main/connection.cpp:34
    #22 0x55cb75977e49 in CreateDeleteInt64NodeTrxTest::testMixedDeleteAndInsert(bool, kuzu::testing::TransactionTestType) (/data0/kuzu/build/debug/test/runner/e2e_delete_create_transaction_test+0x61ce49)
    #23 0x55cb759363ab in CreateDeleteInt64NodeTrxTest_MixedInsertDeleteRollbackNormalExecution_Test::TestBody() /data0/kuzu/test/runner/e2e_delete_create_transaction_test.cpp:293
    #24 0x55cb75b3e5a2 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /data0/kuzu/build/debug/_deps/googletest-src/googletest/src/gtest.cc:2607
    #25 0x55cb75b2c8d3 in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /data0/kuzu/build/debug/_deps/googletest-src/googletest/src/gtest.cc:2643
    #26 0x55cb75ac3f3f in testing::Test::Run() /data0/kuzu/build/debug/_deps/googletest-src/googletest/src/gtest.cc:2682
    #27 0x55cb75ac5514 in testing::TestInfo::Run() /data0/kuzu/build/debug/_deps/googletest-src/googletest/src/gtest.cc:2861
    #28 0x55cb75ac6714 in testing::TestSuite::Run() /data0/kuzu/build/debug/_deps/googletest-src/googletest/src/gtest.cc:3015
    #29 0x55cb75aec55d in testing::internal::UnitTestImpl::RunAllTests() /data0/kuzu/build/debug/_deps/googletest-src/googletest/src/gtest.cc:5855

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7faa5f6ec587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x55cb75b67538 in __gnu_cxx::new_allocator<std::__detail::_Hash_node<unsigned long, false> >::allocate(unsigned long, void const*) /usr/include/c++/9/ext/new_allocator.h:114
    #2 0x55cb75b670b2 in std::allocator_traits<std::allocator<std::__detail::_Hash_node<unsigned long, false> > >::allocate(std::allocator<std::__detail::_Hash_node<unsigned long, false> >&, unsigned long) /usr/include/c++/9/bits/alloc_traits.h:443
    #3 0x55cb75b66ad5 in std::__detail::_Hash_node<unsigned long, false>* std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<unsigned long, false> > >::_M_allocate_node<unsigned long const&>(unsigned long const&) /usr/include/c++/9/bits/hashtable_policy.h:2081
    #4 0x55cb75eaba11 in std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >::_Hashtable(std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> > const&)::{lambda(std::__detail::_Hash_node<unsigned long, false> const*)#1}::operator()(std::__detail::_Hash_node<unsigned long, false> const*) const /usr/include/c++/9/bits/hashtable.h:1275
    #5 0x55cb75eb06e4 in void std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >::_M_assign<std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >::_M_assign(std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> > const&)::{lambda(std::__detail::_Hash_node<unsigned long, false> const*)#1}>(std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> > const&, std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >::_M_assign(std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> > const&)::{lambda(std::__detail::_Hash_node<unsigned long, false> const*)#1} const&) /usr/include/c++/9/bits/hashtable.h:1159
    #6 0x55cb75eabd5d in std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >::_Hashtable(std::_Hashtable<unsigned long, unsigned long, std::allocator<unsigned long>, std::__detail::_Identity, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> > const&) /usr/include/c++/9/bits/hashtable.h:1273
    #7 0x55cb75ea83ac in std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >::unordered_set(std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > const&) /usr/include/c++/9/bits/unordered_set.h:175
    #8 0x55cb76692587 in void __gnu_cxx::new_allocator<kuzu::binder::NodeExpression>::construct<kuzu::binder::NodeExpression, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(kuzu::binder::NodeExpression*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/ext/new_allocator.h:146
    #9 0x55cb76691f5b in void std::allocator_traits<std::allocator<kuzu::binder::NodeExpression> >::construct<kuzu::binder::NodeExpression, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(std::allocator<kuzu::binder::NodeExpression>&, kuzu::binder::NodeExpression*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/bits/alloc_traits.h:483
    #10 0x55cb7669186b in std::_Sp_counted_ptr_inplace<kuzu::binder::NodeExpression, std::allocator<kuzu::binder::NodeExpression>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(std::allocator<kuzu::binder::NodeExpression>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/bits/shared_ptr_base.h:548
    #11 0x55cb76690bb3 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<kuzu::binder::NodeExpression, std::allocator<kuzu::binder::NodeExpression>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(kuzu::binder::NodeExpression*&, std::_Sp_alloc_shared_tag<std::allocator<kuzu::binder::NodeExpression> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/bits/shared_ptr_base.h:679
    #12 0x55cb76690240 in std::__shared_ptr<kuzu::binder::NodeExpression, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<kuzu::binder::NodeExpression>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(std::_Sp_alloc_shared_tag<std::allocator<kuzu::binder::NodeExpression> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/bits/shared_ptr_base.h:1344
    #13 0x55cb7668f8e9 in std::shared_ptr<kuzu::binder::NodeExpression>::shared_ptr<std::allocator<kuzu::binder::NodeExpression>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(std::_Sp_alloc_shared_tag<std::allocator<kuzu::binder::NodeExpression> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/bits/shared_ptr.h:359
    #14 0x55cb7668f0fa in std::shared_ptr<kuzu::binder::NodeExpression> std::allocate_shared<kuzu::binder::NodeExpression, std::allocator<kuzu::binder::NodeExpression>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(std::allocator<kuzu::binder::NodeExpression> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/bits/shared_ptr.h:702
    #15 0x55cb7668e5d3 in std::shared_ptr<kuzu::binder::NodeExpression> std::make_shared<kuzu::binder::NodeExpression, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >&) /usr/include/c++/9/bits/shared_ptr.h:718
    #16 0x55cb76686bdb in kuzu::binder::Binder::createQueryNode(kuzu::parser::NodePattern const&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:146
    #17 0x55cb76685f7e in kuzu::binder::Binder::bindQueryNode(kuzu::parser::NodePattern const&, kuzu::binder::QueryGraph&, kuzu::binder::PropertyKeyValCollection&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:130
    #18 0x55cb766820b9 in kuzu::binder::Binder::bindPatternElement(kuzu::parser::PatternElement const&, kuzu::binder::PropertyKeyValCollection&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:28
    #19 0x55cb76681d3d in kuzu::binder::Binder::bindGraphPattern(std::vector<std::unique_ptr<kuzu::parser::PatternElement, std::default_delete<kuzu::parser::PatternElement> >, std::allocator<std::unique_ptr<kuzu::parser::PatternElement, std::default_delete<kuzu::parser::PatternElement> > > > const&) /data0/kuzu/src/binder/bind/bind_graph_pattern.cpp:19
    #20 0x55cb766a6578 in kuzu::binder::Binder::bindMatchClause(kuzu::parser::ReadingClause const&) /data0/kuzu/src/binder/bind/bind_reading_clause.cpp:25
    #21 0x55cb766a618c in kuzu::binder::Binder::bindReadingClause(kuzu::parser::ReadingClause const&) /data0/kuzu/src/binder/bind/bind_reading_clause.cpp:11
    #22 0x55cb76693984 in kuzu::binder::Binder::bindSingleQuery(kuzu::parser::SingleQuery const&) /data0/kuzu/src/binder/bind/bind_query.cpp:33
    #23 0x55cb76693214 in kuzu::binder::Binder::bindQuery(kuzu::parser::RegularQuery const&) /data0/kuzu/src/binder/bind/bind_query.cpp:13
    #24 0x55cb75e7e4e5 in kuzu::binder::Binder::bind(kuzu::parser::Statement const&) /data0/kuzu/src/binder/binder.cpp:21
    #25 0x55cb75b8affd in kuzu::main::Connection::prepareNoLock(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /data0/kuzu/src/main/connection.cpp:80
    #26 0x55cb75b8a68c in kuzu::main::Connection::query(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /data0/kuzu/src/main/connection.cpp:34
    #27 0x55cb75982496 in CreateRelTrxTest::readAllKnowsProperty(kuzu::main::Connection*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (/data0/kuzu/build/debug/test/runner/e2e_delete_create_transaction_test+0x627496)
    #28 0x55cb7594251f in CreateRelTrxTest_InsertRelsToLargeListCommitRecovery_Test::TestBody() /data0/kuzu/test/runner/e2e_delete_create_transaction_test.cpp:719
    #29 0x55cb75b3e5a2 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /data0/kuzu/build/debug/_deps/googletest-src/googletest/src/gtest.cc:2607
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants