Description
EventLoop::loop() executes posted functions inside a for(;;) loop without exception safety on the cleanup path. If the posted function throws, m_post_fn is never reset to nullptr and m_cv.notify_all() is never called. The calling thread, blocked in post() waiting for m_post_fn != &fn, hangs forever.
The cleanup code after the loop (closing file descriptors, resetting m_async_fns, notifying waiters) also runs outside any RAII guard, so all of it is skipped during stack unwinding.
In loop():
0if (m_post_fn) {
1 Unlock(lock, *m_post_fn); // exception propagates from here
2 m_post_fn = nullptr; // skipped
3 m_cv.notify_all(); // skipped
4}
In post():
0// waits forever: m_post_fn still == &fn, nobody notifies
1m_cv.wait(lock.m_lock, [this, &fn]() { return m_post_fn != &fn; });
After the loop exits via exception, ~EventLoop() hits KJ_ASSERT(m_post_fn == nullptr) and aborts. If assertions are disabled, the condition variable is destroyed while the posting thread still waits on it (undefined behavior).
Current callers avoid this because clientInvoke captures exceptions in std::exception_ptr rather than letting them propagate. The bug is latent but violates exception safety guarantees and will break any future caller that throws from a posted function.
Reproducer
0#include <mp/proxy-io.h>
1#include <mp/util.h>
2
3#include <cstdio>
4#include <future>
5#include <stdexcept>
6#include <thread>
7
8int main()
9{
10 std::promise<mp::EventLoop*> loop_ready;
11
12 std::thread loop_thread([&] {
13 mp::EventLoop loop("bugtest", [](mp::LogMessage log) {
14 if (log.level == mp::Log::Raise)
15 throw std::runtime_error(log.message);
16 });
17
18 loop_ready.set_value(&loop);
19
20 try {
21 loop.loop();
22 } catch (const std::exception& e) {
23 fprintf(stderr, "loop() threw: %s\n", e.what());
24 }
25 // ~EventLoop fires KJ_ASSERT(m_post_fn == nullptr) here
26 });
27
28 mp::EventLoop* loop = loop_ready.get_future().get();
29
30 std::thread post_thread([&] {
31 loop->post(kj::Function<void()>([] {
32 throw std::runtime_error("throw from posted fn");
33 }));
34 });
35
36 post_thread.detach();
37 loop_thread.join();
38 return 0;
39}
Run under Helgrind:
0$ valgrind --tool=helgrind ./post_race_test
1
2==276139== Helgrind, a thread error detector
3==276139== Copyright (C) 2007-2024, and GNU GPL'd, by OpenWorks LLP et al.
4==276139== Using Valgrind-3.25.1 and LibVEX; rerun with -h for copyright info
5==276139== Command: ./test/post_race_test
6==276139==
7==276139== ---Thread-Announcement------------------------------------------
8==276139==
9==276139== Thread [#1](/bitcoin-core-multiprocess/1/) is the program's root thread
10==276139==
11==276139== ---Thread-Announcement------------------------------------------
12==276139==
13==276139== Thread [#2](/bitcoin-core-multiprocess/2/) was created
14==276139== at 0x50BF823: clone (in /usr/lib/libc.so.6)
15==276139== by 0x50BF980: ??? (in /usr/lib/libc.so.6)
16==276139== by 0x503B4ED: ??? (in /usr/lib/libc.so.6)
17==276139== by 0x503C16B: pthread_create (in /usr/lib/libc.so.6)
18==276139== by 0x4CB96A1: std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (in /usr/lib/libstdc++.so.6.0.34)
19==276139== by 0x4008F22: std::thread::thread<main::{lambda()#1}, , void>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
20==276139== by 0x4008D0B: main (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
21==276139==
22==276139== ----------------------------------------------------------------
23==276139==
24==276139== Possible data race during read of size 8 at 0x51CE098 by thread [#1](/bitcoin-core-multiprocess/1/)
25==276139== Locks held: none
26==276139== at 0x400CE00: std::__uniq_ptr_impl<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::_M_ptr() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
27==276139== by 0x400C1C1: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::get() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
28==276139== by 0x400B4DD: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::operator*() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
29==276139== by 0x400A9BC: std::__future_base::_State_baseV2::wait() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
30==276139== by 0x400C861: std::__basic_future<mp::EventLoop*>::_M_get_result() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
31==276139== by 0x400BD32: std::future<mp::EventLoop*>::get() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
32==276139== by 0x4008D2A: main (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
33==276139==
34==276139== This conflicts with a previous write of size 8 by thread [#2](/bitcoin-core-multiprocess/2/)
35==276139== Locks held: none
36==276139== at 0x400CED2: std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<std::__future_base::_Result_base*> >, std::is_move_constructible<std::__future_base::_Result_base*>, std::is_move_assignable<std::__future_base::_Result_base*> >::value, void>::type std::swap<std::__future_base::_Result_base*>(std::__future_base::_Result_base*&, std::__future_base::_Result_base*&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
37==276139== by 0x400C318: std::__uniq_ptr_impl<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::swap(std::__uniq_ptr_impl<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
38==276139== by 0x400B7D6: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::swap(std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
39==276139== by 0x400ACCF: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
40==276139== by 0x400CE89: void std::__invoke_impl<void, void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::__invoke_memfun_deref, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
41==276139== by 0x400C213: std::__invoke_result<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>::type std::__invoke<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
42==276139== by 0x400B574: std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
43==276139== by 0x400C236: std::once_flag::_Prepare_execution::_Prepare_execution<std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::{lambda()#1}>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
44==276139== Address 0x51ce098 is 24 bytes inside a block of size 48 alloc'd
45==276139== at 0x488C093: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
46==276139== by 0x400ECB8: std::__new_allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
47==276139== by 0x400E3A6: std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> >&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
48==276139== by 0x400D98C: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<std::__future_base::_State_baseV2, std::allocator<void>>(std::__future_base::_State_baseV2*&, std::_Sp_alloc_shared_tag<std::allocator<void> >) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
49==276139== by 0x400D009: std::__shared_ptr<std::__future_base::_State_baseV2, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<void>>(std::_Sp_alloc_shared_tag<std::allocator<void> >) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
50==276139== by 0x400C402: std::shared_ptr<std::__future_base::_State_baseV2>::shared_ptr<std::allocator<void>>(std::_Sp_alloc_shared_tag<std::allocator<void> >) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
51==276139== by 0x400B8E6: std::shared_ptr<std::__future_base::_State_baseV2> std::make_shared<std::__future_base::_State_baseV2>() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
52==276139== by 0x400BA6D: std::promise<mp::EventLoop*>::promise() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
53==276139== by 0x4008CF0: main (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
54==276139== Block was alloc'd by thread [#1](/bitcoin-core-multiprocess/1/)
55==276139==
56==276139== ----------------------------------------------------------------
57==276139==
58==276139== Possible data race during read of size 8 at 0x51CE100 by thread [#1](/bitcoin-core-multiprocess/1/)
59==276139== Locks held: none
60==276139== at 0x400BD43: std::future<mp::EventLoop*>::get() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
61==276139== by 0x4008D2A: main (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
62==276139==
63==276139== This conflicts with a previous write of size 8 by thread [#2](/bitcoin-core-multiprocess/2/)
64==276139== Locks held: none
65==276139== at 0x400EB56: std::__future_base::_Result<mp::EventLoop*>::_M_set(mp::EventLoop*&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
66==276139== by 0x400E8FA: std::__future_base::_State_baseV2::_Setter<mp::EventLoop*, mp::EventLoop*&&>::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
67==276139== by 0x400E617: std::unique_ptr<std::__future_base::_Result<mp::EventLoop*>, std::__future_base::_Result_base::_Deleter> std::__invoke_impl<std::unique_ptr<std::__future_base::_Result<mp::EventLoop*>, std::__future_base::_Result_base::_Deleter>, std::__future_base::_State_baseV2::_Setter<mp::EventLoop*, mp::EventLoop*&&>&>(std::__invoke_other, std::__future_base::_State_baseV2::_Setter<mp::EventLoop*, mp::EventLoop*&&>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
68==276139== by 0x400DBDA: std::enable_if<is_invocable_r_v<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>, std::__future_base::_State_baseV2::_Setter<mp::EventLoop*, mp::EventLoop*&&>&>, std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> >::type std::__invoke_r<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>, std::__future_base::_State_baseV2::_Setter<mp::EventLoop*, mp::EventLoop*&&>&>(std::__future_base::_State_baseV2::_Setter<mp::EventLoop*, mp::EventLoop*&&>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
69==276139== by 0x400D1B9: std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_State_baseV2::_Setter<mp::EventLoop*, mp::EventLoop*&&> >::_M_invoke(std::_Any_data const&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
70==276139== by 0x400B839: std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
71==276139== by 0x400ACB1: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
72==276139== by 0x400CE89: void std::__invoke_impl<void, void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::__invoke_memfun_deref, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
73==276139== Address 0x51ce100 is 16 bytes inside a block of size 32 alloc'd
74==276139== at 0x488C093: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
75==276139== by 0x400BA7F: std::promise<mp::EventLoop*>::promise() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
76==276139== by 0x4008CF0: main (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
77==276139== Block was alloc'd by thread [#1](/bitcoin-core-multiprocess/1/)
78==276139==
79==276139== ---Thread-Announcement------------------------------------------
80==276139==
81==276139== Thread [#3](/bitcoin-core-multiprocess/3/) was created
82==276139== at 0x50BF823: clone (in /usr/lib/libc.so.6)
83==276139== by 0x50BF980: ??? (in /usr/lib/libc.so.6)
84==276139== by 0x503B4ED: ??? (in /usr/lib/libc.so.6)
85==276139== by 0x503C16B: pthread_create (in /usr/lib/libc.so.6)
86==276139== by 0x4CB96A1: std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (in /usr/lib/libstdc++.so.6.0.34)
87==276139== by 0x40090A8: std::thread::thread<main::{lambda()#2}, , void>(main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
88==276139== by 0x4008D55: main (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
89==276139==
90==276139== ----------------------------------------------------------------
91==276139==
92==276139== Possible data race during read of size 8 at 0x5DBBB58 by thread [#3](/bitcoin-core-multiprocess/3/)
93==276139== Locks held: none
94==276139== at 0x4011264: mp::EventLoop::post(kj::Function<void ()>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
95==276139== by 0x4008C75: main::{lambda()#2}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
96==276139== by 0x4009C30: void std::__invoke_impl<void, main::{lambda()#2}>(std::__invoke_other, main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
97==276139== by 0x4009BAE: std::__invoke_result<main::{lambda()#2}>::type std::__invoke<main::{lambda()#2}>(main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
98==276139== by 0x4009B3D: void std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
99==276139== by 0x4009AF5: std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
100==276139== by 0x4009A7F: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#2}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
101==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
102==276139== by 0x503B98A: ??? (in /usr/lib/libc.so.6)
103==276139== by 0x50BF833: clone (in /usr/lib/libc.so.6)
104==276139== Address 0x5dbbb58 is on thread [#2](/bitcoin-core-multiprocess/2/)'s stack
105==276139== in frame [#9](/bitcoin-core-multiprocess/9/), created by main::{lambda()#1}::operator()() const (???:)
106==276139==
107==276139== ----------------------------------------------------------------
108==276139==
109==276139== Thread [#2](/bitcoin-core-multiprocess/2/): Bug in libpthread: write lock granted on mutex/rwlock which is currently wr-held by a different thread
110==276139== at 0x4894C2A: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
111==276139== by 0x4014C11: std::mutex::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
112==276139== by 0x4016614: std::unique_lock<std::mutex>::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
113==276139== by 0x401654E: std::unique_lock<std::mutex>::unique_lock(std::mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
114==276139== by 0x4014E32: mp::Lock::Lock(mp::Mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
115==276139== by 0x4010C2F: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
116==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
117==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
118==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
119==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
120==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
121==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
122==276139==
123==276139== ----------------------------------------------------------------
124==276139==
125==276139== Lock at 0x5DBBBA0 was first observed
126==276139== at 0x4894C2A: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
127==276139== by 0x4014C11: std::mutex::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
128==276139== by 0x4016614: std::unique_lock<std::mutex>::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
129==276139== by 0x401654E: std::unique_lock<std::mutex>::unique_lock(std::mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
130==276139== by 0x4014E32: mp::Lock::Lock(mp::Mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
131==276139== by 0x4010A4B: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
132==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
133==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
134==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
135==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
136==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
137==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
138==276139== Address 0x5dbbba0 is on thread [#2](/bitcoin-core-multiprocess/2/)'s stack
139==276139== in frame [#1](/bitcoin-core-multiprocess/1/), created by main::{lambda()#1}::operator()() const (???:)
140==276139==
141==276139== Possible data race during read of size 8 at 0x5DBBB68 by thread [#2](/bitcoin-core-multiprocess/2/)
142==276139== Locks held: none
143==276139== at 0x4010C37: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
144==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
145==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
146==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
147==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
148==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
149==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
150==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
151==276139== by 0x503B98A: ??? (in /usr/lib/libc.so.6)
152==276139== by 0x50BF833: clone (in /usr/lib/libc.so.6)
153==276139==
154==276139== This conflicts with a previous write of size 8 by thread [#3](/bitcoin-core-multiprocess/3/)
155==276139== Locks held: 1, at address 0x5DBBBA0
156==276139== at 0x40112D9: mp::EventLoop::post(kj::Function<void ()>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
157==276139== by 0x4008C75: main::{lambda()#2}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
158==276139== by 0x4009C30: void std::__invoke_impl<void, main::{lambda()#2}>(std::__invoke_other, main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
159==276139== by 0x4009BAE: std::__invoke_result<main::{lambda()#2}>::type std::__invoke<main::{lambda()#2}>(main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
160==276139== by 0x4009B3D: void std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
161==276139== by 0x4009AF5: std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
162==276139== by 0x4009A7F: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#2}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
163==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
164==276139== Address 0x5dbbb68 is on thread [#2](/bitcoin-core-multiprocess/2/)'s stack
165==276139== in frame [#1](/bitcoin-core-multiprocess/1/), created by main::{lambda()#1}::operator()() const (???:)
166==276139==
167==276139== ----------------------------------------------------------------
168==276139==
169==276139== Thread [#2](/bitcoin-core-multiprocess/2/) unlocked lock at 0x5DBBBA0 currently held by thread [#3](/bitcoin-core-multiprocess/3/)
170==276139== at 0x4895369: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
171==276139== by 0x4014C5D: std::mutex::unlock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
172==276139== by 0x40165C1: std::unique_lock<std::mutex>::unlock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
173==276139== by 0x4014E4D: mp::Lock::unlock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
174==276139== by 0x401A437: mp::UnlockGuard<mp::Lock>::UnlockGuard(mp::Lock&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
175==276139== by 0x401803D: void mp::Unlock<mp::Lock, kj::Function<void ()>&>(mp::Lock&, kj::Function<void ()>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
176==276139== by 0x4010C5C: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
177==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
178==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
179==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
180==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
181==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
182==276139== Lock at 0x5DBBBA0 was first observed
183==276139== at 0x4894C2A: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
184==276139== by 0x4014C11: std::mutex::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
185==276139== by 0x4016614: std::unique_lock<std::mutex>::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
186==276139== by 0x401654E: std::unique_lock<std::mutex>::unique_lock(std::mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
187==276139== by 0x4014E32: mp::Lock::Lock(mp::Mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
188==276139== by 0x4010A4B: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
189==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
190==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
191==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
192==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
193==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
194==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
195==276139== Address 0x5dbbba0 is on thread [#2](/bitcoin-core-multiprocess/2/)'s stack
196==276139== in frame [#7](/bitcoin-core-multiprocess/7/), created by main::{lambda()#1}::operator()() const (???:)
197==276139==
198==276139==
199==276139== ----------------------------------------------------------------
200==276139==
201==276139== Possible data race during read of size 8 at 0x65BCC88 by thread [#2](/bitcoin-core-multiprocess/2/)
202==276139== Locks held: none
203==276139== at 0x401ACD6: kj::Own<kj::Function<void ()>::Iface, decltype(nullptr)>::operator*() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
204==276139== by 0x40181A9: kj::Function<void ()>::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
205==276139== by 0x4018049: void mp::Unlock<mp::Lock, kj::Function<void ()>&>(mp::Lock&, kj::Function<void ()>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
206==276139== by 0x4010C5C: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
207==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
208==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
209==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
210==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
211==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
212==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
213==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
214==276139== by 0x503B98A: ??? (in /usr/lib/libc.so.6)
215==276139== Address 0x65bcc88 is on thread [#3](/bitcoin-core-multiprocess/3/)'s stack
216==276139== in frame [#7](/bitcoin-core-multiprocess/7/), created by main::{lambda()#2}::operator()() const (???:)
217==276139==
218==276139== ----------------------------------------------------------------
219==276139==
220==276139== Possible data race during read of size 8 at 0x51CF080 by thread [#2](/bitcoin-core-multiprocess/2/)
221==276139== Locks held: none
222==276139== at 0x40181AA: kj::Function<void ()>::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
223==276139== by 0x4018049: void mp::Unlock<mp::Lock, kj::Function<void ()>&>(mp::Lock&, kj::Function<void ()>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
224==276139== by 0x4010C5C: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
225==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
226==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
227==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
228==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
229==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
230==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
231==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
232==276139== by 0x503B98A: ??? (in /usr/lib/libc.so.6)
233==276139== by 0x50BF833: clone (in /usr/lib/libc.so.6)
234==276139== Address 0x51cf080 is 0 bytes inside a block of size 16 alloc'd
235==276139== at 0x488C093: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
236==276139== by 0x400929E: kj::Own<kj::Function<void ()>::Impl<main::{lambda()#2}::operator()() const::{lambda()#1}>, decltype(nullptr)> kj::heap<kj::Function<void ()>::Impl<main::{lambda()#2}::operator()() const::{lambda()#1}>, main::{lambda()#2}::operator()() const::{lambda()#1}>(main::{lambda()#2}::operator()() const::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
237==276139== by 0x4008FE9: kj::Function<void ()>::Function<main::{lambda()#2}::operator()() const::{lambda()#1}>(main::{lambda()#2}::operator()() const::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
238==276139== by 0x4008C66: main::{lambda()#2}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
239==276139== by 0x4009C30: void std::__invoke_impl<void, main::{lambda()#2}>(std::__invoke_other, main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
240==276139== by 0x4009BAE: std::__invoke_result<main::{lambda()#2}>::type std::__invoke<main::{lambda()#2}>(main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
241==276139== by 0x4009B3D: void std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
242==276139== by 0x4009AF5: std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
243==276139== by 0x4009A7F: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#2}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
244==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
245==276139== by 0x503B98A: ??? (in /usr/lib/libc.so.6)
246==276139== by 0x50BF833: clone (in /usr/lib/libc.so.6)
247==276139== Block was alloc'd by thread [#3](/bitcoin-core-multiprocess/3/)
248==276139==
249==276139== ----------------------------------------------------------------
250==276139==
251==276139== Thread [#2](/bitcoin-core-multiprocess/2/): Bug in libpthread: write lock granted on mutex/rwlock which is currently wr-held by a different thread
252==276139== at 0x4894C2A: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
253==276139== by 0x4014C11: std::mutex::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
254==276139== by 0x4016614: std::unique_lock<std::mutex>::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
255==276139== by 0x4014E69: mp::Lock::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
256==276139== by 0x401A456: mp::UnlockGuard<mp::Lock>::~UnlockGuard() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
257==276139== by 0x4018075: void mp::Unlock<mp::Lock, kj::Function<void ()>&>(mp::Lock&, kj::Function<void ()>&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
258==276139== by 0x4010C5C: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
259==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
260==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
261==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
262==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
263==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
264==276139==
265==276139== ----------------------------------------------------------------
266==276139==
267==276139== Thread [#2](/bitcoin-core-multiprocess/2/) unlocked lock at 0x5DBBBA0 currently held by thread [#3](/bitcoin-core-multiprocess/3/)
268==276139== at 0x4895369: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
269==276139== by 0x4014C5D: std::mutex::unlock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
270==276139== by 0x40165C1: std::unique_lock<std::mutex>::unlock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
271==276139== by 0x401657D: std::unique_lock<std::mutex>::~unique_lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
272==276139== by 0x4015D49: mp::Lock::~Lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
273==276139== by 0x4011005: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
274==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
275==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
276==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
277==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
278==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
279==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
280==276139== Lock at 0x5DBBBA0 was first observed
281==276139== at 0x4894C2A: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
282==276139== by 0x4014C11: std::mutex::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
283==276139== by 0x4016614: std::unique_lock<std::mutex>::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
284==276139== by 0x401654E: std::unique_lock<std::mutex>::unique_lock(std::mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
285==276139== by 0x4014E32: mp::Lock::Lock(mp::Mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
286==276139== by 0x4010A4B: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
287==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
288==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
289==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
290==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
291==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
292==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
293==276139== Address 0x5dbbba0 is on thread [#2](/bitcoin-core-multiprocess/2/)'s stack
294==276139== in frame [#6](/bitcoin-core-multiprocess/6/), created by main::{lambda()#1}::operator()() const (???:)
295==276139==
296==276139==
297loop() threw: throw from posted fn
298==276139== ----------------------------------------------------------------
299==276139==
300==276139== Lock at 0x5DBBBA0 was first observed
301==276139== at 0x4894C2A: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
302==276139== by 0x4014C11: std::mutex::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
303==276139== by 0x4016614: std::unique_lock<std::mutex>::lock() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
304==276139== by 0x401654E: std::unique_lock<std::mutex>::unique_lock(std::mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
305==276139== by 0x4014E32: mp::Lock::Lock(mp::Mutex&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
306==276139== by 0x4010A4B: mp::EventLoop::loop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
307==276139== by 0x4008ACC: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
308==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
309==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
310==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
311==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
312==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
313==276139== Address 0x5dbbba0 is on thread [#2](/bitcoin-core-multiprocess/2/)'s stack
314==276139== in frame [#2](/bitcoin-core-multiprocess/2/), created by main::{lambda()#1}::operator()() const (???:)
315==276139==
316==276139== Possible data race during read of size 8 at 0x5DBBB68 by thread [#2](/bitcoin-core-multiprocess/2/)
317==276139== Locks held: none
318==276139== at 0x4017725: kj::_::DebugComparison<kj::Function<void ()>*&, decltype(nullptr)> kj::_::DebugExpression<kj::Function<void ()>*&>::operator==<decltype(nullptr)>(decltype(nullptr)&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
319==276139== by 0x40104BF: mp::EventLoop::~EventLoop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
320==276139== by 0x4008ADB: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
321==276139== by 0x4009C6D: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
322==276139== by 0x4009BF3: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(main::{lambda()#1}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
323==276139== by 0x4009B69: void std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
324==276139== by 0x4009B11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
325==276139== by 0x4009ABF: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#1}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
326==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
327==276139== by 0x503B98A: ??? (in /usr/lib/libc.so.6)
328==276139== by 0x50BF833: clone (in /usr/lib/libc.so.6)
329==276139==
330==276139== This conflicts with a previous write of size 8 by thread [#3](/bitcoin-core-multiprocess/3/)
331==276139== Locks held: 1, at address 0x5DBBBA0
332==276139== at 0x40112D9: mp::EventLoop::post(kj::Function<void ()>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
333==276139== by 0x4008C75: main::{lambda()#2}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
334==276139== by 0x4009C30: void std::__invoke_impl<void, main::{lambda()#2}>(std::__invoke_other, main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
335==276139== by 0x4009BAE: std::__invoke_result<main::{lambda()#2}>::type std::__invoke<main::{lambda()#2}>(main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
336==276139== by 0x4009B3D: void std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
337==276139== by 0x4009AF5: std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
338==276139== by 0x4009A7F: std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::{lambda()#2}> > >::_M_run() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
339==276139== by 0x4CB95A3: ??? (in /usr/lib/libstdc++.so.6.0.34)
340==276139== Address 0x5dbbb68 is on thread [#2](/bitcoin-core-multiprocess/2/)'s stack
341==276139== in frame [#2](/bitcoin-core-multiprocess/2/), created by main::{lambda()#1}::operator()() const (???:)
342==276139==
343terminate called after throwing an instance of 'kj::ExceptionImpl'
344 what(): mp/proxy.cpp:216: failed: expected m_post_fn == nullptr [65bcc80 == nullptr]
345stack: 401052d 4008adb 4009c6d 4009bf3 4009b69 4009b11 4009abf 4cb95a3 503b98a 50bf833
346==276139==
347==276139== Process terminating with default action of signal 6 (SIGABRT): dumping core
348==276139== at 0x503D90C: ??? (in /usr/lib/libc.so.6)
349==276139== by 0x4FE339F: raise (in /usr/lib/libc.so.6)
350==276139== by 0x4FCA579: abort (in /usr/lib/libc.so.6)
351==276139== by 0x4C6BBF5: ??? (in /usr/lib/libstdc++.so.6.0.34)
352==276139== by 0x4C85EB9: ??? (in /usr/lib/libstdc++.so.6.0.34)
353==276139== by 0x4C6B5D8: std::terminate() (in /usr/lib/libstdc++.so.6.0.34)
354==276139== by 0x4C86175: __cxa_throw (in /usr/lib/libstdc++.so.6.0.34)
355==276139== by 0x4B65249: ??? (in /usr/lib/libkj.so.1.2.0)
356==276139== by 0x4B713E2: kj::throwFatalException(kj::Exception&&, unsigned int) (in /usr/lib/libkj.so.1.2.0)
357==276139== by 0x4B7146A: kj::_::Debug::Fault::fatal() (in /usr/lib/libkj.so.1.2.0)
358==276139== by 0x401052D: mp::EventLoop::~EventLoop() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
359==276139== by 0x4008ADB: main::{lambda()#1}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
360==276139== ----------------------------------------------------------------
361==276139==
362==276139== Thread [#3](/bitcoin-core-multiprocess/3/): Exiting thread still holds 1 lock
363==276139== at 0x5043FE2: ??? (in /usr/lib/libc.so.6)
364==276139== by 0x503816B: ??? (in /usr/lib/libc.so.6)
365==276139== by 0x50387DB: ??? (in /usr/lib/libc.so.6)
366==276139== by 0x503AE9D: pthread_cond_wait (in /usr/lib/libc.so.6)
367==276139== by 0x4CAEEA0: std::condition_variable::wait(std::unique_lock<std::mutex>&) (in /usr/lib/libstdc++.so.6.0.34)
368==276139== by 0x4013150: void std::condition_variable::wait<mp::EventLoop::post(kj::Function<void ()>)::{lambda()#3}>(std::unique_lock<std::mutex>&, mp::EventLoop::post(kj::Function<void ()>)::{lambda()#3}) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
369==276139== by 0x4011323: mp::EventLoop::post(kj::Function<void ()>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
370==276139== by 0x4008C75: main::{lambda()#2}::operator()() const (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
371==276139== by 0x4009C30: void std::__invoke_impl<void, main::{lambda()#2}>(std::__invoke_other, main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
372==276139== by 0x4009BAE: std::__invoke_result<main::{lambda()#2}>::type std::__invoke<main::{lambda()#2}>(main::{lambda()#2}&&) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
373==276139== by 0x4009B3D: void std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
374==276139== by 0x4009AF5: std::thread::_Invoker<std::tuple<main::{lambda()#2}> >::operator()() (in /home/mohamed/dev/libmultiprocess/build/test/post_race_test)
375==276139==
376==276139==
377==276139== Use --history-level=approx or =none to gain increased speed, at
378==276139== the cost of reduced accuracy of conflicting-access information
379==276139== For lists of detected and suppressed errors, rerun with: -s
380==276139== ERROR SUMMARY: 13 errors from 12 contexts (suppressed: 30 from 22)
381[1] 276139 IOT instruction (core dumped) valgrind --tool=helgrind ./test/post_race_test