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