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 1158947cf8SJonas Devlieghere #include "lldb/API/LLDB.h" 1258947cf8SJonas Devlieghere #include "lldb/API/SBAddress.h" 1358947cf8SJonas Devlieghere #include "lldb/API/SBAttachInfo.h" 1458947cf8SJonas Devlieghere #include "lldb/API/SBBlock.h" 1558947cf8SJonas Devlieghere #include "lldb/API/SBBreakpoint.h" 1658947cf8SJonas Devlieghere #include "lldb/API/SBCommandInterpreter.h" 174b354039SJonas Devlieghere #include "lldb/API/SBCommandInterpreterRunOptions.h" 1858947cf8SJonas Devlieghere #include "lldb/API/SBData.h" 1958947cf8SJonas Devlieghere #include "lldb/API/SBDebugger.h" 2058947cf8SJonas Devlieghere #include "lldb/API/SBDeclaration.h" 2158947cf8SJonas Devlieghere #include "lldb/API/SBError.h" 2258947cf8SJonas Devlieghere #include "lldb/API/SBFileSpec.h" 2358947cf8SJonas Devlieghere #include "lldb/API/SBHostOS.h" 2458947cf8SJonas Devlieghere #include "lldb/API/SBReproducer.h" 2558947cf8SJonas Devlieghere #include "lldb/Host/FileSystem.h" 26*ccf1469aSJonas Devlieghere #include "lldb/Version/Version.h" 2758947cf8SJonas Devlieghere 2858947cf8SJonas Devlieghere using namespace lldb; 2958947cf8SJonas Devlieghere using namespace lldb_private; 3058947cf8SJonas Devlieghere using namespace lldb_private::repro; 3158947cf8SJonas Devlieghere 3237469061SJonas Devlieghere SBReplayOptions::SBReplayOptions() 3313cde673SMartin Storsjö : m_opaque_up(std::make_unique<ReplayOptions>()){} 3437469061SJonas Devlieghere 3537469061SJonas Devlieghere SBReplayOptions::SBReplayOptions(const SBReplayOptions &rhs) 3637469061SJonas Devlieghere : m_opaque_up(std::make_unique<ReplayOptions>(*rhs.m_opaque_up)) {} 3737469061SJonas Devlieghere 3837469061SJonas Devlieghere SBReplayOptions::~SBReplayOptions() = default; 3937469061SJonas Devlieghere 4037469061SJonas Devlieghere SBReplayOptions &SBReplayOptions::operator=(const SBReplayOptions &rhs) { 4137469061SJonas Devlieghere if (this == &rhs) 4237469061SJonas Devlieghere return *this; 4337469061SJonas Devlieghere *m_opaque_up = *rhs.m_opaque_up; 4437469061SJonas Devlieghere return *this; 4537469061SJonas Devlieghere } 4637469061SJonas Devlieghere 4737469061SJonas Devlieghere void SBReplayOptions::SetVerify(bool verify) { m_opaque_up->verify = verify; } 4837469061SJonas Devlieghere 4937469061SJonas Devlieghere bool SBReplayOptions::GetVerify() const { return m_opaque_up->verify; } 5037469061SJonas Devlieghere 5137469061SJonas Devlieghere void SBReplayOptions::SetCheckVersion(bool check) { 5237469061SJonas Devlieghere m_opaque_up->check_version = check; 5337469061SJonas Devlieghere } 5437469061SJonas Devlieghere 5537469061SJonas Devlieghere bool SBReplayOptions::GetCheckVersion() const { 5637469061SJonas Devlieghere return m_opaque_up->check_version; 5737469061SJonas Devlieghere } 5837469061SJonas Devlieghere 59baf5664fSJonas Devlieghere SBRegistry::SBRegistry() { 60ae211eceSMichal Gorny Registry &R = *this; 61baf5664fSJonas Devlieghere 62ae211eceSMichal Gorny RegisterMethods<SBAddress>(R); 63ae211eceSMichal Gorny RegisterMethods<SBAttachInfo>(R); 64ae211eceSMichal Gorny RegisterMethods<SBBlock>(R); 65ae211eceSMichal Gorny RegisterMethods<SBBreakpoint>(R); 66ae211eceSMichal Gorny RegisterMethods<SBBreakpointList>(R); 67ae211eceSMichal Gorny RegisterMethods<SBBreakpointLocation>(R); 68ae211eceSMichal Gorny RegisterMethods<SBBreakpointName>(R); 69ae211eceSMichal Gorny RegisterMethods<SBBroadcaster>(R); 704b354039SJonas Devlieghere RegisterMethods<SBCommandInterpreter>(R); 71ae211eceSMichal Gorny RegisterMethods<SBCommandInterpreterRunOptions>(R); 72ae211eceSMichal Gorny RegisterMethods<SBCommandReturnObject>(R); 73ae211eceSMichal Gorny RegisterMethods<SBCommunication>(R); 74ae211eceSMichal Gorny RegisterMethods<SBCompileUnit>(R); 75ae211eceSMichal Gorny RegisterMethods<SBData>(R); 76ae211eceSMichal Gorny RegisterMethods<SBDebugger>(R); 77ae211eceSMichal Gorny RegisterMethods<SBDeclaration>(R); 78690993a0SJonas Devlieghere RegisterMethods<SBEnvironment>(R); 79ae211eceSMichal Gorny RegisterMethods<SBError>(R); 80ae211eceSMichal Gorny RegisterMethods<SBEvent>(R); 81ae211eceSMichal Gorny RegisterMethods<SBExecutionContext>(R); 82ae211eceSMichal Gorny RegisterMethods<SBExpressionOptions>(R); 8357504530SLawrence D'Anna RegisterMethods<SBFile>(R); 84ae211eceSMichal Gorny RegisterMethods<SBFileSpec>(R); 85ae211eceSMichal Gorny RegisterMethods<SBFileSpecList>(R); 86ae211eceSMichal Gorny RegisterMethods<SBFrame>(R); 87ae211eceSMichal Gorny RegisterMethods<SBFunction>(R); 88ae211eceSMichal Gorny RegisterMethods<SBHostOS>(R); 89690993a0SJonas Devlieghere RegisterMethods<SBInputReader>(R); 90ae211eceSMichal Gorny RegisterMethods<SBInstruction>(R); 91ae211eceSMichal Gorny RegisterMethods<SBInstructionList>(R); 92ae211eceSMichal Gorny RegisterMethods<SBLanguageRuntime>(R); 93ae211eceSMichal Gorny RegisterMethods<SBLaunchInfo>(R); 94ae211eceSMichal Gorny RegisterMethods<SBLineEntry>(R); 95ae211eceSMichal Gorny RegisterMethods<SBListener>(R); 96ae211eceSMichal Gorny RegisterMethods<SBMemoryRegionInfo>(R); 97ae211eceSMichal Gorny RegisterMethods<SBMemoryRegionInfoList>(R); 98ae211eceSMichal Gorny RegisterMethods<SBModule>(R); 99ae211eceSMichal Gorny RegisterMethods<SBModuleSpec>(R); 100690993a0SJonas Devlieghere RegisterMethods<SBPlatform>(R); 101ae211eceSMichal Gorny RegisterMethods<SBPlatformConnectOptions>(R); 102ae211eceSMichal Gorny RegisterMethods<SBPlatformShellCommand>(R); 103ae211eceSMichal Gorny RegisterMethods<SBProcess>(R); 104ae211eceSMichal Gorny RegisterMethods<SBProcessInfo>(R); 105ae211eceSMichal Gorny RegisterMethods<SBQueue>(R); 106ae211eceSMichal Gorny RegisterMethods<SBQueueItem>(R); 107ae211eceSMichal Gorny RegisterMethods<SBSection>(R); 108ae211eceSMichal Gorny RegisterMethods<SBSourceManager>(R); 109ae211eceSMichal Gorny RegisterMethods<SBStream>(R); 110ae211eceSMichal Gorny RegisterMethods<SBStringList>(R); 111ae211eceSMichal Gorny RegisterMethods<SBStructuredData>(R); 112ae211eceSMichal Gorny RegisterMethods<SBSymbol>(R); 113ae211eceSMichal Gorny RegisterMethods<SBSymbolContext>(R); 114ae211eceSMichal Gorny RegisterMethods<SBSymbolContextList>(R); 115ae211eceSMichal Gorny RegisterMethods<SBTarget>(R); 116ae211eceSMichal Gorny RegisterMethods<SBThread>(R); 117ae211eceSMichal Gorny RegisterMethods<SBThreadCollection>(R); 118ae211eceSMichal Gorny RegisterMethods<SBThreadPlan>(R); 119ae211eceSMichal Gorny RegisterMethods<SBTrace>(R); 120ae211eceSMichal Gorny RegisterMethods<SBType>(R); 121ae211eceSMichal Gorny RegisterMethods<SBTypeCategory>(R); 122ae211eceSMichal Gorny RegisterMethods<SBTypeEnumMember>(R); 123ae211eceSMichal Gorny RegisterMethods<SBTypeFilter>(R); 124ae211eceSMichal Gorny RegisterMethods<SBTypeFormat>(R); 125ae211eceSMichal Gorny RegisterMethods<SBTypeNameSpecifier>(R); 126ae211eceSMichal Gorny RegisterMethods<SBTypeSummary>(R); 127690993a0SJonas Devlieghere RegisterMethods<SBTypeSummaryOptions>(R); 128ae211eceSMichal Gorny RegisterMethods<SBTypeSynthetic>(R); 129ae211eceSMichal Gorny RegisterMethods<SBUnixSignals>(R); 130ae211eceSMichal Gorny RegisterMethods<SBValue>(R); 131ae211eceSMichal Gorny RegisterMethods<SBValueList>(R); 132ae211eceSMichal Gorny RegisterMethods<SBVariablesOptions>(R); 133ae211eceSMichal Gorny RegisterMethods<SBWatchpoint>(R); 134baf5664fSJonas Devlieghere } 13558947cf8SJonas Devlieghere 13613ecae2fSJonas Devlieghere const char *SBReproducer::Capture() { 13713ecae2fSJonas Devlieghere static std::string error; 13813ecae2fSJonas Devlieghere if (auto e = Reproducer::Initialize(ReproducerMode::Capture, llvm::None)) { 13913ecae2fSJonas Devlieghere error = llvm::toString(std::move(e)); 14013ecae2fSJonas Devlieghere return error.c_str(); 14113ecae2fSJonas Devlieghere } 142950a8aa1SJonas Devlieghere 143950a8aa1SJonas Devlieghere if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 144950a8aa1SJonas Devlieghere auto &p = g->GetOrCreate<SBProvider>(); 145950a8aa1SJonas Devlieghere InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); 146950a8aa1SJonas Devlieghere } 147950a8aa1SJonas Devlieghere 14813ecae2fSJonas Devlieghere return nullptr; 14913ecae2fSJonas Devlieghere } 15013ecae2fSJonas Devlieghere 151936c6242SJonas Devlieghere const char *SBReproducer::Capture(const char *path) { 152936c6242SJonas Devlieghere static std::string error; 153936c6242SJonas Devlieghere if (auto e = 154936c6242SJonas Devlieghere Reproducer::Initialize(ReproducerMode::Capture, FileSpec(path))) { 155936c6242SJonas Devlieghere error = llvm::toString(std::move(e)); 156936c6242SJonas Devlieghere return error.c_str(); 157936c6242SJonas Devlieghere } 158950a8aa1SJonas Devlieghere 159950a8aa1SJonas Devlieghere if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 160950a8aa1SJonas Devlieghere auto &p = g->GetOrCreate<SBProvider>(); 161950a8aa1SJonas Devlieghere InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); 162950a8aa1SJonas Devlieghere } 163950a8aa1SJonas Devlieghere 164936c6242SJonas Devlieghere return nullptr; 165936c6242SJonas Devlieghere } 16658947cf8SJonas Devlieghere 167fc410138SJonas Devlieghere const char *SBReproducer::PassiveReplay(const char *path) { 168fc410138SJonas Devlieghere static std::string error; 169950a8aa1SJonas Devlieghere if (auto e = Reproducer::Initialize(ReproducerMode::PassiveReplay, 170950a8aa1SJonas Devlieghere FileSpec(path))) { 171fc410138SJonas Devlieghere error = llvm::toString(std::move(e)); 172fc410138SJonas Devlieghere return error.c_str(); 173fc410138SJonas Devlieghere } 174950a8aa1SJonas Devlieghere 175950a8aa1SJonas Devlieghere if (auto *l = lldb_private::repro::Reproducer::Instance().GetLoader()) { 176950a8aa1SJonas Devlieghere FileSpec file = l->GetFile<SBProvider::Info>(); 177950a8aa1SJonas Devlieghere auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); 178950a8aa1SJonas Devlieghere if (!error_or_file) { 179950a8aa1SJonas Devlieghere error = 180950a8aa1SJonas Devlieghere "unable to read SB API data: " + error_or_file.getError().message(); 181950a8aa1SJonas Devlieghere return error.c_str(); 182950a8aa1SJonas Devlieghere } 183950a8aa1SJonas Devlieghere static ReplayData r(std::move(*error_or_file)); 184950a8aa1SJonas Devlieghere InstrumentationData::Initialize(r.GetDeserializer(), r.GetRegistry()); 185950a8aa1SJonas Devlieghere } 186950a8aa1SJonas Devlieghere 187fc410138SJonas Devlieghere return nullptr; 188fc410138SJonas Devlieghere } 189fc410138SJonas Devlieghere 190d3ba1e02SJonas Devlieghere const char *SBReproducer::Replay(const char *path) { 19137469061SJonas Devlieghere SBReplayOptions options; 19237469061SJonas Devlieghere return SBReproducer::Replay(path, options); 193d3ba1e02SJonas Devlieghere } 194d3ba1e02SJonas Devlieghere 19562827737SJonas Devlieghere const char *SBReproducer::Replay(const char *path, bool skip_version_check) { 19637469061SJonas Devlieghere SBReplayOptions options; 19737469061SJonas Devlieghere options.SetCheckVersion(!skip_version_check); 19837469061SJonas Devlieghere return SBReproducer::Replay(path, options); 19937469061SJonas Devlieghere } 20037469061SJonas Devlieghere 20137469061SJonas Devlieghere const char *SBReproducer::Replay(const char *path, 20237469061SJonas Devlieghere const SBReplayOptions &options) { 203936c6242SJonas Devlieghere static std::string error; 204936c6242SJonas Devlieghere if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) { 205936c6242SJonas Devlieghere error = llvm::toString(std::move(e)); 206936c6242SJonas Devlieghere return error.c_str(); 207936c6242SJonas Devlieghere } 208936c6242SJonas Devlieghere 209936c6242SJonas Devlieghere repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); 210936c6242SJonas Devlieghere if (!loader) { 211936c6242SJonas Devlieghere error = "unable to get replay loader."; 212936c6242SJonas Devlieghere return error.c_str(); 213936c6242SJonas Devlieghere } 214936c6242SJonas Devlieghere 21537469061SJonas Devlieghere if (options.GetCheckVersion()) { 21662827737SJonas Devlieghere llvm::Expected<std::string> version = loader->LoadBuffer<VersionProvider>(); 21762827737SJonas Devlieghere if (!version) { 21862827737SJonas Devlieghere error = llvm::toString(version.takeError()); 21962827737SJonas Devlieghere return error.c_str(); 22062827737SJonas Devlieghere } 22162827737SJonas Devlieghere if (lldb_private::GetVersion() != llvm::StringRef(*version).rtrim()) { 22262827737SJonas Devlieghere error = "reproducer capture and replay version don't match:\n"; 22362827737SJonas Devlieghere error.append("reproducer captured with:\n"); 22462827737SJonas Devlieghere error.append(*version); 22562827737SJonas Devlieghere error.append("reproducer replayed with:\n"); 22662827737SJonas Devlieghere error.append(lldb_private::GetVersion()); 22762827737SJonas Devlieghere return error.c_str(); 22862827737SJonas Devlieghere } 22962827737SJonas Devlieghere } 23062827737SJonas Devlieghere 23137469061SJonas Devlieghere if (options.GetVerify()) { 23237469061SJonas Devlieghere bool verification_failed = false; 23337469061SJonas Devlieghere llvm::raw_string_ostream os(error); 23437469061SJonas Devlieghere auto error_callback = [&](llvm::StringRef error) { 23537469061SJonas Devlieghere verification_failed = true; 23637469061SJonas Devlieghere os << "\nerror: " << error; 23737469061SJonas Devlieghere }; 23837469061SJonas Devlieghere 23937469061SJonas Devlieghere auto warning_callback = [&](llvm::StringRef warning) { 24037469061SJonas Devlieghere verification_failed = true; 24137469061SJonas Devlieghere os << "\nwarning: " << warning; 24237469061SJonas Devlieghere }; 24337469061SJonas Devlieghere 24437469061SJonas Devlieghere auto note_callback = [&](llvm::StringRef warning) {}; 24537469061SJonas Devlieghere 24637469061SJonas Devlieghere Verifier verifier(loader); 24737469061SJonas Devlieghere verifier.Verify(error_callback, warning_callback, note_callback); 24837469061SJonas Devlieghere 24937469061SJonas Devlieghere if (verification_failed) { 25037469061SJonas Devlieghere os.flush(); 25137469061SJonas Devlieghere return error.c_str(); 25237469061SJonas Devlieghere } 25337469061SJonas Devlieghere } 25437469061SJonas Devlieghere 255ef96e985SJonas Devlieghere FileSpec file = loader->GetFile<SBProvider::Info>(); 256936c6242SJonas Devlieghere if (!file) { 257936c6242SJonas Devlieghere error = "unable to get replay data from reproducer."; 258936c6242SJonas Devlieghere return error.c_str(); 259936c6242SJonas Devlieghere } 26058947cf8SJonas Devlieghere 26158947cf8SJonas Devlieghere SBRegistry registry; 26258947cf8SJonas Devlieghere registry.Replay(file); 26358947cf8SJonas Devlieghere 264936c6242SJonas Devlieghere return nullptr; 265c8dfe907SJonas Devlieghere } 266c8dfe907SJonas Devlieghere 26773811d32SJonas Devlieghere const char *SBReproducer::Finalize(const char *path) { 26873811d32SJonas Devlieghere static std::string error; 26973811d32SJonas Devlieghere if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) { 27073811d32SJonas Devlieghere error = llvm::toString(std::move(e)); 27173811d32SJonas Devlieghere return error.c_str(); 27273811d32SJonas Devlieghere } 27373811d32SJonas Devlieghere 27473811d32SJonas Devlieghere repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); 27573811d32SJonas Devlieghere if (!loader) { 27673811d32SJonas Devlieghere error = "unable to get replay loader."; 27773811d32SJonas Devlieghere return error.c_str(); 27873811d32SJonas Devlieghere } 27973811d32SJonas Devlieghere 28073811d32SJonas Devlieghere if (auto e = repro::Finalize(loader)) { 28173811d32SJonas Devlieghere error = llvm::toString(std::move(e)); 28273811d32SJonas Devlieghere return error.c_str(); 28373811d32SJonas Devlieghere } 28473811d32SJonas Devlieghere 28573811d32SJonas Devlieghere return nullptr; 28673811d32SJonas Devlieghere } 28773811d32SJonas Devlieghere 288c8dfe907SJonas Devlieghere bool SBReproducer::Generate() { 289c8dfe907SJonas Devlieghere auto &r = Reproducer::Instance(); 290c8dfe907SJonas Devlieghere if (auto generator = r.GetGenerator()) { 291c8dfe907SJonas Devlieghere generator->Keep(); 292c8dfe907SJonas Devlieghere return true; 293c8dfe907SJonas Devlieghere } 294c8dfe907SJonas Devlieghere return false; 295c8dfe907SJonas Devlieghere } 296c8dfe907SJonas Devlieghere 297066e817bSJonas Devlieghere bool SBReproducer::SetAutoGenerate(bool b) { 298066e817bSJonas Devlieghere auto &r = Reproducer::Instance(); 299066e817bSJonas Devlieghere if (auto generator = r.GetGenerator()) { 300066e817bSJonas Devlieghere generator->SetAutoGenerate(b); 301066e817bSJonas Devlieghere return true; 302066e817bSJonas Devlieghere } 303066e817bSJonas Devlieghere return false; 304066e817bSJonas Devlieghere } 305066e817bSJonas Devlieghere 306c8dfe907SJonas Devlieghere const char *SBReproducer::GetPath() { 30773811d32SJonas Devlieghere ConstString path; 308c8dfe907SJonas Devlieghere auto &r = Reproducer::Instance(); 30973811d32SJonas Devlieghere if (FileSpec reproducer_path = Reproducer::Instance().GetReproducerPath()) 31073811d32SJonas Devlieghere path = ConstString(r.GetReproducerPath().GetCString()); 31173811d32SJonas Devlieghere return path.GetCString(); 31258947cf8SJonas Devlieghere } 31358947cf8SJonas Devlieghere 3146671a81bSJonas Devlieghere void SBReproducer::SetWorkingDirectory(const char *path) { 3156671a81bSJonas Devlieghere if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 316f8df2e1aSJonas Devlieghere auto &wp = g->GetOrCreate<repro::WorkingDirectoryProvider>(); 317c90ca0c8SJonas Devlieghere wp.SetDirectory(path); 318f8df2e1aSJonas Devlieghere auto &fp = g->GetOrCreate<repro::FileProvider>(); 319c90ca0c8SJonas Devlieghere fp.RecordInterestingDirectory(wp.GetDirectory()); 3206671a81bSJonas Devlieghere } 3216671a81bSJonas Devlieghere } 3226671a81bSJonas Devlieghere 32358947cf8SJonas Devlieghere char lldb_private::repro::SBProvider::ID = 0; 324ef96e985SJonas Devlieghere const char *SBProvider::Info::name = "sbapi"; 325ef96e985SJonas Devlieghere const char *SBProvider::Info::file = "sbapi.bin"; 326