llvm-project/lldb/unittests/Core/CMakeLists.txt

17 lines
267 B
CMake
Raw Normal View History

add_lldb_unittest(LLDBCoreTests
Fix a race in Broadcaster/Listener interaction Summary: The following problem was occuring: - broadcaster B had two listeners: L1 and L2 (thread T1) - (T1) B has started to broadcast an event, it has locked a shared_ptr to L1 (in ListenerIterator()) - on another thread T2 the penultimate reference to L1 was destroyed (the transient object in B is now the last reference) - (T2) the last reference to L2 was destroyed as well - (T1) B has finished broadcasting the event to L1 and destroyed the last shared_ptr - (T1) this triggered the destructor, which called into B->RemoveListener() - (T1) all pointers in the m_listeners list were now stale, so RemoveListener emptied the list - (T1) Eventually control returned to the ListenerIterator() for doing broadcasting, which was still in the middle of iterating through the list - (T1) Only now, it was holding onto a dangling iterator. BOOM. I fix this issue by making sure nothing can interfere with the iterate-and-remove-expired-pointers loop, by moving this logic into a single function, which first locks (or clears) the whole list and then returns the list of valid and locked Listeners for further processing. Instead of std::list I use an llvm::SmallVector which should hopefully offset the fact that we create a copy of the list for the common case where we have only a few listeners (no heap allocations). A slight difference in behaviour is that now RemoveListener does not remove an element from the list -- it only sets it's mask to 0, which means it will be removed during the next iteration of GetListeners(). This is purely an implementation detail and it should not be externally noticable. I was not able to reproduce this bug reliably without inserting sleep statements into the code, so I do not add a test for it. Instead, I add some unit tests for the functions that I do modify. Reviewers: clayborg, jingham Subscribers: tberghammer, lldb-commits Differential Revision: https://reviews.llvm.org/D23406 llvm-svn: 278664
2016-08-15 17:53:08 +08:00
BroadcasterTest.cpp
Handle bit fields on big-endian systems correctly Currently, the DataExtractor::GetMaxU64Bitfield and GetMaxS64Bitfield routines assume the incoming "bitfield_bit_offset" parameter uses little-endian bit numbering, i.e. a bitfield_bit_offset 0 refers to a bitfield whose least-significant bit coincides with the least- significant bit of the surrounding integer. On many big-endian systems, however, the big-endian bit numbering is used for bit fields. Here, a bitfield_bit_offset 0 refers to a bitfield whose most-significant bit conincides with the most- significant bit of the surrounding integer. Now, in principle LLDB could arbitrarily choose which semantics of bitfield_bit_offset to use. However, there are two problems with the current approach: - When parsing DWARF, LLDB decodes bit offsets in little-endian bit numbering on LE systems, but in big-endian bit numbering on BE systems. Passing those offsets later on into the DataExtractor routines gives incorrect results on BE. - In the interim, LLDB's type layer combines byte and bit offsets into a single number. I.e. instead of recording bitfields by specifying the byte offset and byte size of the surrounding integer *plus* the bit offset of the bit field within that field, it simply records a single bit offset number. Now, note that converting from byte offset + bit offset to a single offset value and back is well-defined if we either use little-endian byte order *and* little-endian bit numbering, or use big-endian byte order *and* big-endian bit numbering. Any other combination will yield incorrect results. Therefore, the simplest approach would seem to be to always use the bit numbering that matches the system byte order. This makes storing a single bit offset valid, and makes the existing DWARF code correct. The only place to fix is to teach DataExtractor to use big-endian bit numbering on big endian systems. However, there is only additional caveat: we also get bit offsets from LLDB synthetic bitfields. While the exact semantics of those doesn't seem to be well-defined, from test cases it appears that the intent was for the user-provided synthetic bitfield offset to always use little-endian bit numbering. Therefore, on a big-endian system we now have to convert those to big-endian bit numbering to remain consistent. Differential Revision: http://reviews.llvm.org/D18982 llvm-svn: 266312
2016-04-14 22:32:57 +08:00
DataExtractorTest.cpp
EventTest.cpp
ListenerTest.cpp
ScalarTest.cpp
StateTest.cpp
StreamCallbackTest.cpp
LINK_LIBS
lldbCore
lldbHost
LLVMTestingSupport
LINK_COMPONENTS
Support
)