xref: /llvm-project/lldb/tools/lldb-test/lldb-test.cpp (revision 599ca7165edcf7d226bd658c450801044b46ce7c)
1 //===- lldb-test.cpp ------------------------------------------ *- C++ --*-===//
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 "FormatUtil.h"
10 #include "SystemInitializerTest.h"
11 
12 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
13 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
14 #include "lldb/Breakpoint/BreakpointLocation.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Expression/IRMemoryMap.h"
19 #include "lldb/Initialization/SystemLifetimeManager.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/CommandReturnObject.h"
22 #include "lldb/Symbol/CompileUnit.h"
23 #include "lldb/Symbol/LineTable.h"
24 #include "lldb/Symbol/SymbolFile.h"
25 #include "lldb/Symbol/Symtab.h"
26 #include "lldb/Symbol/TypeList.h"
27 #include "lldb/Symbol/TypeMap.h"
28 #include "lldb/Symbol/VariableList.h"
29 #include "lldb/Target/Language.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Utility/DataExtractor.h"
33 #include "lldb/Utility/LLDBAssert.h"
34 #include "lldb/Utility/State.h"
35 #include "lldb/Utility/StreamString.h"
36 
37 #include "llvm/ADT/IntervalMap.h"
38 #include "llvm/ADT/ScopeExit.h"
39 #include "llvm/ADT/StringRef.h"
40 #include "llvm/Support/CommandLine.h"
41 #include "llvm/Support/ManagedStatic.h"
42 #include "llvm/Support/MathExtras.h"
43 #include "llvm/Support/Path.h"
44 #include "llvm/Support/PrettyStackTrace.h"
45 #include "llvm/Support/Signals.h"
46 #include "llvm/Support/WithColor.h"
47 
48 #include <cstdio>
49 #include <optional>
50 #include <thread>
51 
52 using namespace lldb;
53 using namespace lldb_private;
54 using namespace llvm;
55 
56 namespace opts {
57 static cl::SubCommand BreakpointSubcommand("breakpoints",
58                                            "Test breakpoint resolution");
59 cl::SubCommand ObjectFileSubcommand("object-file",
60                                     "Display LLDB object file information");
61 cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
62 cl::SubCommand SymTabSubcommand("symtab",
63                                 "Test symbol table functionality");
64 cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
65 cl::SubCommand AssertSubcommand("assert", "Test assert handling");
66 
67 cl::opt<std::string> Log("log", cl::desc("Path to a log file"), cl::init(""),
68                          cl::sub(BreakpointSubcommand),
69                          cl::sub(ObjectFileSubcommand),
70                          cl::sub(SymbolsSubcommand),
71                          cl::sub(SymTabSubcommand),
72                          cl::sub(IRMemoryMapSubcommand));
73 
74 /// Create a target using the file pointed to by \p Filename, or abort.
75 TargetSP createTarget(Debugger &Dbg, const std::string &Filename);
76 
77 /// Read \p Filename into a null-terminated buffer, or abort.
78 std::unique_ptr<MemoryBuffer> openFile(const std::string &Filename);
79 
80 namespace breakpoint {
81 static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
82                                    cl::Required, cl::sub(BreakpointSubcommand));
83 static cl::opt<std::string> CommandFile(cl::Positional,
84                                         cl::desc("<command-file>"),
85                                         cl::init("-"),
86                                         cl::sub(BreakpointSubcommand));
87 static cl::opt<bool> Persistent(
88     "persistent",
89     cl::desc("Don't automatically remove all breakpoints before each command"),
90     cl::sub(BreakpointSubcommand));
91 
92 static llvm::StringRef plural(uintmax_t value) { return value == 1 ? "" : "s"; }
93 static void dumpState(const BreakpointList &List, LinePrinter &P);
94 static std::string substitute(StringRef Cmd);
95 static int evaluateBreakpoints(Debugger &Dbg);
96 } // namespace breakpoint
97 
98 namespace object {
99 cl::opt<bool> SectionContents("contents",
100                               cl::desc("Dump each section's contents"),
101                               cl::sub(ObjectFileSubcommand));
102 cl::opt<bool> SectionDependentModules("dep-modules",
103                                       cl::desc("Dump each dependent module"),
104                                       cl::sub(ObjectFileSubcommand));
105 cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
106                                      cl::OneOrMore,
107                                      cl::sub(ObjectFileSubcommand));
108 } // namespace object
109 
110 namespace symtab {
111 
112 /// The same enum as Mangled::NamePreference but with a default
113 /// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was
114 /// explicitly set or not.
115 enum class ManglingPreference {
116   None,
117   Mangled,
118   Demangled,
119   MangledWithoutArguments,
120 };
121 
122 static cl::opt<std::string> FindSymbolsByRegex(
123     "find-symbols-by-regex",
124     cl::desc(
125         "Dump symbols found in the symbol table matching the specified regex."),
126     cl::sub(SymTabSubcommand));
127 
128 static cl::opt<ManglingPreference> ManglingPreference(
129     "mangling-preference",
130     cl::desc("Preference on mangling scheme the regex should match against and "
131              "dumped."),
132     cl::values(
133         clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),
134         clEnumValN(ManglingPreference::Demangled, "demangled",
135                    "Prefer demangled"),
136         clEnumValN(ManglingPreference::MangledWithoutArguments,
137                    "demangled-without-args", "Prefer mangled without args")),
138     cl::sub(SymTabSubcommand));
139 
140 static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
141                                       cl::Required, cl::sub(SymTabSubcommand));
142 
143 /// Validate that the options passed make sense.
144 static std::optional<llvm::Error> validate();
145 
146 /// Transforms the selected mangling preference into a Mangled::NamePreference
147 static Mangled::NamePreference getNamePreference();
148 
149 static int handleSymtabCommand(Debugger &Dbg);
150 } // namespace symtab
151 
152 namespace symbols {
153 static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
154                                       cl::Required, cl::sub(SymbolsSubcommand));
155 
156 static cl::opt<std::string>
157     SymbolPath("symbol-file",
158                cl::desc("The file from which to fetch symbol information."),
159                cl::value_desc("file"), cl::sub(SymbolsSubcommand));
160 
161 enum class FindType {
162   None,
163   Function,
164   Block,
165   Namespace,
166   Type,
167   Variable,
168 };
169 static cl::opt<FindType> Find(
170     "find", cl::desc("Choose search type:"),
171     cl::values(
172         clEnumValN(FindType::None, "none", "No search, just dump the module."),
173         clEnumValN(FindType::Function, "function", "Find functions."),
174         clEnumValN(FindType::Block, "block", "Find blocks."),
175         clEnumValN(FindType::Namespace, "namespace", "Find namespaces."),
176         clEnumValN(FindType::Type, "type", "Find types."),
177         clEnumValN(FindType::Variable, "variable", "Find global variables.")),
178     cl::sub(SymbolsSubcommand));
179 
180 static cl::opt<std::string> Name("name", cl::desc("Name to find."),
181                                  cl::sub(SymbolsSubcommand));
182 static cl::opt<bool>
183     Regex("regex",
184           cl::desc("Search using regular expressions (available for variables "
185                    "and functions only)."),
186           cl::sub(SymbolsSubcommand));
187 static cl::opt<std::string>
188     Context("context",
189             cl::desc("Restrict search to the context of the given variable."),
190             cl::value_desc("variable"), cl::sub(SymbolsSubcommand));
191 
192 static cl::opt<std::string> CompilerContext(
193     "compiler-context",
194     cl::desc("Specify a compiler context as \"kind:name,...\"."),
195     cl::value_desc("context"), cl::sub(SymbolsSubcommand));
196 
197 static cl::opt<std::string>
198     Language("language", cl::desc("Specify a language type, like C99."),
199              cl::value_desc("language"), cl::sub(SymbolsSubcommand));
200 
201 static cl::list<FunctionNameType> FunctionNameFlags(
202     "function-flags", cl::desc("Function search flags:"),
203     cl::values(clEnumValN(eFunctionNameTypeAuto, "auto",
204                           "Automatically deduce flags based on name."),
205                clEnumValN(eFunctionNameTypeFull, "full", "Full function name."),
206                clEnumValN(eFunctionNameTypeBase, "base", "Base name."),
207                clEnumValN(eFunctionNameTypeMethod, "method", "Method name."),
208                clEnumValN(eFunctionNameTypeSelector, "selector",
209                           "Selector name.")),
210     cl::sub(SymbolsSubcommand));
211 static FunctionNameType getFunctionNameFlags() {
212   FunctionNameType Result = FunctionNameType(0);
213   for (FunctionNameType Flag : FunctionNameFlags)
214     Result = FunctionNameType(Result | Flag);
215   return Result;
216 }
217 
218 static cl::opt<bool> DumpAST("dump-ast",
219                              cl::desc("Dump AST restored from symbols."),
220                              cl::sub(SymbolsSubcommand));
221 static cl::opt<bool> DumpClangAST(
222     "dump-clang-ast",
223     cl::desc("Dump clang AST restored from symbols. When used on its own this "
224              "will dump the entire AST of all loaded symbols. When combined "
225              "with -find, it changes the presentation of the search results "
226              "from pretty-printing the types to an AST dump."),
227     cl::sub(SymbolsSubcommand));
228 
229 static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),
230                             cl::sub(SymbolsSubcommand));
231 
232 static cl::opt<std::string> File("file",
233                                  cl::desc("File (compile unit) to search."),
234                                  cl::sub(SymbolsSubcommand));
235 static cl::opt<int> Line("line", cl::desc("Line to search."),
236                          cl::sub(SymbolsSubcommand));
237 
238 static Expected<CompilerDeclContext> getDeclContext(SymbolFile &Symfile);
239 
240 static Error findFunctions(lldb_private::Module &Module);
241 static Error findBlocks(lldb_private::Module &Module);
242 static Error findNamespaces(lldb_private::Module &Module);
243 static Error findTypes(lldb_private::Module &Module);
244 static Error findVariables(lldb_private::Module &Module);
245 static Error dumpModule(lldb_private::Module &Module);
246 static Error dumpAST(lldb_private::Module &Module);
247 static Error dumpEntireClangAST(lldb_private::Module &Module);
248 static Error verify(lldb_private::Module &Module);
249 
250 static Expected<Error (*)(lldb_private::Module &)> getAction();
251 static int dumpSymbols(Debugger &Dbg);
252 } // namespace symbols
253 
254 namespace irmemorymap {
255 static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
256                                    cl::Required,
257                                    cl::sub(IRMemoryMapSubcommand));
258 static cl::opt<std::string> CommandFile(cl::Positional,
259                                         cl::desc("<command-file>"),
260                                         cl::init("-"),
261                                         cl::sub(IRMemoryMapSubcommand));
262 static cl::opt<bool> UseHostOnlyAllocationPolicy(
263     "host-only", cl::desc("Use the host-only allocation policy"),
264     cl::init(false), cl::sub(IRMemoryMapSubcommand));
265 
266 using AllocationT = std::pair<addr_t, addr_t>;
267 using AddrIntervalMap =
268     IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>;
269 
270 struct IRMemoryMapTestState {
271   TargetSP Target;
272   IRMemoryMap Map;
273 
274   AddrIntervalMap::Allocator IntervalMapAllocator;
275   AddrIntervalMap Allocations;
276 
277   StringMap<addr_t> Label2AddrMap;
278 
279   IRMemoryMapTestState(TargetSP Target)
280       : Target(Target), Map(Target), Allocations(IntervalMapAllocator) {}
281 };
282 
283 bool evalMalloc(StringRef Line, IRMemoryMapTestState &State);
284 bool evalFree(StringRef Line, IRMemoryMapTestState &State);
285 int evaluateMemoryMapCommands(Debugger &Dbg);
286 } // namespace irmemorymap
287 
288 namespace assert {
289 int lldb_assert(Debugger &Dbg);
290 } // namespace assert
291 } // namespace opts
292 
293 llvm::SmallVector<CompilerContext, 4> parseCompilerContext() {
294   llvm::SmallVector<CompilerContext, 4> result;
295   if (opts::symbols::CompilerContext.empty())
296     return result;
297 
298   StringRef str{opts::symbols::CompilerContext};
299   SmallVector<StringRef, 8> entries_str;
300   str.split(entries_str, ',', /*maxSplit*/-1, /*keepEmpty=*/false);
301   for (auto entry_str : entries_str) {
302     StringRef key, value;
303     std::tie(key, value) = entry_str.split(':');
304     auto kind =
305         StringSwitch<CompilerContextKind>(key)
306             .Case("TranslationUnit", CompilerContextKind::TranslationUnit)
307             .Case("Module", CompilerContextKind::Module)
308             .Case("Namespace", CompilerContextKind::Namespace)
309             .Case("ClassOrStruct", CompilerContextKind::ClassOrStruct)
310             .Case("Union", CompilerContextKind::Union)
311             .Case("Function", CompilerContextKind::Function)
312             .Case("Variable", CompilerContextKind::Variable)
313             .Case("Enum", CompilerContextKind::Enum)
314             .Case("Typedef", CompilerContextKind::Typedef)
315             .Case("AnyModule", CompilerContextKind::AnyModule)
316             .Case("AnyType", CompilerContextKind::AnyType)
317             .Default(CompilerContextKind::Invalid);
318     if (value.empty()) {
319       WithColor::error() << "compiler context entry has no \"name\"\n";
320       exit(1);
321     }
322     result.push_back({kind, ConstString{value}});
323   }
324   outs() << "Search context: {";
325   lldb_private::StreamString s;
326   llvm::interleaveComma(result, s, [&](auto &ctx) { ctx.Dump(s); });
327   outs() << s.GetString().str() << "}\n";
328 
329   return result;
330 }
331 
332 template <typename... Args>
333 static Error make_string_error(const char *Format, Args &&... args) {
334   return llvm::make_error<llvm::StringError>(
335       llvm::formatv(Format, std::forward<Args>(args)...).str(),
336       llvm::inconvertibleErrorCode());
337 }
338 
339 TargetSP opts::createTarget(Debugger &Dbg, const std::string &Filename) {
340   TargetSP Target;
341   Status ST = Dbg.GetTargetList().CreateTarget(
342       Dbg, Filename, /*triple*/ "", eLoadDependentsNo,
343       /*platform_options*/ nullptr, Target);
344   if (ST.Fail()) {
345     errs() << formatv("Failed to create target '{0}: {1}\n", Filename, ST);
346     exit(1);
347   }
348   return Target;
349 }
350 
351 std::unique_ptr<MemoryBuffer> opts::openFile(const std::string &Filename) {
352   auto MB = MemoryBuffer::getFileOrSTDIN(Filename);
353   if (!MB) {
354     errs() << formatv("Could not open file '{0}: {1}\n", Filename,
355                       MB.getError().message());
356     exit(1);
357   }
358   return std::move(*MB);
359 }
360 
361 void opts::breakpoint::dumpState(const BreakpointList &List, LinePrinter &P) {
362   P.formatLine("{0} breakpoint{1}", List.GetSize(), plural(List.GetSize()));
363   if (List.GetSize() > 0)
364     P.formatLine("At least one breakpoint.");
365   for (size_t i = 0, e = List.GetSize(); i < e; ++i) {
366     BreakpointSP BP = List.GetBreakpointAtIndex(i);
367     P.formatLine("Breakpoint ID {0}:", BP->GetID());
368     AutoIndent Indent(P, 2);
369     P.formatLine("{0} location{1}.", BP->GetNumLocations(),
370                  plural(BP->GetNumLocations()));
371     if (BP->GetNumLocations() > 0)
372       P.formatLine("At least one location.");
373     P.formatLine("{0} resolved location{1}.", BP->GetNumResolvedLocations(),
374                  plural(BP->GetNumResolvedLocations()));
375     if (BP->GetNumResolvedLocations() > 0)
376       P.formatLine("At least one resolved location.");
377     for (size_t l = 0, le = BP->GetNumLocations(); l < le; ++l) {
378       BreakpointLocationSP Loc = BP->GetLocationAtIndex(l);
379       P.formatLine("Location ID {0}:", Loc->GetID());
380       AutoIndent Indent(P, 2);
381       P.formatLine("Enabled: {0}", Loc->IsEnabled());
382       P.formatLine("Resolved: {0}", Loc->IsResolved());
383       SymbolContext sc;
384       Loc->GetAddress().CalculateSymbolContext(&sc);
385       lldb_private::StreamString S;
386       sc.DumpStopContext(&S, BP->GetTarget().GetProcessSP().get(),
387                          Loc->GetAddress(), false, true, false, true, true);
388       P.formatLine("Address: {0}", S.GetString());
389     }
390   }
391   P.NewLine();
392 }
393 
394 std::string opts::breakpoint::substitute(StringRef Cmd) {
395   std::string Result;
396   raw_string_ostream OS(Result);
397   while (!Cmd.empty()) {
398     switch (Cmd[0]) {
399     case '%':
400       if (Cmd.consume_front("%p") && (Cmd.empty() || !isalnum(Cmd[0]))) {
401         OS << sys::path::parent_path(breakpoint::CommandFile);
402         break;
403       }
404       [[fallthrough]];
405     default:
406       size_t pos = Cmd.find('%');
407       OS << Cmd.substr(0, pos);
408       Cmd = Cmd.substr(pos);
409       break;
410     }
411   }
412   return std::move(OS.str());
413 }
414 
415 int opts::breakpoint::evaluateBreakpoints(Debugger &Dbg) {
416   TargetSP Target = opts::createTarget(Dbg, breakpoint::Target);
417   std::unique_ptr<MemoryBuffer> MB = opts::openFile(breakpoint::CommandFile);
418 
419   LinePrinter P(4, outs());
420   StringRef Rest = MB->getBuffer();
421   int HadErrors = 0;
422   while (!Rest.empty()) {
423     StringRef Line;
424     std::tie(Line, Rest) = Rest.split('\n');
425     Line = Line.ltrim().rtrim();
426     if (Line.empty() || Line[0] == '#')
427       continue;
428 
429     if (!Persistent)
430       Target->RemoveAllBreakpoints(/*internal_also*/ true);
431 
432     std::string Command = substitute(Line);
433     P.formatLine("Command: {0}", Command);
434     CommandReturnObject Result(/*colors*/ false);
435     if (!Dbg.GetCommandInterpreter().HandleCommand(
436             Command.c_str(), /*add_to_history*/ eLazyBoolNo, Result)) {
437       P.formatLine("Failed: {0}", Result.GetErrorData());
438       HadErrors = 1;
439       continue;
440     }
441 
442     dumpState(Target->GetBreakpointList(/*internal*/ false), P);
443   }
444   return HadErrors;
445 }
446 
447 Expected<CompilerDeclContext>
448 opts::symbols::getDeclContext(SymbolFile &Symfile) {
449   if (Context.empty())
450     return CompilerDeclContext();
451   VariableList List;
452   Symfile.FindGlobalVariables(ConstString(Context), CompilerDeclContext(),
453                               UINT32_MAX, List);
454   if (List.Empty())
455     return make_string_error("Context search didn't find a match.");
456   if (List.GetSize() > 1)
457     return make_string_error("Context search found multiple matches.");
458   return List.GetVariableAtIndex(0)->GetDeclContext();
459 }
460 
461 static lldb::DescriptionLevel GetDescriptionLevel() {
462   return opts::symbols::DumpClangAST ? eDescriptionLevelVerbose : eDescriptionLevelFull;
463 }
464 
465 Error opts::symbols::findFunctions(lldb_private::Module &Module) {
466   SymbolFile &Symfile = *Module.GetSymbolFile();
467   SymbolContextList List;
468   auto compiler_context = parseCompilerContext();
469   if (!File.empty()) {
470     assert(Line != 0);
471 
472     FileSpec src_file(File);
473     size_t cu_count = Module.GetNumCompileUnits();
474     for (size_t i = 0; i < cu_count; i++) {
475       lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
476       if (!cu_sp)
477         continue;
478 
479       LineEntry le;
480       cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
481       if (!le.IsValid())
482         continue;
483       const bool include_inlined_functions = false;
484       auto addr =
485           le.GetSameLineContiguousAddressRange(include_inlined_functions)
486               .GetBaseAddress();
487       if (!addr.IsValid())
488         continue;
489 
490       SymbolContext sc;
491       uint32_t resolved =
492           addr.CalculateSymbolContext(&sc, eSymbolContextFunction);
493       if (resolved & eSymbolContextFunction)
494         List.Append(sc);
495     }
496   } else if (Regex) {
497     RegularExpression RE(Name);
498     assert(RE.IsValid());
499     List.Clear();
500     Symfile.FindFunctions(RE, true, List);
501   } else if (!compiler_context.empty()) {
502     List.Clear();
503     Module.FindFunctions(compiler_context, getFunctionNameFlags(), {}, List);
504   } else {
505     Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
506     if (!ContextOr)
507       return ContextOr.takeError();
508     const CompilerDeclContext &ContextPtr =
509         ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
510 
511     List.Clear();
512     Module::LookupInfo lookup_info(ConstString(Name), getFunctionNameFlags(),
513                                    eLanguageTypeUnknown);
514     Symfile.FindFunctions(lookup_info, ContextPtr, true, List);
515   }
516   outs() << formatv("Found {0} functions:\n", List.GetSize());
517   StreamString Stream;
518   List.Dump(&Stream, nullptr);
519   outs() << Stream.GetData() << "\n";
520   return Error::success();
521 }
522 
523 Error opts::symbols::findBlocks(lldb_private::Module &Module) {
524   assert(!Regex);
525   assert(!File.empty());
526   assert(Line != 0);
527 
528   SymbolContextList List;
529 
530   FileSpec src_file(File);
531   size_t cu_count = Module.GetNumCompileUnits();
532   for (size_t i = 0; i < cu_count; i++) {
533     lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
534     if (!cu_sp)
535       continue;
536 
537     LineEntry le;
538     cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
539     if (!le.IsValid())
540       continue;
541     const bool include_inlined_functions = false;
542     auto addr = le.GetSameLineContiguousAddressRange(include_inlined_functions)
543                     .GetBaseAddress();
544     if (!addr.IsValid())
545       continue;
546 
547     SymbolContext sc;
548     uint32_t resolved = addr.CalculateSymbolContext(&sc, eSymbolContextBlock);
549     if (resolved & eSymbolContextBlock)
550       List.Append(sc);
551   }
552 
553   outs() << formatv("Found {0} blocks:\n", List.GetSize());
554   StreamString Stream;
555   List.Dump(&Stream, nullptr);
556   outs() << Stream.GetData() << "\n";
557   return Error::success();
558 }
559 
560 Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
561   SymbolFile &Symfile = *Module.GetSymbolFile();
562   Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
563   if (!ContextOr)
564     return ContextOr.takeError();
565   const CompilerDeclContext &ContextPtr =
566       ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
567 
568   CompilerDeclContext Result =
569       Symfile.FindNamespace(ConstString(Name), ContextPtr);
570   if (Result)
571     outs() << "Found namespace: "
572            << Result.GetScopeQualifiedName().GetStringRef() << "\n";
573   else
574     outs() << "Namespace not found.\n";
575   return Error::success();
576 }
577 
578 Error opts::symbols::findTypes(lldb_private::Module &Module) {
579   SymbolFile &Symfile = *Module.GetSymbolFile();
580   Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
581   if (!ContextOr)
582     return ContextOr.takeError();
583 
584   TypeResults results;
585   if (!Name.empty()) {
586     if (ContextOr->IsValid()) {
587       TypeQuery query(*ContextOr, ConstString(Name),
588                       TypeQueryOptions::e_module_search);
589       if (!Language.empty())
590         query.AddLanguage(Language::GetLanguageTypeFromString(Language));
591       Symfile.FindTypes(query, results);
592     } else {
593       TypeQuery query(Name);
594       if (!Language.empty())
595         query.AddLanguage(Language::GetLanguageTypeFromString(Language));
596       Symfile.FindTypes(query, results);
597     }
598   } else {
599     TypeQuery query(parseCompilerContext(), TypeQueryOptions::e_module_search);
600     if (!Language.empty())
601       query.AddLanguage(Language::GetLanguageTypeFromString(Language));
602     Symfile.FindTypes(query, results);
603   }
604   outs() << formatv("Found {0} types:\n", results.GetTypeMap().GetSize());
605   StreamString Stream;
606   // Resolve types to force-materialize typedef types.
607   for (const auto &type_sp : results.GetTypeMap().Types())
608     type_sp->GetFullCompilerType();
609   results.GetTypeMap().Dump(&Stream, false, GetDescriptionLevel());
610   outs() << Stream.GetData() << "\n";
611   return Error::success();
612 }
613 
614 Error opts::symbols::findVariables(lldb_private::Module &Module) {
615   SymbolFile &Symfile = *Module.GetSymbolFile();
616   VariableList List;
617   if (Regex) {
618     RegularExpression RE(Name);
619     assert(RE.IsValid());
620     Symfile.FindGlobalVariables(RE, UINT32_MAX, List);
621   } else if (!File.empty()) {
622     CompUnitSP CU;
623     for (size_t Ind = 0; !CU && Ind < Module.GetNumCompileUnits(); ++Ind) {
624       CompUnitSP Candidate = Module.GetCompileUnitAtIndex(Ind);
625       if (!Candidate ||
626           Candidate->GetPrimaryFile().GetFilename().GetStringRef() != File)
627         continue;
628       if (CU)
629         return make_string_error("Multiple compile units for file `{0}` found.",
630                                  File);
631       CU = std::move(Candidate);
632     }
633 
634     if (!CU)
635       return make_string_error("Compile unit `{0}` not found.", File);
636 
637     List.AddVariables(CU->GetVariableList(true).get());
638   } else {
639     Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
640     if (!ContextOr)
641       return ContextOr.takeError();
642     const CompilerDeclContext &ContextPtr =
643         ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
644 
645     Symfile.FindGlobalVariables(ConstString(Name), ContextPtr, UINT32_MAX, List);
646   }
647   outs() << formatv("Found {0} variables:\n", List.GetSize());
648   StreamString Stream;
649   List.Dump(&Stream, false);
650   outs() << Stream.GetData() << "\n";
651   return Error::success();
652 }
653 
654 Error opts::symbols::dumpModule(lldb_private::Module &Module) {
655   StreamString Stream;
656   Module.ParseAllDebugSymbols();
657   Module.Dump(&Stream);
658   outs() << Stream.GetData() << "\n";
659   return Error::success();
660 }
661 
662 Error opts::symbols::dumpAST(lldb_private::Module &Module) {
663   Module.ParseAllDebugSymbols();
664 
665   SymbolFile *symfile = Module.GetSymbolFile();
666   if (!symfile)
667     return make_string_error("Module has no symbol file.");
668 
669   auto type_system_or_err =
670       symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
671   if (!type_system_or_err)
672     return make_string_error("Can't retrieve TypeSystemClang");
673 
674   auto ts = *type_system_or_err;
675   auto *clang_ast_ctx = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
676   if (!clang_ast_ctx)
677     return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");
678 
679   clang::ASTContext &ast_ctx = clang_ast_ctx->getASTContext();
680 
681   clang::TranslationUnitDecl *tu = ast_ctx.getTranslationUnitDecl();
682   if (!tu)
683     return make_string_error("Can't retrieve translation unit declaration.");
684 
685   tu->print(outs());
686 
687   return Error::success();
688 }
689 
690 Error opts::symbols::dumpEntireClangAST(lldb_private::Module &Module) {
691   Module.ParseAllDebugSymbols();
692 
693   SymbolFile *symfile = Module.GetSymbolFile();
694   if (!symfile)
695     return make_string_error("Module has no symbol file.");
696 
697   auto type_system_or_err =
698       symfile->GetTypeSystemForLanguage(eLanguageTypeObjC_plus_plus);
699   if (!type_system_or_err)
700     return make_string_error("Can't retrieve TypeSystemClang");
701   auto ts = *type_system_or_err;
702   auto *clang_ast_ctx = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
703   if (!clang_ast_ctx)
704     return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");
705 
706   StreamString Stream;
707   clang_ast_ctx->DumpFromSymbolFile(Stream, Name);
708   outs() << Stream.GetData() << "\n";
709 
710   return Error::success();
711 }
712 
713 Error opts::symbols::verify(lldb_private::Module &Module) {
714   SymbolFile *symfile = Module.GetSymbolFile();
715   if (!symfile)
716     return make_string_error("Module has no symbol file.");
717 
718   uint32_t comp_units_count = symfile->GetNumCompileUnits();
719 
720   outs() << "Found " << comp_units_count << " compile units.\n";
721 
722   for (uint32_t i = 0; i < comp_units_count; i++) {
723     lldb::CompUnitSP comp_unit = symfile->GetCompileUnitAtIndex(i);
724     if (!comp_unit)
725       return make_string_error("Cannot parse compile unit {0}.", i);
726 
727     outs() << "Processing '"
728            << comp_unit->GetPrimaryFile().GetFilename().AsCString()
729            << "' compile unit.\n";
730 
731     LineTable *lt = comp_unit->GetLineTable();
732     if (!lt)
733       return make_string_error("Can't get a line table of a compile unit.");
734 
735     uint32_t count = lt->GetSize();
736 
737     outs() << "The line table contains " << count << " entries.\n";
738 
739     if (count == 0)
740       continue;
741 
742     LineEntry le;
743     if (!lt->GetLineEntryAtIndex(0, le))
744       return make_string_error("Can't get a line entry of a compile unit.");
745 
746     for (uint32_t i = 1; i < count; i++) {
747       lldb::addr_t curr_end =
748           le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();
749 
750       if (!lt->GetLineEntryAtIndex(i, le))
751         return make_string_error("Can't get a line entry of a compile unit");
752 
753       if (curr_end > le.range.GetBaseAddress().GetFileAddress())
754         return make_string_error(
755             "Line table of a compile unit is inconsistent.");
756     }
757   }
758 
759   outs() << "The symbol information is verified.\n";
760 
761   return Error::success();
762 }
763 
764 Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
765   if (Verify && DumpAST)
766     return make_string_error(
767         "Cannot both verify symbol information and dump AST.");
768 
769   if (Verify) {
770     if (Find != FindType::None)
771       return make_string_error(
772           "Cannot both search and verify symbol information.");
773     if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
774         Line != 0)
775       return make_string_error(
776           "-regex, -context, -name, -file and -line options are not "
777           "applicable for symbol verification.");
778     return verify;
779   }
780 
781   if (DumpAST) {
782     if (Find != FindType::None)
783       return make_string_error("Cannot both search and dump AST.");
784     if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
785         Line != 0)
786       return make_string_error(
787           "-regex, -context, -name, -file and -line options are not "
788           "applicable for dumping AST.");
789     return dumpAST;
790   }
791 
792   if (DumpClangAST) {
793     if (Find == FindType::None) {
794       if (Regex || !Context.empty() || !File.empty() || Line != 0)
795         return make_string_error(
796             "-regex, -context, -name, -file and -line options are not "
797             "applicable for dumping the entire clang AST. Either combine with "
798             "-find, or use -dump-clang-ast as a standalone option.");
799       return dumpEntireClangAST;
800     }
801     if (Find != FindType::Type)
802       return make_string_error("This combination of -dump-clang-ast and -find "
803                                "<kind> is not yet implemented.");
804   }
805 
806   if (Regex && !Context.empty())
807     return make_string_error(
808         "Cannot search using both regular expressions and context.");
809 
810   if (Regex && !RegularExpression(Name).IsValid())
811     return make_string_error("`{0}` is not a valid regular expression.", Name);
812 
813   if (Regex + !Context.empty() + !File.empty() >= 2)
814     return make_string_error(
815         "Only one of -regex, -context and -file may be used simultaneously.");
816   if (Regex && Name.empty())
817     return make_string_error("-regex used without a -name");
818 
819   switch (Find) {
820   case FindType::None:
821     if (!Context.empty() || !Name.empty() || !File.empty() || Line != 0)
822       return make_string_error(
823           "Specify search type (-find) to use search options.");
824     return dumpModule;
825 
826   case FindType::Function:
827     if (!File.empty() + (Line != 0) == 1)
828       return make_string_error("Both file name and line number must be "
829                                "specified when searching a function "
830                                "by file position.");
831     if (Regex + (getFunctionNameFlags() != 0) + !File.empty() >= 2)
832       return make_string_error("Only one of regular expression, function-flags "
833                                "and file position may be used simultaneously "
834                                "when searching a function.");
835     return findFunctions;
836 
837   case FindType::Block:
838     if (File.empty() || Line == 0)
839       return make_string_error("Both file name and line number must be "
840                                "specified when searching a block.");
841     if (Regex || getFunctionNameFlags() != 0)
842       return make_string_error("Cannot use regular expression or "
843                                "function-flags for searching a block.");
844     return findBlocks;
845 
846   case FindType::Namespace:
847     if (Regex || !File.empty() || Line != 0)
848       return make_string_error("Cannot search for namespaces using regular "
849                                "expressions, file names or line numbers.");
850     return findNamespaces;
851 
852   case FindType::Type:
853     if (Regex || !File.empty() || Line != 0)
854       return make_string_error("Cannot search for types using regular "
855                                "expressions, file names or line numbers.");
856     if (!Name.empty() && !CompilerContext.empty())
857       return make_string_error("Name is ignored if compiler context present.");
858 
859     return findTypes;
860 
861   case FindType::Variable:
862     if (Line != 0)
863       return make_string_error("Cannot search for variables "
864                                "using line numbers.");
865     return findVariables;
866   }
867 
868   llvm_unreachable("Unsupported symbol action.");
869 }
870 
871 std::optional<llvm::Error> opts::symtab::validate() {
872   if (ManglingPreference != ManglingPreference::None &&
873       FindSymbolsByRegex.empty())
874     return make_string_error("Mangling preference set but no regex specified.");
875 
876   return {};
877 }
878 
879 static Mangled::NamePreference opts::symtab::getNamePreference() {
880   switch (ManglingPreference) {
881   case ManglingPreference::None:
882   case ManglingPreference::Mangled:
883     return Mangled::ePreferMangled;
884   case ManglingPreference::Demangled:
885     return Mangled::ePreferDemangled;
886   case ManglingPreference::MangledWithoutArguments:
887     return Mangled::ePreferDemangledWithoutArguments;
888   }
889   llvm_unreachable("Fully covered switch above!");
890 }
891 
892 int opts::symtab::handleSymtabCommand(Debugger &Dbg) {
893   if (auto error = validate()) {
894     logAllUnhandledErrors(std::move(*error), WithColor::error(), "");
895     return 1;
896   }
897 
898   if (!FindSymbolsByRegex.empty()) {
899     ModuleSpec Spec{FileSpec(InputFile)};
900 
901     auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
902     auto *Symtab = ModulePtr->GetSymtab();
903     auto NamePreference = getNamePreference();
904     std::vector<uint32_t> Indexes;
905 
906     Symtab->FindAllSymbolsMatchingRexExAndType(
907         RegularExpression(FindSymbolsByRegex), lldb::eSymbolTypeAny,
908         Symtab::eDebugAny, Symtab::eVisibilityAny, Indexes, NamePreference);
909     for (auto i : Indexes) {
910       auto *symbol = Symtab->SymbolAtIndex(i);
911       if (symbol) {
912         StreamString stream;
913         symbol->Dump(&stream, nullptr, i, NamePreference);
914         outs() << stream.GetString();
915       }
916     }
917   }
918 
919   return 0;
920 }
921 
922 int opts::symbols::dumpSymbols(Debugger &Dbg) {
923   auto ActionOr = getAction();
924   if (!ActionOr) {
925     logAllUnhandledErrors(ActionOr.takeError(), WithColor::error(), "");
926     return 1;
927   }
928   auto Action = *ActionOr;
929 
930   outs() << "Module: " << InputFile << "\n";
931   ModuleSpec Spec{FileSpec(InputFile)};
932   StringRef Symbols = SymbolPath.empty() ? InputFile : SymbolPath;
933   Spec.GetSymbolFileSpec().SetFile(Symbols, FileSpec::Style::native);
934 
935   auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
936   SymbolFile *Symfile = ModulePtr->GetSymbolFile();
937   if (!Symfile) {
938     WithColor::error() << "Module has no symbol vendor.\n";
939     return 1;
940   }
941 
942   if (Error E = Action(*ModulePtr)) {
943     WithColor::error() << toString(std::move(E)) << "\n";
944     return 1;
945   }
946 
947   return 0;
948 }
949 
950 static void dumpSectionList(LinePrinter &Printer, const SectionList &List, bool is_subsection) {
951   size_t Count = List.GetNumSections(0);
952   if (Count == 0) {
953     Printer.formatLine("There are no {0}sections", is_subsection ? "sub" : "");
954     return;
955   }
956   Printer.formatLine("Showing {0} {1}sections", Count,
957                      is_subsection ? "sub" : "");
958   for (size_t I = 0; I < Count; ++I) {
959     auto S = List.GetSectionAtIndex(I);
960     assert(S);
961     AutoIndent Indent(Printer, 2);
962     Printer.formatLine("Index: {0}", I);
963     Printer.formatLine("ID: {0:x}", S->GetID());
964     Printer.formatLine("Name: {0}", S->GetName().GetStringRef());
965     Printer.formatLine("Type: {0}", S->GetTypeAsCString());
966     Printer.formatLine("Permissions: {0}", GetPermissionsAsCString(S->GetPermissions()));
967     Printer.formatLine("Thread specific: {0:y}", S->IsThreadSpecific());
968     Printer.formatLine("VM address: {0:x}", S->GetFileAddress());
969     Printer.formatLine("VM size: {0}", S->GetByteSize());
970     Printer.formatLine("File size: {0}", S->GetFileSize());
971 
972     if (opts::object::SectionContents) {
973       lldb_private::DataExtractor Data;
974       S->GetSectionData(Data);
975       ArrayRef<uint8_t> Bytes(Data.GetDataStart(), Data.GetDataEnd());
976       Printer.formatBinary("Data: ", Bytes, 0);
977     }
978 
979     if (S->GetType() == eSectionTypeContainer)
980       dumpSectionList(Printer, S->GetChildren(), true);
981     Printer.NewLine();
982   }
983 }
984 
985 static int dumpObjectFiles(Debugger &Dbg) {
986   LinePrinter Printer(4, llvm::outs());
987 
988   int HadErrors = 0;
989   for (const auto &File : opts::object::InputFilenames) {
990     ModuleSpec Spec{FileSpec(File)};
991 
992     auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
993 
994     ObjectFile *ObjectPtr = ModulePtr->GetObjectFile();
995     if (!ObjectPtr) {
996       WithColor::error() << File << " not recognised as an object file\n";
997       HadErrors = 1;
998       continue;
999     }
1000 
1001     // Fetch symbol vendor before we get the section list to give the symbol
1002     // vendor a chance to populate it.
1003     ModulePtr->GetSymbolFile();
1004     SectionList *Sections = ModulePtr->GetSectionList();
1005     if (!Sections) {
1006       llvm::errs() << "Could not load sections for module " << File << "\n";
1007       HadErrors = 1;
1008       continue;
1009     }
1010 
1011     Printer.formatLine("Plugin name: {0}", ObjectPtr->GetPluginName());
1012     Printer.formatLine("Architecture: {0}",
1013                        ModulePtr->GetArchitecture().GetTriple().getTriple());
1014     Printer.formatLine("UUID: {0}", ModulePtr->GetUUID().GetAsString());
1015     Printer.formatLine("Executable: {0}", ObjectPtr->IsExecutable());
1016     Printer.formatLine("Stripped: {0}", ObjectPtr->IsStripped());
1017     Printer.formatLine("Type: {0}", ObjectPtr->GetType());
1018     Printer.formatLine("Strata: {0}", ObjectPtr->GetStrata());
1019     Printer.formatLine("Base VM address: {0:x}",
1020                        ObjectPtr->GetBaseAddress().GetFileAddress());
1021 
1022     dumpSectionList(Printer, *Sections, /*is_subsection*/ false);
1023 
1024     if (opts::object::SectionDependentModules) {
1025       // A non-empty section list ensures a valid object file.
1026       auto Obj = ModulePtr->GetObjectFile();
1027       FileSpecList Files;
1028       auto Count = Obj->GetDependentModules(Files);
1029       Printer.formatLine("Showing {0} dependent module(s)", Count);
1030       for (size_t I = 0; I < Files.GetSize(); ++I) {
1031         AutoIndent Indent(Printer, 2);
1032         Printer.formatLine("Name: {0}",
1033                            Files.GetFileSpecAtIndex(I).GetPath());
1034       }
1035       Printer.NewLine();
1036     }
1037   }
1038   return HadErrors;
1039 }
1040 
1041 bool opts::irmemorymap::evalMalloc(StringRef Line,
1042                                    IRMemoryMapTestState &State) {
1043   // ::= <label> = malloc <size> <alignment>
1044   StringRef Label;
1045   std::tie(Label, Line) = Line.split('=');
1046   if (Line.empty())
1047     return false;
1048   Label = Label.trim();
1049   Line = Line.trim();
1050   size_t Size;
1051   uint8_t Alignment;
1052   int Matches = sscanf(Line.data(), "malloc %zu %hhu", &Size, &Alignment);
1053   if (Matches != 2)
1054     return false;
1055 
1056   outs() << formatv("Command: {0} = malloc(size={1}, alignment={2})\n", Label,
1057                     Size, Alignment);
1058   if (!isPowerOf2_32(Alignment)) {
1059     outs() << "Malloc error: alignment is not a power of 2\n";
1060     exit(1);
1061   }
1062 
1063   IRMemoryMap::AllocationPolicy AP =
1064       UseHostOnlyAllocationPolicy ? IRMemoryMap::eAllocationPolicyHostOnly
1065                                   : IRMemoryMap::eAllocationPolicyProcessOnly;
1066 
1067   // Issue the malloc in the target process with "-rw" permissions.
1068   const uint32_t Permissions = 0x3;
1069   const bool ZeroMemory = false;
1070   Status ST;
1071   addr_t Addr =
1072       State.Map.Malloc(Size, Alignment, Permissions, AP, ZeroMemory, ST);
1073   if (ST.Fail()) {
1074     outs() << formatv("Malloc error: {0}\n", ST);
1075     return true;
1076   }
1077 
1078   // Print the result of the allocation before checking its validity.
1079   outs() << formatv("Malloc: address = {0:x}\n", Addr);
1080 
1081   // Check that the allocation is aligned.
1082   if (!Addr || Addr % Alignment != 0) {
1083     outs() << "Malloc error: zero or unaligned allocation detected\n";
1084     exit(1);
1085   }
1086 
1087   // In case of Size == 0, we still expect the returned address to be unique and
1088   // non-overlapping.
1089   addr_t EndOfRegion = Addr + std::max<size_t>(Size, 1);
1090   if (State.Allocations.overlaps(Addr, EndOfRegion)) {
1091     auto I = State.Allocations.find(Addr);
1092     outs() << "Malloc error: overlapping allocation detected"
1093            << formatv(", previous allocation at [{0:x}, {1:x})\n", I.start(),
1094                       I.stop());
1095     exit(1);
1096   }
1097 
1098   // Insert the new allocation into the interval map. Use unique allocation
1099   // IDs to inhibit interval coalescing.
1100   static unsigned AllocationID = 0;
1101   State.Allocations.insert(Addr, EndOfRegion, AllocationID++);
1102 
1103   // Store the label -> address mapping.
1104   State.Label2AddrMap[Label] = Addr;
1105 
1106   return true;
1107 }
1108 
1109 bool opts::irmemorymap::evalFree(StringRef Line, IRMemoryMapTestState &State) {
1110   // ::= free <label>
1111   if (!Line.consume_front("free"))
1112     return false;
1113   StringRef Label = Line.trim();
1114 
1115   outs() << formatv("Command: free({0})\n", Label);
1116   auto LabelIt = State.Label2AddrMap.find(Label);
1117   if (LabelIt == State.Label2AddrMap.end()) {
1118     outs() << "Free error: Invalid allocation label\n";
1119     exit(1);
1120   }
1121 
1122   Status ST;
1123   addr_t Addr = LabelIt->getValue();
1124   State.Map.Free(Addr, ST);
1125   if (ST.Fail()) {
1126     outs() << formatv("Free error: {0}\n", ST);
1127     exit(1);
1128   }
1129 
1130   // Erase the allocation from the live interval map.
1131   auto Interval = State.Allocations.find(Addr);
1132   if (Interval != State.Allocations.end()) {
1133     outs() << formatv("Free: [{0:x}, {1:x})\n", Interval.start(),
1134                       Interval.stop());
1135     Interval.erase();
1136   }
1137 
1138   return true;
1139 }
1140 
1141 int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) {
1142   // Set up a Target.
1143   TargetSP Target = opts::createTarget(Dbg, irmemorymap::Target);
1144 
1145   // Set up a Process. In order to allocate memory within a target, this
1146   // process must be alive and must support JIT'ing.
1147   CommandReturnObject Result(/*colors*/ false);
1148   Dbg.SetAsyncExecution(false);
1149   CommandInterpreter &CI = Dbg.GetCommandInterpreter();
1150   auto IssueCmd = [&](const char *Cmd) -> bool {
1151     return CI.HandleCommand(Cmd, eLazyBoolNo, Result);
1152   };
1153   if (!IssueCmd("b main") || !IssueCmd("run")) {
1154     outs() << formatv("Failed: {0}\n", Result.GetErrorData());
1155     exit(1);
1156   }
1157 
1158   ProcessSP Process = Target->GetProcessSP();
1159   if (!Process || !Process->IsAlive() || !Process->CanJIT()) {
1160     outs() << "Cannot use process to test IRMemoryMap\n";
1161     exit(1);
1162   }
1163 
1164   // Set up an IRMemoryMap and associated testing state.
1165   IRMemoryMapTestState State(Target);
1166 
1167   // Parse and apply commands from the command file.
1168   std::unique_ptr<MemoryBuffer> MB = opts::openFile(irmemorymap::CommandFile);
1169   StringRef Rest = MB->getBuffer();
1170   while (!Rest.empty()) {
1171     StringRef Line;
1172     std::tie(Line, Rest) = Rest.split('\n');
1173     Line = Line.ltrim().rtrim();
1174 
1175     if (Line.empty() || Line[0] == '#')
1176       continue;
1177 
1178     if (evalMalloc(Line, State))
1179       continue;
1180 
1181     if (evalFree(Line, State))
1182       continue;
1183 
1184     errs() << "Could not parse line: " << Line << "\n";
1185     exit(1);
1186   }
1187   return 0;
1188 }
1189 
1190 int opts::assert::lldb_assert(Debugger &Dbg) {
1191   lldbassert(false && "lldb-test assert");
1192   return 1;
1193 }
1194 
1195 int main(int argc, const char *argv[]) {
1196   StringRef ToolName = argv[0];
1197   sys::PrintStackTraceOnErrorSignal(ToolName);
1198   PrettyStackTraceProgram X(argc, argv);
1199   llvm_shutdown_obj Y;
1200 
1201   cl::ParseCommandLineOptions(argc, argv, "LLDB Testing Utility\n");
1202 
1203   SystemLifetimeManager DebuggerLifetime;
1204   if (auto e = DebuggerLifetime.Initialize(
1205           std::make_unique<SystemInitializerTest>(), nullptr)) {
1206     WithColor::error() << "initialization failed: " << toString(std::move(e))
1207                        << '\n';
1208     return 1;
1209   }
1210 
1211   auto TerminateDebugger =
1212       llvm::make_scope_exit([&] { DebuggerLifetime.Terminate(); });
1213 
1214   auto Dbg = lldb_private::Debugger::CreateInstance();
1215   ModuleList::GetGlobalModuleListProperties().SetEnableExternalLookup(false);
1216   CommandReturnObject Result(/*colors*/ false);
1217   Dbg->GetCommandInterpreter().HandleCommand(
1218       "settings set plugin.process.gdb-remote.packet-timeout 60",
1219       /*add_to_history*/ eLazyBoolNo, Result);
1220   Dbg->GetCommandInterpreter().HandleCommand(
1221       "settings set target.inherit-tcc true",
1222       /*add_to_history*/ eLazyBoolNo, Result);
1223   Dbg->GetCommandInterpreter().HandleCommand(
1224       "settings set target.detach-on-error false",
1225       /*add_to_history*/ eLazyBoolNo, Result);
1226 
1227   if (!opts::Log.empty())
1228     Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, 0, eLogHandlerStream, errs());
1229 
1230   if (opts::BreakpointSubcommand)
1231     return opts::breakpoint::evaluateBreakpoints(*Dbg);
1232   if (opts::ObjectFileSubcommand)
1233     return dumpObjectFiles(*Dbg);
1234   if (opts::SymbolsSubcommand)
1235     return opts::symbols::dumpSymbols(*Dbg);
1236   if (opts::SymTabSubcommand)
1237     return opts::symtab::handleSymtabCommand(*Dbg);
1238   if (opts::IRMemoryMapSubcommand)
1239     return opts::irmemorymap::evaluateMemoryMapCommands(*Dbg);
1240   if (opts::AssertSubcommand)
1241     return opts::assert::lldb_assert(*Dbg);
1242 
1243   WithColor::error() << "No command specified.\n";
1244   return 1;
1245 }
1246