1 //===-- SBReproducer.cpp --------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SBReproducerPrivate.h" 10 11 #include "SBReproducerPrivate.h" 12 #include "lldb/API/LLDB.h" 13 #include "lldb/API/SBAddress.h" 14 #include "lldb/API/SBAttachInfo.h" 15 #include "lldb/API/SBBlock.h" 16 #include "lldb/API/SBBreakpoint.h" 17 #include "lldb/API/SBCommandInterpreter.h" 18 #include "lldb/API/SBCommandInterpreterRunOptions.h" 19 #include "lldb/API/SBData.h" 20 #include "lldb/API/SBDebugger.h" 21 #include "lldb/API/SBDeclaration.h" 22 #include "lldb/API/SBError.h" 23 #include "lldb/API/SBFileSpec.h" 24 #include "lldb/API/SBHostOS.h" 25 #include "lldb/API/SBReproducer.h" 26 #include "lldb/Host/FileSystem.h" 27 #include "lldb/lldb-private.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 using namespace lldb_private::repro; 32 33 SBRegistry::SBRegistry() { 34 Registry &R = *this; 35 36 RegisterMethods<SBAddress>(R); 37 RegisterMethods<SBAttachInfo>(R); 38 RegisterMethods<SBBlock>(R); 39 RegisterMethods<SBBreakpoint>(R); 40 RegisterMethods<SBBreakpointList>(R); 41 RegisterMethods<SBBreakpointLocation>(R); 42 RegisterMethods<SBBreakpointName>(R); 43 RegisterMethods<SBBroadcaster>(R); 44 RegisterMethods<SBCommandInterpreter>(R); 45 RegisterMethods<SBCommandInterpreterRunOptions>(R); 46 RegisterMethods<SBCommandReturnObject>(R); 47 RegisterMethods<SBCommunication>(R); 48 RegisterMethods<SBCompileUnit>(R); 49 RegisterMethods<SBData>(R); 50 RegisterMethods<SBDebugger>(R); 51 RegisterMethods<SBDeclaration>(R); 52 RegisterMethods<SBEnvironment>(R); 53 RegisterMethods<SBError>(R); 54 RegisterMethods<SBEvent>(R); 55 RegisterMethods<SBExecutionContext>(R); 56 RegisterMethods<SBExpressionOptions>(R); 57 RegisterMethods<SBFile>(R); 58 RegisterMethods<SBFileSpec>(R); 59 RegisterMethods<SBFileSpecList>(R); 60 RegisterMethods<SBFrame>(R); 61 RegisterMethods<SBFunction>(R); 62 RegisterMethods<SBHostOS>(R); 63 RegisterMethods<SBInputReader>(R); 64 RegisterMethods<SBInstruction>(R); 65 RegisterMethods<SBInstructionList>(R); 66 RegisterMethods<SBLanguageRuntime>(R); 67 RegisterMethods<SBLaunchInfo>(R); 68 RegisterMethods<SBLineEntry>(R); 69 RegisterMethods<SBListener>(R); 70 RegisterMethods<SBMemoryRegionInfo>(R); 71 RegisterMethods<SBMemoryRegionInfoList>(R); 72 RegisterMethods<SBModule>(R); 73 RegisterMethods<SBModuleSpec>(R); 74 RegisterMethods<SBPlatform>(R); 75 RegisterMethods<SBPlatformConnectOptions>(R); 76 RegisterMethods<SBPlatformShellCommand>(R); 77 RegisterMethods<SBProcess>(R); 78 RegisterMethods<SBProcessInfo>(R); 79 RegisterMethods<SBQueue>(R); 80 RegisterMethods<SBQueueItem>(R); 81 RegisterMethods<SBSection>(R); 82 RegisterMethods<SBSourceManager>(R); 83 RegisterMethods<SBStream>(R); 84 RegisterMethods<SBStringList>(R); 85 RegisterMethods<SBStructuredData>(R); 86 RegisterMethods<SBSymbol>(R); 87 RegisterMethods<SBSymbolContext>(R); 88 RegisterMethods<SBSymbolContextList>(R); 89 RegisterMethods<SBTarget>(R); 90 RegisterMethods<SBThread>(R); 91 RegisterMethods<SBThreadCollection>(R); 92 RegisterMethods<SBThreadPlan>(R); 93 RegisterMethods<SBTrace>(R); 94 RegisterMethods<SBTraceOptions>(R); 95 RegisterMethods<SBType>(R); 96 RegisterMethods<SBTypeCategory>(R); 97 RegisterMethods<SBTypeEnumMember>(R); 98 RegisterMethods<SBTypeFilter>(R); 99 RegisterMethods<SBTypeFormat>(R); 100 RegisterMethods<SBTypeNameSpecifier>(R); 101 RegisterMethods<SBTypeSummary>(R); 102 RegisterMethods<SBTypeSummaryOptions>(R); 103 RegisterMethods<SBTypeSynthetic>(R); 104 RegisterMethods<SBUnixSignals>(R); 105 RegisterMethods<SBValue>(R); 106 RegisterMethods<SBValueList>(R); 107 RegisterMethods<SBVariablesOptions>(R); 108 RegisterMethods<SBWatchpoint>(R); 109 } 110 111 const char *SBReproducer::Capture() { 112 static std::string error; 113 if (auto e = Reproducer::Initialize(ReproducerMode::Capture, llvm::None)) { 114 error = llvm::toString(std::move(e)); 115 return error.c_str(); 116 } 117 118 if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 119 auto &p = g->GetOrCreate<SBProvider>(); 120 InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); 121 } 122 123 return nullptr; 124 } 125 126 const char *SBReproducer::Capture(const char *path) { 127 static std::string error; 128 if (auto e = 129 Reproducer::Initialize(ReproducerMode::Capture, FileSpec(path))) { 130 error = llvm::toString(std::move(e)); 131 return error.c_str(); 132 } 133 134 if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 135 auto &p = g->GetOrCreate<SBProvider>(); 136 InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); 137 } 138 139 return nullptr; 140 } 141 142 const char *SBReproducer::PassiveReplay(const char *path) { 143 static std::string error; 144 if (auto e = Reproducer::Initialize(ReproducerMode::PassiveReplay, 145 FileSpec(path))) { 146 error = llvm::toString(std::move(e)); 147 return error.c_str(); 148 } 149 150 if (auto *l = lldb_private::repro::Reproducer::Instance().GetLoader()) { 151 FileSpec file = l->GetFile<SBProvider::Info>(); 152 auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); 153 if (!error_or_file) { 154 error = 155 "unable to read SB API data: " + error_or_file.getError().message(); 156 return error.c_str(); 157 } 158 static ReplayData r(std::move(*error_or_file)); 159 InstrumentationData::Initialize(r.GetDeserializer(), r.GetRegistry()); 160 } 161 162 return nullptr; 163 } 164 165 const char *SBReproducer::Replay(const char *path) { 166 return SBReproducer::Replay(path, false); 167 } 168 169 const char *SBReproducer::Replay(const char *path, bool skip_version_check) { 170 static std::string error; 171 if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) { 172 error = llvm::toString(std::move(e)); 173 return error.c_str(); 174 } 175 176 repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); 177 if (!loader) { 178 error = "unable to get replay loader."; 179 return error.c_str(); 180 } 181 182 if (!skip_version_check) { 183 llvm::Expected<std::string> version = loader->LoadBuffer<VersionProvider>(); 184 if (!version) { 185 error = llvm::toString(version.takeError()); 186 return error.c_str(); 187 } 188 if (lldb_private::GetVersion() != llvm::StringRef(*version).rtrim()) { 189 error = "reproducer capture and replay version don't match:\n"; 190 error.append("reproducer captured with:\n"); 191 error.append(*version); 192 error.append("reproducer replayed with:\n"); 193 error.append(lldb_private::GetVersion()); 194 return error.c_str(); 195 } 196 } 197 198 FileSpec file = loader->GetFile<SBProvider::Info>(); 199 if (!file) { 200 error = "unable to get replay data from reproducer."; 201 return error.c_str(); 202 } 203 204 SBRegistry registry; 205 registry.Replay(file); 206 207 return nullptr; 208 } 209 210 bool SBReproducer::Generate() { 211 auto &r = Reproducer::Instance(); 212 if (auto generator = r.GetGenerator()) { 213 generator->Keep(); 214 return true; 215 } 216 return false; 217 } 218 219 bool SBReproducer::SetAutoGenerate(bool b) { 220 auto &r = Reproducer::Instance(); 221 if (auto generator = r.GetGenerator()) { 222 generator->SetAutoGenerate(b); 223 return true; 224 } 225 return false; 226 } 227 228 const char *SBReproducer::GetPath() { 229 static std::string path; 230 auto &r = Reproducer::Instance(); 231 path = r.GetReproducerPath().GetCString(); 232 return path.c_str(); 233 } 234 235 void SBReproducer::SetWorkingDirectory(const char *path) { 236 if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { 237 g->GetOrCreate<WorkingDirectoryProvider>().Update(path); 238 } 239 } 240 241 char lldb_private::repro::SBProvider::ID = 0; 242 const char *SBProvider::Info::name = "sbapi"; 243 const char *SBProvider::Info::file = "sbapi.bin"; 244