CCF icon indicating copy to clipboard operation
CCF copied to clipboard

Fix thread safety risk when closing uv process handles

Open eddyashton opened this issue 9 months ago • 1 comments

A confusing file-handle related issue from TSAN runs (spun out from #6616).

Full stack is below, looks like some cross-thread interaction over file handles. Always involves the ProcessWriter or ProcessReader from process_launcher.h. Investigation of that code reveals a bunch of inline calls to close(). I think those are unsafe - we shouldn't be calling close() and trying to free the underlying uv handle within a callback, we should rely on the existing close_ptr for that. That requires changing the ownership rules, so those are stashed in the ProcessEntry and persist until the process completes.

(A minor implementation detail - it took me a lot of trial-and-error to work out that the close_ptr and proxy_ptr do not support null-initialisation. They are default-constructed pointing to a valid instance, and trying to make them start out with a nullptr likely results in a downstream T() default-constructor never being called. So where we want nullable semantics, we have to wrap them again in a unique_ptr or shared_ptr. I think this is fixable, but out-of-scope here).

Error trace for the curious:

WARNING: ThreadSanitizer: data race (pid=33758)
  Write of size 8 at 0x7ba800000138 by thread T7:
    #0 closedir <null> (cchost+0x6dfd6) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #1 <null> <null> (libstdc++.so.6+0x18b4ed) (BuildId: 20422e448604b560d74d2eb3befe56d6655830db)
    #2 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/shared_ptr_base.h:705:11 (cchost+0x19755c) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #3 std::__shared_ptr<std::filesystem::__cxx11::_Dir, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/shared_ptr_base.h:1154:31 (cchost+0x1974f9) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #4 std::filesystem::__cxx11::directory_iterator::~directory_iterator() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/fs_dir.h:403:35 (cchost+0x110255) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #5 asynchost::get_file_name_with_idx(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned long, bool) /data/src/3.CCF/build.tsan/../src/host/ledger.h:107:24 (cchost+0x101221) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #6 asynchost::Ledger::get_file_from_cache(unsigned long) /data/src/3.CCF/build.tsan/../src/host/ledger.h:783:20 (cchost+0x2e04d3) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #7 asynchost::Ledger::get_file_from_idx(unsigned long, bool) /data/src/3.CCF/build.tsan/../src/host/ledger.h:862:14 (cchost+0x2df28a) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #8 asynchost::Ledger::read_entries_range(unsigned long, unsigned long, bool, std::optional<unsigned long>) /data/src/3.CCF/build.tsan/../src/host/ledger.h:909:23 (cchost+0x2dea11) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #9 asynchost::Ledger::on_ledger_get_async(uv_work_s*) /data/src/3.CCF/build.tsan/../src/host/ledger.h:1510:41 (cchost+0x2dc0f5) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #10 <null> <null> (libuv.so.1+0xc51d) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)

  Previous read of size 8 at 0x7ba800000138 by main thread:
    #0 epoll_ctl <null> (cchost+0x6e306) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #1 uv__platform_invalidate_fd <null> (libuv.so.1+0x20641) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)
    #2 asynchost::ProcessWriter::on_write_done(uv_write_s*, int) /data/src/3.CCF/build.tsan/../src/host/process_launcher.h:182:7 (cchost+0x2bd380) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #3 asynchost::ProcessWriter::on_write_done_cb(uv_write_s*, int) /data/src/3.CCF/build.tsan/../src/host/process_launcher.h:175:47 (cchost+0x2bd0f5) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #4 <null> <null> (libuv.so.1+0x1b3bf) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)

  Location is file descriptor 13 created by main thread at:
    #0 socketpair <null> (cchost+0x6cee6) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #1 uv__make_socketpair <null> (libuv.so.1+0x18584) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)
    #2 asynchost::ProcessLauncher::maybe_process_next_entry() /data/src/3.CCF/build.tsan/../src/host/process_launcher.h:220:7 (cchost+0x2b062f) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #3 asynchost::ProcessLauncher::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda'(unsigned char const*, unsigned long)::operator()(unsigned char const*, unsigned long) const /data/src/3.CCF/build.tsan/../src/host/process_launcher.h:337:7 (cchost+0x2b01e9) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #4 void std::__invoke_impl<void, asynchost::ProcessLauncher::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda'(unsigned char const*, unsigned long)&, unsigned char const*, unsigned long>(std::__invoke_other, asynchost::ProcessLauncher::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda'(unsigned char const*, unsigned long)&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14 (cchost+0x2afea5) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #5 std::enable_if<is_invocable_r_v<void, asynchost::ProcessLauncher::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda'(unsigned char const*, unsigned long)&, unsigned char const*, unsigned long>, void>::type std::__invoke_r<void, asynchost::ProcessLauncher::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda'(unsigned char const*, unsigned long)&, unsigned char const*, unsigned long>(asynchost::ProcessLauncher::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda'(unsigned char const*, unsigned long)&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:111:2 (cchost+0x2afdb5) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #6 std::_Function_handler<void (unsigned char const*, unsigned long), asynchost::ProcessLauncher::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda'(unsigned char const*, unsigned long)>::_M_invoke(std::_Any_data const&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:290:9 (cchost+0x2afbf7) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #7 std::function<void (unsigned char const*, unsigned long)>::operator()(unsigned char const*, unsigned long) const /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:590:9 (cchost+0x2ab5a9) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #8 messaging::Dispatcher<unsigned int>::dispatch(unsigned int, unsigned char const*, unsigned long) /data/src/3.CCF/build.tsan/../src/ds/messaging.h:166:9 (cchost+0x2a853f) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #9 messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)::operator()(unsigned int, unsigned char const*, unsigned long) const /data/src/3.CCF/build.tsan/../src/ds/messaging.h:252:15 (cchost+0x3878c1) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #10 void std::__invoke_impl<void, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int, unsigned char const*, unsigned long>(std::__invoke_other, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int&&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14 (cchost+0x38782d) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #11 std::enable_if<is_invocable_r_v<void, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int, unsigned char const*, unsigned long>, void>::type std::__invoke_r<void, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int, unsigned char const*, unsigned long>(messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int&&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:111:2 (cchost+0x387715) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #12 std::_Function_handler<void (unsigned int, unsigned char const*, unsigned long), messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)>::_M_invoke(std::_Any_data const&, unsigned int&&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:290:9 (cchost+0x387547) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #13 std::function<void (unsigned int, unsigned char const*, unsigned long)>::operator()(unsigned int, unsigned char const*, unsigned long) const /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:590:9 (cchost+0x38743f) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #14 ringbuffer::Reader::read(unsigned long, std::function<void (unsigned int, unsigned char const*, unsigned long)>) /data/src/3.CCF/build.tsan/../src/ds/ring_buffer.h:249:9 (cchost+0x3870f9) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #15 messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&) /data/src/3.CCF/build.tsan/../src/ds/messaging.h:248:23 (cchost+0x386c10) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #16 asynchost::HandleRingbufferImpl::on_timer() /data/src/3.CCF/build.tsan/../src/host/handle_ring_buffer.h:107:10 (cchost+0x416c43) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #17 asynchost::Timer<asynchost::HandleRingbufferImpl>::on_timer() /data/src/3.CCF/build.tsan/../src/host/timer.h:48:17 (cchost+0x416bcc) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #18 asynchost::Timer<asynchost::HandleRingbufferImpl>::on_timer(uv_timer_s*) /data/src/3.CCF/build.tsan/../src/host/timer.h:43:42 (cchost+0x40e6f5) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #19 uv__run_timers <null> (libuv.so.1+0xd265) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)

  Thread T7 (tid=33833, running) created by main thread at:
    #0 pthread_create <null> (cchost+0x6864d) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #1 uv_thread_create_ex <null> (libuv.so.1+0x1d1e7) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)
    #2 uv_once <null> (libuv.so.1+0x1d57c) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)
    #3 asynchost::TCPImpl::resolve(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) /data/src/3.CCF/build.tsan/../src/host/tcp.h:570:12 (cchost+0x318dde) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #4 asynchost::TCPImpl::client_bind() /data/src/3.CCF/build.tsan/../src/host/tcp.h:202:11 (cchost+0x32c296) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #5 asynchost::TCPImpl::on_client_resolved(uv_getaddrinfo_s*, int) /data/src/3.CCF/build.tsan/../src/host/tcp.h:226:11 (cchost+0x32be81) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #6 asynchost::TCPImpl::on_client_resolved(uv_getaddrinfo_s*, int, addrinfo*) /data/src/3.CCF/build.tsan/../src/host/tcp.h:210:41 (cchost+0x32bb11) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #7 asynchost::DNS::resolve(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&, void*, void (*)(uv_getaddrinfo_s*, int, addrinfo*), bool) /data/src/3.CCF/build.tsan/../src/host/dns.h:93:9 (cchost+0x31992f) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #8 asynchost::TCPImpl::connect(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&, std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&) /data/src/3.CCF/build.tsan/../src/host/tcp.h:256:14 (cchost+0x3295a1) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #9 asynchost::NodeConnections::create_connection(ccf::EntityId<ccf::NodeIdFormatter> const&, 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&) /data/src/3.CCF/build.tsan/../src/host/node_connections.h:451:15 (cchost+0x3279fc) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #10 asynchost::NodeConnections::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda1'(unsigned char const*, unsigned long)::operator()(unsigned char const*, unsigned long) const /data/src/3.CCF/build.tsan/../src/host/node_connections.h:325:7 (cchost+0x326370) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #11 void std::__invoke_impl<void, asynchost::NodeConnections::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda1'(unsigned char const*, unsigned long)&, unsigned char const*, unsigned long>(std::__invoke_other, asynchost::NodeConnections::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda1'(unsigned char const*, unsigned long)&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14 (cchost+0x325f35) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #12 std::enable_if<is_invocable_r_v<void, asynchost::NodeConnections::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda1'(unsigned char const*, unsigned long)&, unsigned char const*, unsigned long>, void>::type std::__invoke_r<void, asynchost::NodeConnections::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda1'(unsigned char const*, unsigned long)&, unsigned char const*, unsigned long>(asynchost::NodeConnections::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda1'(unsigned char const*, unsigned long)&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:111:2 (cchost+0x325e45) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #13 std::_Function_handler<void (unsigned char const*, unsigned long), asynchost::NodeConnections::register_message_handlers(messaging::Dispatcher<unsigned int>&)::'lambda1'(unsigned char const*, unsigned long)>::_M_invoke(std::_Any_data const&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:290:9 (cchost+0x325c87) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #14 std::function<void (unsigned char const*, unsigned long)>::operator()(unsigned char const*, unsigned long) const /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:590:9 (cchost+0x2ab5a9) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #15 messaging::Dispatcher<unsigned int>::dispatch(unsigned int, unsigned char const*, unsigned long) /data/src/3.CCF/build.tsan/../src/ds/messaging.h:166:9 (cchost+0x2a853f) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #16 messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)::operator()(unsigned int, unsigned char const*, unsigned long) const /data/src/3.CCF/build.tsan/../src/ds/messaging.h:252:15 (cchost+0x3878c1) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #17 void std::__invoke_impl<void, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int, unsigned char const*, unsigned long>(std::__invoke_other, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int&&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14 (cchost+0x38782d) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #18 std::enable_if<is_invocable_r_v<void, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int, unsigned char const*, unsigned long>, void>::type std::__invoke_r<void, messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int, unsigned char const*, unsigned long>(messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)&, unsigned int&&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:111:2 (cchost+0x387715) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #19 std::_Function_handler<void (unsigned int, unsigned char const*, unsigned long), messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&)::'lambda'(unsigned int, unsigned char const*, unsigned long)>::_M_invoke(std::_Any_data const&, unsigned int&&, unsigned char const*&&, unsigned long&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:290:9 (cchost+0x387547) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #20 std::function<void (unsigned int, unsigned char const*, unsigned long)>::operator()(unsigned int, unsigned char const*, unsigned long) const /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:590:9 (cchost+0x38743f) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #21 ringbuffer::Reader::read(unsigned long, std::function<void (unsigned int, unsigned char const*, unsigned long)>) /data/src/3.CCF/build.tsan/../src/ds/ring_buffer.h:249:9 (cchost+0x3870f9) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #22 messaging::BufferProcessor::read_n(unsigned long, ringbuffer::Reader&) /data/src/3.CCF/build.tsan/../src/ds/messaging.h:248:23 (cchost+0x386c10) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #23 asynchost::HandleRingbufferImpl::on_timer() /data/src/3.CCF/build.tsan/../src/host/handle_ring_buffer.h:107:10 (cchost+0x416c43) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #24 asynchost::Timer<asynchost::HandleRingbufferImpl>::on_timer() /data/src/3.CCF/build.tsan/../src/host/timer.h:48:17 (cchost+0x416bcc) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #25 asynchost::Timer<asynchost::HandleRingbufferImpl>::on_timer(uv_timer_s*) /data/src/3.CCF/build.tsan/../src/host/timer.h:43:42 (cchost+0x40e6f5) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75)
    #26 uv__run_timers <null> (libuv.so.1+0xd265) (BuildId: 3a6ab5819a05143fa819875bbc22c7aa4effc73d)

SUMMARY: ThreadSanitizer: data race (/data/src/3.CCF/build.tsan/cchost+0x6dfd6) (BuildId: 686f8f5f02789eb4bb69c43e14a72d01b6866f75) in __interceptor_closedir
==================

eddyashton avatar Mar 04 '25 12:03 eddyashton

This doesn't work like I thought it did. Inline close() should be ok, and we need to uv_close() at least the stdin pipe once we're done writing to it.

And then when I tried a second look, the (previously 100%) repro suddenly disappeared. So this is on hold.

eddyashton avatar Mar 04 '25 16:03 eddyashton