diff options
Diffstat (limited to 'lldb/source/Utility/ReproducerInstrumentation.cpp')
-rw-r--r-- | lldb/source/Utility/ReproducerInstrumentation.cpp | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/lldb/source/Utility/ReproducerInstrumentation.cpp b/lldb/source/Utility/ReproducerInstrumentation.cpp deleted file mode 100644 index b3285f4b3776..000000000000 --- a/lldb/source/Utility/ReproducerInstrumentation.cpp +++ /dev/null @@ -1,262 +0,0 @@ -//===-- ReproducerInstrumentation.cpp -------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lldb/Utility/ReproducerInstrumentation.h" -#include "lldb/Utility/Reproducer.h" -#include <cstdio> -#include <cstdlib> -#include <limits> -#include <thread> - -using namespace lldb_private; -using namespace lldb_private::repro; - -// Whether we're currently across the API boundary. -static thread_local bool g_global_boundary = false; - -void *IndexToObject::GetObjectForIndexImpl(unsigned idx) { - return m_mapping.lookup(idx); -} - -void IndexToObject::AddObjectForIndexImpl(unsigned idx, void *object) { - assert(idx != 0 && "Cannot add object for sentinel"); - m_mapping[idx] = object; -} - -std::vector<void *> IndexToObject::GetAllObjects() const { - std::vector<std::pair<unsigned, void *>> pairs; - for (auto &e : m_mapping) { - pairs.emplace_back(e.first, e.second); - } - - // Sort based on index. - std::sort(pairs.begin(), pairs.end(), - [](auto &lhs, auto &rhs) { return lhs.first < rhs.first; }); - - std::vector<void *> objects; - objects.reserve(pairs.size()); - for (auto &p : pairs) { - objects.push_back(p.second); - } - - return objects; -} - -template <> const uint8_t *Deserializer::Deserialize<const uint8_t *>() { - return Deserialize<uint8_t *>(); -} - -template <> void *Deserializer::Deserialize<void *>() { - return const_cast<void *>(Deserialize<const void *>()); -} - -template <> const void *Deserializer::Deserialize<const void *>() { - return nullptr; -} - -template <> char *Deserializer::Deserialize<char *>() { - return const_cast<char *>(Deserialize<const char *>()); -} - -template <> const char *Deserializer::Deserialize<const char *>() { - const size_t size = Deserialize<size_t>(); - if (size == std::numeric_limits<size_t>::max()) - return nullptr; - assert(HasData(size + 1)); - const char *str = m_buffer.data(); - m_buffer = m_buffer.drop_front(size + 1); -#ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> \"" - << str << "\"\n"; -#endif - return str; -} - -template <> const char **Deserializer::Deserialize<const char **>() { - const size_t size = Deserialize<size_t>(); - if (size == 0) - return nullptr; - const char **r = - reinterpret_cast<const char **>(calloc(size + 1, sizeof(char *))); - for (size_t i = 0; i < size; ++i) - r[i] = Deserialize<const char *>(); - return r; -} - -void Deserializer::CheckSequence(unsigned sequence) { - if (m_expected_sequence && *m_expected_sequence != sequence) - llvm::report_fatal_error( - "The result does not match the preceding " - "function. This is probably the result of concurrent " - "use of the SB API during capture, which is currently not " - "supported."); - m_expected_sequence.reset(); -} - -bool Registry::Replay(const FileSpec &file) { - auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); - if (auto err = error_or_file.getError()) - return false; - - return Replay((*error_or_file)->getBuffer()); -} - -bool Registry::Replay(llvm::StringRef buffer) { - Deserializer deserializer(buffer); - return Replay(deserializer); -} - -bool Registry::Replay(Deserializer &deserializer) { -#ifndef LLDB_REPRO_INSTR_TRACE - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_API); -#endif - - // Disable buffering stdout so that we approximate the way things get flushed - // during an interactive session. - setvbuf(stdout, nullptr, _IONBF, 0); - - while (deserializer.HasData(1)) { - unsigned sequence = deserializer.Deserialize<unsigned>(); - unsigned id = deserializer.Deserialize<unsigned>(); - -#ifndef LLDB_REPRO_INSTR_TRACE - LLDB_LOG(log, "Replaying {0}: {1}", id, GetSignature(id)); -#else - llvm::errs() << "Replaying " << id << ": " << GetSignature(id) << "\n"; -#endif - - deserializer.SetExpectedSequence(sequence); - GetReplayer(id)->operator()(deserializer); - } - - // Add a small artificial delay to ensure that all asynchronous events have - // completed before we exit. - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - return true; -} - -void Registry::DoRegister(uintptr_t RunID, std::unique_ptr<Replayer> replayer, - SignatureStr signature) { - const unsigned id = m_replayers.size() + 1; - assert(m_replayers.find(RunID) == m_replayers.end()); - m_replayers[RunID] = std::make_pair(std::move(replayer), id); - m_ids[id] = - std::make_pair(m_replayers[RunID].first.get(), std::move(signature)); -} - -unsigned Registry::GetID(uintptr_t addr) { - unsigned id = m_replayers[addr].second; - assert(id != 0 && "Forgot to add function to registry?"); - return id; -} - -std::string Registry::GetSignature(unsigned id) { - assert(m_ids.count(id) != 0 && "ID not in registry"); - return m_ids[id].second.ToString(); -} - -void Registry::CheckID(unsigned expected, unsigned actual) { - if (expected != actual) { - llvm::errs() << "Reproducer expected signature " << expected << ": '" - << GetSignature(expected) << "'\n"; - llvm::errs() << "Reproducer actual signature " << actual << ": '" - << GetSignature(actual) << "'\n"; - llvm::report_fatal_error( - "Detected reproducer replay divergence. Refusing to continue."); - } - -#ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Replaying " << actual << ": " << GetSignature(actual) - << "\n"; -#endif -} - -Replayer *Registry::GetReplayer(unsigned id) { - assert(m_ids.count(id) != 0 && "ID not in registry"); - return m_ids[id].first; -} - -std::string Registry::SignatureStr::ToString() const { - return (result + (result.empty() ? "" : " ") + scope + "::" + name + args) - .str(); -} - -unsigned ObjectToIndex::GetIndexForObjectImpl(const void *object) { - unsigned index = m_mapping.size() + 1; - auto it = m_mapping.find(object); - if (it == m_mapping.end()) - m_mapping[object] = index; - return m_mapping[object]; -} - -Recorder::Recorder() - : m_pretty_func(), m_pretty_args(), - - m_sequence(std::numeric_limits<unsigned>::max()) { - if (!g_global_boundary) { - g_global_boundary = true; - m_local_boundary = true; - m_sequence = GetNextSequenceNumber(); - } -} - -Recorder::Recorder(llvm::StringRef pretty_func, std::string &&pretty_args) - : m_serializer(nullptr), m_pretty_func(pretty_func), - m_pretty_args(pretty_args), m_local_boundary(false), - m_result_recorded(true), - m_sequence(std::numeric_limits<unsigned>::max()) { - if (!g_global_boundary) { - g_global_boundary = true; - m_local_boundary = true; - m_sequence = GetNextSequenceNumber(); - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "{0} ({1})", - m_pretty_func, m_pretty_args); - } -} - -Recorder::~Recorder() { - assert(m_result_recorded && "Did you forget LLDB_RECORD_RESULT?"); - UpdateBoundary(); -} - -unsigned Recorder::GetSequenceNumber() const { - assert(m_sequence != std::numeric_limits<unsigned>::max()); - return m_sequence; -} - -void Recorder::PrivateThread() { g_global_boundary = true; } - -void Recorder::UpdateBoundary() { - if (m_local_boundary) - g_global_boundary = false; -} - -void InstrumentationData::Initialize(Serializer &serializer, - Registry ®istry) { - InstanceImpl().emplace(serializer, registry); -} - -void InstrumentationData::Initialize(Deserializer &deserializer, - Registry ®istry) { - InstanceImpl().emplace(deserializer, registry); -} - -InstrumentationData &InstrumentationData::Instance() { - if (!InstanceImpl()) - InstanceImpl().emplace(); - return *InstanceImpl(); -} - -llvm::Optional<InstrumentationData> &InstrumentationData::InstanceImpl() { - static llvm::Optional<InstrumentationData> g_instrumentation_data; - return g_instrumentation_data; -} - -std::atomic<unsigned> lldb_private::repro::Recorder::g_sequence; -std::mutex lldb_private::repro::Recorder::g_mutex; |