180814287SRaphael Isemann //===-- SBReproducer.cpp --------------------------------------------------===// 258947cf8SJonas Devlieghere // 3023f9998SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4023f9998SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5023f9998SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 658947cf8SJonas Devlieghere // 758947cf8SJonas Devlieghere //===----------------------------------------------------------------------===// 858947cf8SJonas Devlieghere 958947cf8SJonas Devlieghere #include "SBReproducerPrivate.h" 1058947cf8SJonas Devlieghere 11baf5664fSJonas Devlieghere #include "SBReproducerPrivate.h" 1258947cf8SJonas Devlieghere #include "lldb/API/LLDB.h" 1358947cf8SJonas Devlieghere #include "lldb/API/SBAddress.h" 1458947cf8SJonas Devlieghere #include "lldb/API/SBAttachInfo.h" 1558947cf8SJonas Devlieghere #include "lldb/API/SBBlock.h" 1658947cf8SJonas Devlieghere #include "lldb/API/SBBreakpoint.h" 1758947cf8SJonas Devlieghere #include "lldb/API/SBCommandInterpreter.h" 184b354039SJonas Devlieghere #include "lldb/API/SBCommandInterpreterRunOptions.h" 1958947cf8SJonas Devlieghere #include "lldb/API/SBData.h" 2058947cf8SJonas Devlieghere #include "lldb/API/SBDebugger.h" 2158947cf8SJonas Devlieghere #include "lldb/API/SBDeclaration.h" 2258947cf8SJonas Devlieghere #include "lldb/API/SBError.h" 2358947cf8SJonas Devlieghere #include "lldb/API/SBFileSpec.h" 2458947cf8SJonas Devlieghere #include "lldb/API/SBHostOS.h" 2558947cf8SJonas Devlieghere #include "lldb/API/SBReproducer.h" 2658947cf8SJonas Devlieghere #include "lldb/Host/FileSystem.h" 2762827737SJonas Devlieghere #include "lldb/lldb-private.h" 2858947cf8SJonas Devlieghere 2958947cf8SJonas Devlieghere using namespace lldb; 3058947cf8SJonas Devlieghere using namespace lldb_private; 3158947cf8SJonas Devlieghere using namespace lldb_private::repro; 3258947cf8SJonas Devlieghere 33baf5664fSJonas Devlieghere SBRegistry::SBRegistry() { 34ae211eceSMichal Gorny Registry &R = *this; 35baf5664fSJonas Devlieghere 36ae211eceSMichal Gorny RegisterMethods<SBAddress>(R); 37ae211eceSMichal Gorny RegisterMethods<SBAttachInfo>(R); 38ae211eceSMichal Gorny RegisterMethods<SBBlock>(R); 39ae211eceSMichal Gorny RegisterMethods<SBBreakpoint>(R); 40ae211eceSMichal Gorny RegisterMethods<SBBreakpointList>(R); 41ae211eceSMichal Gorny RegisterMethods<SBBreakpointLocation>(R); 42ae211eceSMichal Gorny RegisterMethods<SBBreakpointName>(R); 43ae211eceSMichal Gorny RegisterMethods<SBBroadcaster>(R); 444b354039SJonas Devlieghere RegisterMethods<SBCommandInterpreter>(R); 45ae211eceSMichal Gorny RegisterMethods<SBCommandInterpreterRunOptions>(R); 46ae211eceSMichal Gorny RegisterMethods<SBCommandReturnObject>(R); 47ae211eceSMichal Gorny RegisterMethods<SBCommunication>(R); 48ae211eceSMichal Gorny RegisterMethods<SBCompileUnit>(R); 49ae211eceSMichal Gorny RegisterMethods<SBData>(R); 50ae211eceSMichal Gorny RegisterMethods<SBDebugger>(R); 51ae211eceSMichal Gorny RegisterMethods<SBDeclaration>(R); 52*690993a0SJonas Devlieghere RegisterMethods<SBEnvironment>(R); 53ae211eceSMichal Gorny RegisterMethods<SBError>(R); 54ae211eceSMichal Gorny RegisterMethods<SBEvent>(R); 55ae211eceSMichal Gorny RegisterMethods<SBExecutionContext>(R); 56ae211eceSMichal Gorny RegisterMethods<SBExpressionOptions>(R); 5757504530SLawrence D'Anna RegisterMethods<SBFile>(R); 58ae211eceSMichal Gorny RegisterMethods<SBFileSpec>(R); 59ae211eceSMichal Gorny RegisterMethods<SBFileSpecList>(R); 60ae211eceSMichal Gorny RegisterMethods<SBFrame>(R); 61ae211eceSMichal Gorny RegisterMethods<SBFunction>(R); 62ae211eceSMichal Gorny RegisterMethods<SBHostOS>(R); 63*690993a0SJonas Devlieghere RegisterMethods<SBInputReader>(R); 64ae211eceSMichal Gorny RegisterMethods<SBInstruction>(R); 65ae211eceSMichal Gorny RegisterMethods<SBInstructionList>(R); 66ae211eceSMichal Gorny RegisterMethods<SBLanguageRuntime>(R); 67ae211eceSMichal Gorny RegisterMethods<SBLaunchInfo>(R); 68ae211eceSMichal Gorny RegisterMethods<SBLineEntry>(R); 69ae211eceSMichal Gorny RegisterMethods<SBListener>(R); 70ae211eceSMichal Gorny RegisterMethods<SBMemoryRegionInfo>(R); 71ae211eceSMichal Gorny RegisterMethods<SBMemoryRegionInfoList>(R); 72ae211eceSMichal Gorny RegisterMethods<SBModule>(R); 73ae211eceSMichal Gorny RegisterMethods<SBModuleSpec>(R); 74*690993a0SJonas Devlieghere RegisterMethods<SBPlatform>(R); 75ae211eceSMichal Gorny RegisterMethods<SBPlatformConnectOptions>(R); 76ae211eceSMichal Gorny RegisterMethods<SBPlatformShellCommand>(R); 77ae211eceSMichal Gorny RegisterMethods<SBProcess>(R); 78ae211eceSMichal Gorny RegisterMethods<SBProcessInfo>(R); 79ae211eceSMichal Gorny RegisterMethods<SBQueue>(R); 80ae211eceSMichal Gorny RegisterMethods<SBQueueItem>(R); 81ae211eceSMichal Gorny RegisterMethods<SBSection>(R); 82ae211eceSMichal Gorny RegisterMethods<SBSourceManager>(R); 83ae211eceSMichal Gorny RegisterMethods<SBStream>(R); 84ae211eceSMichal Gorny RegisterMethods<SBStringList>(R); 85ae211eceSMichal Gorny RegisterMethods<SBStructuredData>(R); 86ae211eceSMichal Gorny RegisterMethods<SBSymbol>(R); 87ae211eceSMichal Gorny RegisterMethods<SBSymbolContext>(R); 88ae211eceSMichal Gorny RegisterMethods<SBSymbolContextList>(R); 89ae211eceSMichal Gorny RegisterMethods<SBTarget>(R); 90ae211eceSMichal Gorny RegisterMethods<SBThread>(R); 91ae211eceSMichal Gorny RegisterMethods<SBThreadCollection>(R); 92ae211eceSMichal Gorny RegisterMethods<SBThreadPlan>(R); 93ae211eceSMichal Gorny RegisterMethods<SBTrace>(R); 94ae211eceSMichal Gorny RegisterMethods<SBTraceOptions>(R); 95ae211eceSMichal Gorny RegisterMethods<SBType>(R); 96ae211eceSMichal Gorny RegisterMethods<SBTypeCategory>(R); 97ae211eceSMichal Gorny RegisterMethods<SBTypeEnumMember>(R); 98ae211eceSMichal Gorny RegisterMethods<SBTypeFilter>(R); 99ae211eceSMichal Gorny RegisterMethods<SBTypeFormat>(R); 100ae211eceSMichal Gorny RegisterMethods<SBTypeNameSpecifier>(R); 101ae211eceSMichal Gorny RegisterMethods<SBTypeSummary>(R); 102*690993a0SJonas Devlieghere RegisterMethods<SBTypeSummaryOptions>(R); 103ae211eceSMichal Gorny RegisterMethods<SBTypeSynthetic>(R); 104ae211eceSMichal Gorny RegisterMethods<SBUnixSignals>(R); 105ae211eceSMichal Gorny RegisterMethods<SBValue>(R); 106ae211eceSMichal Gorny RegisterMethods<SBValueList>(R); 107ae211eceSMichal Gorny RegisterMethods<SBVariablesOptions>(R); 108ae211eceSMichal Gorny RegisterMethods<SBWatchpoint>(R); 109baf5664fSJonas Devlieghere } 11058947cf8SJonas Devlieghere 11113ecae2fSJonas Devlieghere const char *SBReproducer::Capture() { 11213ecae2fSJonas Devlieghere static std::string error; 11313ecae2fSJonas Devlieghere if (auto e = Reproducer::Initialize(ReproducerMode::Capture, llvm::None)) { 11413ecae2fSJonas Devlieghere error = llvm::toString(std::move(e)); 11513ecae2fSJonas Devlieghere return error.c_str(); 11613ecae2fSJonas Devlieghere } 117950a8aa1SJonas Devlieghere 118950a8aa1SJonas Devlieghere if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 119950a8aa1SJonas Devlieghere auto &p = g->GetOrCreate<SBProvider>(); 120950a8aa1SJonas Devlieghere InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); 121950a8aa1SJonas Devlieghere } 122950a8aa1SJonas Devlieghere 12313ecae2fSJonas Devlieghere return nullptr; 12413ecae2fSJonas Devlieghere } 12513ecae2fSJonas Devlieghere 126936c6242SJonas Devlieghere const char *SBReproducer::Capture(const char *path) { 127936c6242SJonas Devlieghere static std::string error; 128936c6242SJonas Devlieghere if (auto e = 129936c6242SJonas Devlieghere Reproducer::Initialize(ReproducerMode::Capture, FileSpec(path))) { 130936c6242SJonas Devlieghere error = llvm::toString(std::move(e)); 131936c6242SJonas Devlieghere return error.c_str(); 132936c6242SJonas Devlieghere } 133950a8aa1SJonas Devlieghere 134950a8aa1SJonas Devlieghere if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 135950a8aa1SJonas Devlieghere auto &p = g->GetOrCreate<SBProvider>(); 136950a8aa1SJonas Devlieghere InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); 137950a8aa1SJonas Devlieghere } 138950a8aa1SJonas Devlieghere 139936c6242SJonas Devlieghere return nullptr; 140936c6242SJonas Devlieghere } 14158947cf8SJonas Devlieghere 142fc410138SJonas Devlieghere const char *SBReproducer::PassiveReplay(const char *path) { 143fc410138SJonas Devlieghere static std::string error; 144950a8aa1SJonas Devlieghere if (auto e = Reproducer::Initialize(ReproducerMode::PassiveReplay, 145950a8aa1SJonas Devlieghere FileSpec(path))) { 146fc410138SJonas Devlieghere error = llvm::toString(std::move(e)); 147fc410138SJonas Devlieghere return error.c_str(); 148fc410138SJonas Devlieghere } 149950a8aa1SJonas Devlieghere 150950a8aa1SJonas Devlieghere if (auto *l = lldb_private::repro::Reproducer::Instance().GetLoader()) { 151950a8aa1SJonas Devlieghere FileSpec file = l->GetFile<SBProvider::Info>(); 152950a8aa1SJonas Devlieghere auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); 153950a8aa1SJonas Devlieghere if (!error_or_file) { 154950a8aa1SJonas Devlieghere error = 155950a8aa1SJonas Devlieghere "unable to read SB API data: " + error_or_file.getError().message(); 156950a8aa1SJonas Devlieghere return error.c_str(); 157950a8aa1SJonas Devlieghere } 158950a8aa1SJonas Devlieghere static ReplayData r(std::move(*error_or_file)); 159950a8aa1SJonas Devlieghere InstrumentationData::Initialize(r.GetDeserializer(), r.GetRegistry()); 160950a8aa1SJonas Devlieghere } 161950a8aa1SJonas Devlieghere 162fc410138SJonas Devlieghere return nullptr; 163fc410138SJonas Devlieghere } 164fc410138SJonas Devlieghere 165d3ba1e02SJonas Devlieghere const char *SBReproducer::Replay(const char *path) { 166d3ba1e02SJonas Devlieghere return SBReproducer::Replay(path, false); 167d3ba1e02SJonas Devlieghere } 168d3ba1e02SJonas Devlieghere 16962827737SJonas Devlieghere const char *SBReproducer::Replay(const char *path, bool skip_version_check) { 170936c6242SJonas Devlieghere static std::string error; 171936c6242SJonas Devlieghere if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) { 172936c6242SJonas Devlieghere error = llvm::toString(std::move(e)); 173936c6242SJonas Devlieghere return error.c_str(); 174936c6242SJonas Devlieghere } 175936c6242SJonas Devlieghere 176936c6242SJonas Devlieghere repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); 177936c6242SJonas Devlieghere if (!loader) { 178936c6242SJonas Devlieghere error = "unable to get replay loader."; 179936c6242SJonas Devlieghere return error.c_str(); 180936c6242SJonas Devlieghere } 181936c6242SJonas Devlieghere 18262827737SJonas Devlieghere if (!skip_version_check) { 18362827737SJonas Devlieghere llvm::Expected<std::string> version = loader->LoadBuffer<VersionProvider>(); 18462827737SJonas Devlieghere if (!version) { 18562827737SJonas Devlieghere error = llvm::toString(version.takeError()); 18662827737SJonas Devlieghere return error.c_str(); 18762827737SJonas Devlieghere } 18862827737SJonas Devlieghere if (lldb_private::GetVersion() != llvm::StringRef(*version).rtrim()) { 18962827737SJonas Devlieghere error = "reproducer capture and replay version don't match:\n"; 19062827737SJonas Devlieghere error.append("reproducer captured with:\n"); 19162827737SJonas Devlieghere error.append(*version); 19262827737SJonas Devlieghere error.append("reproducer replayed with:\n"); 19362827737SJonas Devlieghere error.append(lldb_private::GetVersion()); 19462827737SJonas Devlieghere return error.c_str(); 19562827737SJonas Devlieghere } 19662827737SJonas Devlieghere } 19762827737SJonas Devlieghere 198ef96e985SJonas Devlieghere FileSpec file = loader->GetFile<SBProvider::Info>(); 199936c6242SJonas Devlieghere if (!file) { 200936c6242SJonas Devlieghere error = "unable to get replay data from reproducer."; 201936c6242SJonas Devlieghere return error.c_str(); 202936c6242SJonas Devlieghere } 20358947cf8SJonas Devlieghere 20458947cf8SJonas Devlieghere SBRegistry registry; 20558947cf8SJonas Devlieghere registry.Replay(file); 20658947cf8SJonas Devlieghere 207936c6242SJonas Devlieghere return nullptr; 208c8dfe907SJonas Devlieghere } 209c8dfe907SJonas Devlieghere 210c8dfe907SJonas Devlieghere bool SBReproducer::Generate() { 211c8dfe907SJonas Devlieghere auto &r = Reproducer::Instance(); 212c8dfe907SJonas Devlieghere if (auto generator = r.GetGenerator()) { 213c8dfe907SJonas Devlieghere generator->Keep(); 214c8dfe907SJonas Devlieghere return true; 215c8dfe907SJonas Devlieghere } 216c8dfe907SJonas Devlieghere return false; 217c8dfe907SJonas Devlieghere } 218c8dfe907SJonas Devlieghere 219066e817bSJonas Devlieghere bool SBReproducer::SetAutoGenerate(bool b) { 220066e817bSJonas Devlieghere auto &r = Reproducer::Instance(); 221066e817bSJonas Devlieghere if (auto generator = r.GetGenerator()) { 222066e817bSJonas Devlieghere generator->SetAutoGenerate(b); 223066e817bSJonas Devlieghere return true; 224066e817bSJonas Devlieghere } 225066e817bSJonas Devlieghere return false; 226066e817bSJonas Devlieghere } 227066e817bSJonas Devlieghere 228c8dfe907SJonas Devlieghere const char *SBReproducer::GetPath() { 229c8dfe907SJonas Devlieghere static std::string path; 230c8dfe907SJonas Devlieghere auto &r = Reproducer::Instance(); 231c8dfe907SJonas Devlieghere path = r.GetReproducerPath().GetCString(); 232c8dfe907SJonas Devlieghere return path.c_str(); 23358947cf8SJonas Devlieghere } 23458947cf8SJonas Devlieghere 2356671a81bSJonas Devlieghere void SBReproducer::SetWorkingDirectory(const char *path) { 2366671a81bSJonas Devlieghere if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 2376671a81bSJonas Devlieghere g->GetOrCreate<WorkingDirectoryProvider>().Update(path); 2386671a81bSJonas Devlieghere } 2396671a81bSJonas Devlieghere } 2406671a81bSJonas Devlieghere 24158947cf8SJonas Devlieghere char lldb_private::repro::SBProvider::ID = 0; 242ef96e985SJonas Devlieghere const char *SBProvider::Info::name = "sbapi"; 243ef96e985SJonas Devlieghere const char *SBProvider::Info::file = "sbapi.bin"; 244