mirror of
https://github.com/Zygo/bees.git
synced 2025-06-17 01:56:16 +02:00
types: member m_fd in BeesFileRange must be protected against data races
We had an unfortunate pattern of: const BeesFileRange bfr; shared_ptr<BeesContext> ctx; // ... BEESNOTE("foo " << bfr); bfr.fd(ctx); BEESNOTE("foo after opening: " << bfr); If dump_status started running after the first BEESNOTE, but before the second, then bfr.fd() might expose a single Fd object's shared_ptr member to two threads at the same time (the thread running dump_status and the thread running BEESNOTE) without protection by a lock. One of the threads would see a partially-initialized Fd object, and the other thread would crash on an assertion failure, e.g. #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 #1 0x00007f4c4fde5537 in __GI_abort () at abort.c:79 #2 0x00007f4c4fde540f in __assert_fail_base (fmt=0x7f4c4ff4e128 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x5557605629dd "!m_destroyed", file=0x5557605627c0 "../include/crucible/namedptr.h", line=77, function=<optimized out>) at assert.c:92 #3 0x00007f4c4fdf4662 in __GI___assert_fail (assertion=assertion@entry=0x5557605629dd "!m_destroyed", file=file@entry=0x5557605627c0 "../include/crucible/namedptr.h", line=line@entry=77, function=function@entry=0x555760562970 "crucible::NamedPtr<Return, Arguments>::Value::~Value() [with Return = crucible::IOHandle; Arguments = {int}]") at assert.c:101 #4 0x00005557605306f6 in crucible::NamedPtr<crucible::IOHandle, int>::Value::~Value (this=0x7f4a3c2ff0d0, __in_chrg=<optimized out>) at ../include/crucible/namedptr.h:77 #5 0x00005557605137da in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7f4a3c2ff0c0) at /usr/include/c++/10/bits/shared_ptr_base.h:151 #6 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7f4a3c2ff0c0) at /usr/include/c++/10/bits/shared_ptr_base.h:151 #7 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7f4c4c5b5f28, __in_chrg=<optimized out>) at /usr/include/c++/10/bits/shared_ptr_base.h:733 #8 std::__shared_ptr<crucible::IOHandle, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x7f4c4c5b5f20, __in_chrg=<optimized out>) at /usr/include/c++/10/bits/shared_ptr_base.h:1183 #9 std::shared_ptr<crucible::IOHandle>::~shared_ptr (this=0x7f4c4c5b5f20, __in_chrg=<optimized out>) at /usr/include/c++/10/bits/shared_ptr.h:121 #10 crucible::Fd::~Fd (this=0x7f4c4c5b5f20, __in_chrg=<optimized out>) at ../include/crucible/fd.h:46 #11 BeesFileRange::file_size (this=0x7f4c4e5ba4a0) at bees-types.cc:156 #12 0x0000555760513950 in operator<< (os=..., bfr=...) at bees-types.cc:80 #13 0x000055576050d662 in std::function<void (std::ostream&)>::operator()(std::ostream&) const (__args#0=..., this=0x7f4c4e5b9f60) at /usr/include/c++/10/bits/std_function.h:622 #14 BeesNote::get_status[abi:cxx11]() () at bees-trace.cc:165 #15 0x00005557604c9676 in BeesContext::dump_status (this=0x5557611c4de0) at bees-context.cc:89 #16 0x00005557605206fb in std::function<void ()>::operator()() const (this=this@entry=0x7f4c4c5b65f0) at /usr/include/c++/10/bits/std_function.h:622 #17 crucible::catch_all(std::function<void ()> const&, std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)> const&) (f=..., explainer=...) at error.cc:55 #18 0x000055576050aaa7 in operator() (__closure=0x5557611c52c8) at bees-thread.cc:22 #19 0x00007f4c501beed0 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #20 0x00007f4c502c8ea7 in start_thread (arg=<optimized out>) at pthread_create.c:477 #21 0x00007f4c4febddef in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 Fix by making BeesFileRange::m_fd really const (not just mutable), then fix all the broken code referencing it. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
@ -260,7 +260,7 @@ ostream& operator<<(ostream &os, const BeesFileId &bfi);
|
||||
|
||||
class BeesFileRange {
|
||||
protected:
|
||||
mutable Fd m_fd;
|
||||
Fd m_fd;
|
||||
mutable BeesFileId m_fid;
|
||||
off_t m_begin = 0, m_end = 0;
|
||||
mutable off_t m_file_size = -1;
|
||||
@ -301,7 +301,7 @@ public:
|
||||
Fd fd() const;
|
||||
|
||||
// Get the fd, opening it if necessary
|
||||
Fd fd(const shared_ptr<BeesContext> &ctx) const;
|
||||
Fd fd(const shared_ptr<BeesContext> &ctx);
|
||||
|
||||
BeesFileRange copy_closed() const;
|
||||
|
||||
|
Reference in New Issue
Block a user