//===-- SBReproducer.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 "SBReproducerPrivate.h" #include "SBReproducerPrivate.h" #include "lldb/API/LLDB.h" #include "lldb/API/SBAddress.h" #include "lldb/API/SBAttachInfo.h" #include "lldb/API/SBBlock.h" #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBCommandInterpreter.h" #include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBData.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBDeclaration.h" #include "lldb/API/SBError.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBHostOS.h" #include "lldb/API/SBReproducer.h" #include "lldb/Host/FileSystem.h" #include "lldb/lldb-private.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::repro; SBRegistry::SBRegistry() { Registry &R = *this; RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); } const char *SBReproducer::Capture() { static std::string error; if (auto e = Reproducer::Initialize(ReproducerMode::Capture, llvm::None)) { error = llvm::toString(std::move(e)); return error.c_str(); } if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { auto &p = g->GetOrCreate(); InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); } return nullptr; } const char *SBReproducer::Capture(const char *path) { static std::string error; if (auto e = Reproducer::Initialize(ReproducerMode::Capture, FileSpec(path))) { error = llvm::toString(std::move(e)); return error.c_str(); } if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { auto &p = g->GetOrCreate(); InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); } return nullptr; } const char *SBReproducer::PassiveReplay(const char *path) { static std::string error; if (auto e = Reproducer::Initialize(ReproducerMode::PassiveReplay, FileSpec(path))) { error = llvm::toString(std::move(e)); return error.c_str(); } if (auto *l = lldb_private::repro::Reproducer::Instance().GetLoader()) { FileSpec file = l->GetFile(); auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); if (!error_or_file) { error = "unable to read SB API data: " + error_or_file.getError().message(); return error.c_str(); } static ReplayData r(std::move(*error_or_file)); InstrumentationData::Initialize(r.GetDeserializer(), r.GetRegistry()); } return nullptr; } const char *SBReproducer::Replay(const char *path) { return SBReproducer::Replay(path, false); } const char *SBReproducer::Replay(const char *path, bool skip_version_check) { static std::string error; if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) { error = llvm::toString(std::move(e)); return error.c_str(); } repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); if (!loader) { error = "unable to get replay loader."; return error.c_str(); } if (!skip_version_check) { llvm::Expected version = loader->LoadBuffer(); if (!version) { error = llvm::toString(version.takeError()); return error.c_str(); } if (lldb_private::GetVersion() != llvm::StringRef(*version).rtrim()) { error = "reproducer capture and replay version don't match:\n"; error.append("reproducer captured with:\n"); error.append(*version); error.append("reproducer replayed with:\n"); error.append(lldb_private::GetVersion()); return error.c_str(); } } FileSpec file = loader->GetFile(); if (!file) { error = "unable to get replay data from reproducer."; return error.c_str(); } SBRegistry registry; registry.Replay(file); return nullptr; } bool SBReproducer::Generate() { auto &r = Reproducer::Instance(); if (auto generator = r.GetGenerator()) { generator->Keep(); return true; } return false; } bool SBReproducer::SetAutoGenerate(bool b) { auto &r = Reproducer::Instance(); if (auto generator = r.GetGenerator()) { generator->SetAutoGenerate(b); return true; } return false; } const char *SBReproducer::GetPath() { static std::string path; auto &r = Reproducer::Instance(); path = r.GetReproducerPath().GetCString(); return path.c_str(); } void SBReproducer::SetWorkingDirectory(const char *path) { if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { g->GetOrCreate().Update(path); } } char lldb_private::repro::SBProvider::ID = 0; const char *SBProvider::Info::name = "sbapi"; const char *SBProvider::Info::file = "sbapi.bin";