LLDB mainline
CommandObjectTarget.cpp
Go to the documentation of this file.
1//===-- CommandObjectTarget.cpp -------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "lldb/Core/Address.h"
12#include "lldb/Core/Debugger.h"
13#include "lldb/Core/IOHandler.h"
14#include "lldb/Core/Module.h"
17#include "lldb/Core/Section.h"
43#include "lldb/Target/ABI.h"
44#include "lldb/Target/Process.h"
48#include "lldb/Target/Thread.h"
50#include "lldb/Utility/Args.h"
55#include "lldb/Utility/State.h"
56#include "lldb/Utility/Stream.h"
58#include "lldb/Utility/Timer.h"
61#include "lldb/lldb-forward.h"
63
64#include "clang/Driver/CreateInvocationFromArgs.h"
65#include "clang/Frontend/CompilerInstance.h"
66#include "clang/Frontend/CompilerInvocation.h"
67#include "clang/Frontend/FrontendActions.h"
68#include "clang/Serialization/ObjectFilePCHContainerReader.h"
69#include "llvm/ADT/ScopeExit.h"
70#include "llvm/ADT/StringRef.h"
71#include "llvm/Support/FileSystem.h"
72#include "llvm/Support/FormatAdapters.h"
73
74
75using namespace lldb;
76using namespace lldb_private;
77
78static void DumpTargetInfo(uint32_t target_idx, Target *target,
79 const char *prefix_cstr,
80 bool show_stopped_process_status, Stream &strm) {
81 const ArchSpec &target_arch = target->GetArchitecture();
82
83 Module *exe_module = target->GetExecutableModulePointer();
84 char exe_path[PATH_MAX];
85 bool exe_valid = false;
86 if (exe_module)
87 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
88
89 if (!exe_valid)
90 ::strcpy(exe_path, "<none>");
91
92 std::string formatted_label = "";
93 const std::string &label = target->GetLabel();
94 if (!label.empty()) {
95 formatted_label = " (" + label + ")";
96 }
97
98 strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,
99 formatted_label.data(), exe_path);
100
101 uint32_t properties = 0;
102 if (target_arch.IsValid()) {
103 strm.Printf(" ( arch=");
104 target_arch.DumpTriple(strm.AsRawOstream());
105 properties++;
106 }
107 PlatformSP platform_sp(target->GetPlatform());
108 if (platform_sp)
109 strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
110 platform_sp->GetName());
111
112 ProcessSP process_sp(target->GetProcessSP());
113 bool show_process_status = false;
114 if (process_sp) {
115 lldb::pid_t pid = process_sp->GetID();
116 StateType state = process_sp->GetState();
117 if (show_stopped_process_status)
118 show_process_status = StateIsStoppedState(state, true);
119 const char *state_cstr = StateAsCString(state);
120 if (pid != LLDB_INVALID_PROCESS_ID)
121 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
122 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
123 }
124 if (properties > 0)
125 strm.PutCString(" )\n");
126 else
127 strm.EOL();
128 if (show_process_status) {
129 const bool only_threads_with_stop_reason = true;
130 const uint32_t start_frame = 0;
131 const uint32_t num_frames = 1;
132 const uint32_t num_frames_with_source = 1;
133 const bool stop_format = false;
134 process_sp->GetStatus(strm);
135 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
136 start_frame, num_frames, num_frames_with_source,
137 stop_format);
138 }
139}
140
141static uint32_t DumpTargetList(TargetList &target_list,
142 bool show_stopped_process_status, Stream &strm) {
143 const uint32_t num_targets = target_list.GetNumTargets();
144 if (num_targets) {
145 TargetSP selected_target_sp(target_list.GetSelectedTarget());
146 strm.PutCString("Current targets:\n");
147 for (uint32_t i = 0; i < num_targets; ++i) {
148 TargetSP target_sp(target_list.GetTargetAtIndex(i));
149 if (target_sp) {
150 bool is_selected = target_sp.get() == selected_target_sp.get();
151 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
152 show_stopped_process_status, strm);
153 }
154 }
155 }
156 return num_targets;
157}
158
159#define LLDB_OPTIONS_target_dependents
160#include "CommandOptions.inc"
161
163public:
165
166 ~OptionGroupDependents() override = default;
167
168 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
169 return llvm::ArrayRef(g_target_dependents_options);
170 }
171
172 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
173 ExecutionContext *execution_context) override {
175
176 // For compatibility no value means don't load dependents.
177 if (option_value.empty()) {
179 return error;
180 }
181
182 const char short_option =
183 g_target_dependents_options[option_idx].short_option;
184 if (short_option == 'd') {
185 LoadDependentFiles tmp_load_dependents;
187 option_value, g_target_dependents_options[option_idx].enum_values, 0,
188 error);
189 if (error.Success())
190 m_load_dependent_files = tmp_load_dependents;
191 } else {
193 "unrecognized short option '%c'", short_option);
194 }
195
196 return error;
197 }
198
199 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
200
204
206
207private:
211};
212
213#pragma mark CommandObjectTargetCreate
214
216public:
219 interpreter, "target create",
220 "Create a target using the argument as the main executable.",
221 nullptr),
222 m_platform_options(true), // Include the --platform option.
223 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
224 "Fullpath to a core file to use for this target."),
225 m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,
226 "Optional name for this target.", nullptr),
227 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
229 "Fullpath to a stand alone debug "
230 "symbols file for when debug symbols "
231 "are not in the executable."),
233 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
234 "Fullpath to the file on the remote host if debugging remotely.") {
235
237
245 m_option_group.Finalize();
246 }
247
248 ~CommandObjectTargetCreate() override = default;
249
250 Options *GetOptions() override { return &m_option_group; }
251
252protected:
253 void DoExecute(Args &command, CommandReturnObject &result) override {
254 const size_t argc = command.GetArgumentCount();
255 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
256 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
257
258 if (core_file) {
259 auto file = FileSystem::Instance().Open(
261
262 if (!file) {
263 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
264 core_file.GetPath(),
265 llvm::toString(file.takeError()));
266 return;
267 }
268 }
269
270 if (argc == 1 || core_file || remote_file) {
271 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
272 if (symfile) {
273 auto file = FileSystem::Instance().Open(
275
276 if (!file) {
277 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
278 symfile.GetPath(),
279 llvm::toString(file.takeError()));
280 return;
281 }
282 }
283
284 const char *file_path = command.GetArgumentAtIndex(0);
285 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
286
287 bool must_set_platform_path = false;
288
289 Debugger &debugger = GetDebugger();
290
291 TargetSP target_sp;
292 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
294 debugger, file_path, arch_cstr,
295 m_add_dependents.m_load_dependent_files, &m_platform_options,
296 target_sp));
297
298 if (!target_sp) {
299 result.AppendError(error.AsCString());
300 return;
301 }
302
303 const llvm::StringRef label =
304 m_label.GetOptionValue().GetCurrentValueAsRef();
305 if (!label.empty()) {
306 if (auto E = target_sp->SetLabel(label))
307 result.SetError(std::move(E));
308 else
310 return;
311 }
312
313 llvm::scope_exit on_error(
314 [&target_list = debugger.GetTargetList(), &target_sp]() {
315 target_list.DeleteTarget(target_sp);
316 });
317
318 // Only get the platform after we create the target because we might
319 // have switched platforms depending on what the arguments were to
320 // CreateTarget() we can't rely on the selected platform.
321
322 PlatformSP platform_sp = target_sp->GetPlatform();
323
324 FileSpec file_spec;
325 if (file_path) {
326 file_spec.SetFile(file_path, FileSpec::Style::native);
327 FileSystem::Instance().Resolve(file_spec);
328
329 // Try to resolve the exe based on PATH and/or platform-specific
330 // suffixes, but only if using the host platform.
331 if (platform_sp && platform_sp->IsHost() &&
332 !FileSystem::Instance().Exists(file_spec))
334 }
335
336 if (remote_file) {
337 if (platform_sp) {
338 // I have a remote file.. two possible cases
339 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
340 // if the remote file does not exist, push it there
341 if (!platform_sp->GetFileExists(remote_file)) {
342 Status err = platform_sp->PutFile(file_spec, remote_file);
343 if (err.Fail()) {
344 result.AppendError(err.AsCString());
345 return;
346 }
347 }
348 } else {
349 // there is no local file and we need one
350 // in order to make the remote ---> local transfer we need a
351 // platform
352 // TODO: if the user has passed in a --platform argument, use it
353 // to fetch the right platform
354 if (file_path) {
355 // copy the remote file to the local file
356 Status err = platform_sp->GetFile(remote_file, file_spec);
357 if (err.Fail()) {
358 result.AppendError(err.AsCString());
359 return;
360 }
361 } else {
362 // If the remote file exists, we can debug reading that out of
363 // memory. If the platform is already connected to an lldb-server
364 // then we can at least check the file exists remotely. Otherwise
365 // we'll just have to trust that it will be there when we do
366 // process connect.
367 // I don't do this for the host platform because it seems odd to
368 // support supplying a remote file but no local file for a local
369 // debug session.
370 if (platform_sp->IsHost()) {
371 result.AppendError("Supply a local file, not a remote file, "
372 "when debugging on the host.");
373 return;
374 }
375 if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
376 result.AppendError("remote --> local transfer without local "
377 "path is not implemented yet");
378 return;
379 }
380 // Since there's only a remote file, we need to set the executable
381 // file spec to the remote one.
382 ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
383 launch_info.SetExecutableFile(FileSpec(remote_file), true);
384 target_sp->SetProcessLaunchInfo(launch_info);
385 }
386 }
387 } else {
388 result.AppendError("no platform found for target");
389 return;
390 }
391 }
392
393 if (symfile || remote_file) {
394 ModuleSP module_sp(target_sp->GetExecutableModule());
395 if (module_sp) {
396 if (symfile)
397 module_sp->SetSymbolFileFileSpec(symfile);
398 if (remote_file) {
399 std::string remote_path = remote_file.GetPath();
400 target_sp->SetArg0(remote_path.c_str());
401 module_sp->SetPlatformFileSpec(remote_file);
402 }
403 }
404 }
405
406 if (must_set_platform_path) {
407 ModuleSpec main_module_spec(file_spec);
408 ModuleSP module_sp =
409 target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
410 if (module_sp)
411 module_sp->SetPlatformFileSpec(remote_file);
412 }
413
414 if (core_file) {
415 FileSpec core_file_dir;
416 core_file_dir.SetDirectory(core_file.GetDirectory());
417 target_sp->AppendExecutableSearchPaths(core_file_dir);
418
419 ProcessSP process_sp(target_sp->CreateProcess(
420 GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
421
422 if (process_sp) {
423 // Seems weird that we Launch a core file, but that is what we
424 // do!
425 {
426 ElapsedTime load_core_time(
427 target_sp->GetStatistics().GetLoadCoreTime());
428 error = process_sp->LoadCore();
429 }
430
431 if (error.Fail()) {
432 result.AppendError(error.AsCString("unknown core file format"));
433 return;
434 } else {
436 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
437 target_sp->GetArchitecture().GetArchitectureName());
439 on_error.release();
440 }
441 } else {
442 result.AppendErrorWithFormatv("Unknown core file format '{0}'\n",
443 core_file.GetPath());
444 }
445 } else {
447 "Current executable set to '{0}' ({1}).",
448 file_spec.GetPath().c_str(),
449 target_sp->GetArchitecture().GetArchitectureName());
451 on_error.release();
452 }
453 } else {
454 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
455 "argument, or use the --core option",
456 m_cmd_name.c_str());
457 }
458 }
459
460private:
469};
470
471#pragma mark CommandObjectTargetList
472
474public:
477 interpreter, "target list",
478 "List all current targets in the current debug session.", nullptr) {
479 }
480
481 ~CommandObjectTargetList() override = default;
482
483protected:
484 void DoExecute(Args &args, CommandReturnObject &result) override {
485 Stream &strm = result.GetOutputStream();
486
487 bool show_stopped_process_status = false;
488 if (DumpTargetList(GetDebugger().GetTargetList(),
489 show_stopped_process_status, strm) == 0) {
490 strm.PutCString("No targets.\n");
491 }
493 }
494};
495
496#pragma mark CommandObjectTargetSelect
497
499public:
502 interpreter, "target select",
503 "Select a target as the current target by target index.", nullptr) {
505 }
506
507 ~CommandObjectTargetSelect() override = default;
508
509protected:
510 void DoExecute(Args &args, CommandReturnObject &result) override {
511 if (args.GetArgumentCount() == 1) {
512 const char *target_identifier = args.GetArgumentAtIndex(0);
513 uint32_t target_idx = LLDB_INVALID_INDEX32;
514 TargetList &target_list = GetDebugger().GetTargetList();
515 const uint32_t num_targets = target_list.GetNumTargets();
516 if (llvm::to_integer(target_identifier, target_idx)) {
517 if (target_idx < num_targets) {
518 target_list.SetSelectedTarget(target_idx);
519 Stream &strm = result.GetOutputStream();
520 bool show_stopped_process_status = false;
521 DumpTargetList(target_list, show_stopped_process_status, strm);
523 } else {
524 if (num_targets > 0) {
526 "index %u is out of range, valid target indexes are 0 - %u",
527 target_idx, num_targets - 1);
528 } else {
530 "index %u is out of range since there are no active targets",
531 target_idx);
532 }
533 }
534 } else {
535 for (size_t i = 0; i < num_targets; i++) {
536 if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {
537 const std::string &label = target_sp->GetLabel();
538 if (!label.empty() && label == target_identifier) {
539 target_idx = i;
540 break;
541 }
542 }
543 }
544
545 if (target_idx != LLDB_INVALID_INDEX32) {
546 target_list.SetSelectedTarget(target_idx);
547 Stream &strm = result.GetOutputStream();
548 bool show_stopped_process_status = false;
549 DumpTargetList(target_list, show_stopped_process_status, strm);
551 } else {
552 result.AppendErrorWithFormat("invalid index string value '%s'",
553 target_identifier);
554 }
555 }
556 } else {
557 result.AppendError(
558 "'target select' takes a single argument: a target index\n");
559 }
560 }
561};
562
563#pragma mark CommandObjectTargetDelete
564
566public:
568 : CommandObjectParsed(interpreter, "target delete",
569 "Delete one or more targets by target index.",
570 nullptr),
571 m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
572 false, true),
574 LLDB_OPT_SET_1, false, "clean", 'c',
575 "Perform extra cleanup to minimize memory consumption after "
576 "deleting the target. "
577 "By default, LLDB will keep in memory any modules previously "
578 "loaded by the target as well "
579 "as all of its debug info. Specifying --clean will unload all of "
580 "these shared modules and "
581 "cause them to be reparsed again the next time the target is run",
582 false, true) {
585 m_option_group.Finalize();
587 }
588
589 ~CommandObjectTargetDelete() override = default;
590
591 Options *GetOptions() override { return &m_option_group; }
592
593protected:
594 void DoExecute(Args &args, CommandReturnObject &result) override {
595 const size_t argc = args.GetArgumentCount();
596 std::vector<TargetSP> delete_target_list;
597 TargetList &target_list = GetDebugger().GetTargetList();
598 TargetSP target_sp;
599
600 if (m_all_option.GetOptionValue()) {
601 for (size_t i = 0; i < target_list.GetNumTargets(); ++i)
602 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
603 } else if (argc > 0) {
604 const uint32_t num_targets = target_list.GetNumTargets();
605 // Bail out if don't have any targets.
606 if (num_targets == 0) {
607 result.AppendError("no targets to delete");
608 return;
609 }
610
611 for (auto &entry : args.entries()) {
612 uint32_t target_idx;
613 if (entry.ref().getAsInteger(0, target_idx)) {
614 result.AppendErrorWithFormat("invalid target index '%s'",
615 entry.c_str());
616 return;
617 }
618 if (target_idx < num_targets) {
619 target_sp = target_list.GetTargetAtIndex(target_idx);
620 if (target_sp) {
621 delete_target_list.push_back(target_sp);
622 continue;
623 }
624 }
625 if (num_targets > 1)
626 result.AppendErrorWithFormat("target index %u is out of range, valid "
627 "target indexes are 0 - %u",
628 target_idx, num_targets - 1);
629 else
631 "target index %u is out of range, the only valid index is 0",
632 target_idx);
633
634 return;
635 }
636 } else {
637 target_sp = target_list.GetSelectedTarget();
638 if (!target_sp) {
639 result.AppendErrorWithFormat("no target is currently selected");
640 return;
641 }
642 delete_target_list.push_back(target_sp);
643 }
644
645 const size_t num_targets_to_delete = delete_target_list.size();
646 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
647 target_sp = delete_target_list[idx];
648 target_list.DeleteTarget(target_sp);
649 target_sp->Destroy();
650 }
651 // If "--clean" was specified, prune any orphaned shared modules from the
652 // global shared module list
653 if (m_cleanup_option.GetOptionValue()) {
654 const bool mandatory = true;
656 }
657 result.GetOutputStream().Printf("%u targets deleted.\n",
658 (uint32_t)num_targets_to_delete);
660 }
661
665};
666
668public:
671 interpreter, "target show-launch-environment",
672 "Shows the environment being passed to the process when launched, "
673 "taking info account 3 settings: target.env-vars, "
674 "target.inherit-env and target.unset-env-vars.",
675 nullptr, eCommandRequiresTarget) {}
676
678
679protected:
680 void DoExecute(Args &args, CommandReturnObject &result) override {
681 Target *target = m_exe_ctx.GetTargetPtr();
682 Environment env = target->GetEnvironment();
683
684 std::vector<Environment::value_type *> env_vector;
685 env_vector.reserve(env.size());
686 for (auto &KV : env)
687 env_vector.push_back(&KV);
688 std::sort(env_vector.begin(), env_vector.end(),
689 [](Environment::value_type *a, Environment::value_type *b) {
690 return a->first() < b->first();
691 });
692
693 auto &strm = result.GetOutputStream();
694 for (auto &KV : env_vector)
695 strm.Format("{0}={1}\n", KV->first(), KV->second);
696
698 }
699};
700
701#pragma mark CommandObjectTargetVariable
702
704 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
705 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
706
707public:
709 : CommandObjectParsed(interpreter, "target variable",
710 "Read global variables for the current target, "
711 "before or while running a process.",
712 nullptr, eCommandRequiresTarget),
713 m_option_variable(false), // Don't include frame options
717 "A basename or fullpath to a file that contains "
718 "global variables. This option can be "
719 "specified multiple times."),
721 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
723 "A basename or fullpath to a shared library to use in the search "
724 "for global "
725 "variables. This option can be specified multiple times.") {
727
738 m_option_group.Finalize();
739 }
740
741 ~CommandObjectTargetVariable() override = default;
742
743 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
744 const char *root_name) {
745 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
746
747 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
748 valobj_sp->IsRuntimeSupportValue())
749 return;
750
751 switch (var_sp->GetScope()) {
753 if (m_option_variable.show_scope)
754 s.PutCString("GLOBAL: ");
755 break;
756
758 if (m_option_variable.show_scope)
759 s.PutCString("STATIC: ");
760 break;
761
763 if (m_option_variable.show_scope)
764 s.PutCString(" ARG: ");
765 break;
766
768 if (m_option_variable.show_scope)
769 s.PutCString(" LOCAL: ");
770 break;
771
773 if (m_option_variable.show_scope)
774 s.PutCString("THREAD: ");
775 break;
776
777 default:
778 break;
779 }
780
781 if (m_option_variable.show_decl) {
782 bool show_fullpaths = false;
783 bool show_module = true;
784 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
785 s.PutCString(": ");
786 }
787
788 const Format format = m_option_format.GetFormat();
789 if (format != eFormatDefault)
790 options.SetFormat(format);
791
792 options.SetRootValueObjectName(root_name);
793
794 if (llvm::Error error = valobj_sp->Dump(s, options))
795 s << "error: " << toString(std::move(error));
796 }
797
798 static size_t GetVariableCallback(void *baton, const char *name,
799 VariableList &variable_list) {
800 size_t old_size = variable_list.GetSize();
801 Target *target = static_cast<Target *>(baton);
802 if (target)
804 variable_list);
805 return variable_list.GetSize() - old_size;
806 }
807
808 Options *GetOptions() override { return &m_option_group; }
809
810protected:
812 const SymbolContext &sc,
813 const VariableList &variable_list,
814 CommandReturnObject &result) {
815 Stream &s = result.GetOutputStream();
816 if (variable_list.Empty())
817 return;
818 if (sc.module_sp) {
819 if (sc.comp_unit) {
820 s.Format("Global variables for {0} in {1}:\n",
821 sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
822 } else {
823 s.Printf("Global variables for %s\n",
824 sc.module_sp->GetFileSpec().GetPath().c_str());
825 }
826 } else if (sc.comp_unit) {
827 s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
828 }
829
830 for (VariableSP var_sp : variable_list) {
831 if (!var_sp)
832 continue;
834 exe_ctx.GetBestExecutionContextScope(), var_sp));
835
836 if (valobj_sp) {
837 result.GetValueObjectList().Append(valobj_sp);
838 DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
839 }
840 }
841 }
842
843 void DoExecute(Args &args, CommandReturnObject &result) override {
844 Target *target = m_exe_ctx.GetTargetPtr();
845 const size_t argc = args.GetArgumentCount();
846
847 if (argc > 0) {
848 for (const Args::ArgEntry &arg : args) {
849 VariableList variable_list;
850 ValueObjectList valobj_list;
851
852 size_t matches = 0;
853 bool use_var_name = false;
854 if (m_option_variable.use_regex) {
855 RegularExpression regex(arg.ref());
856 if (!regex.IsValid()) {
857 result.GetErrorStream().Printf(
858 "error: invalid regular expression: '%s'\n", arg.c_str());
859 return;
860 }
861 use_var_name = true;
863 variable_list);
864 matches = variable_list.GetSize();
865 } else {
867 arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
868 GetVariableCallback, target, variable_list, valobj_list));
869 matches = variable_list.GetSize();
870 }
871
872 if (matches == 0) {
873 result.AppendErrorWithFormat("can't find global variable '%s'",
874 arg.c_str());
875 return;
876 } else {
877 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
878 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
879 if (var_sp) {
880 ValueObjectSP valobj_sp(
881 valobj_list.GetValueObjectAtIndex(global_idx));
882 if (!valobj_sp)
883 valobj_sp = ValueObjectVariable::Create(
884 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
885
886 if (valobj_sp)
887 DumpValueObject(result.GetOutputStream(), var_sp, valobj_sp,
888 use_var_name ? var_sp->GetName().GetCString()
889 : arg.c_str());
890 }
891 }
892 }
893 }
894 } else {
895 const FileSpecList &compile_units =
896 m_option_compile_units.GetOptionValue().GetCurrentValue();
897 const FileSpecList &shlibs =
898 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
899 SymbolContextList sc_list;
900 const size_t num_compile_units = compile_units.GetSize();
901 const size_t num_shlibs = shlibs.GetSize();
902 if (num_compile_units == 0 && num_shlibs == 0) {
903 bool success = false;
904 StackFrame *frame = m_exe_ctx.GetFramePtr();
905 CompileUnit *comp_unit = nullptr;
906 if (frame) {
907 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
908 comp_unit = sc.comp_unit;
909 if (sc.comp_unit) {
910 const bool can_create = true;
911 VariableListSP comp_unit_varlist_sp(
912 sc.comp_unit->GetVariableList(can_create));
913 if (comp_unit_varlist_sp) {
914 size_t count = comp_unit_varlist_sp->GetSize();
915 if (count > 0) {
916 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
917 result);
918 success = true;
919 }
920 }
921 }
922 }
923 if (!success) {
924 if (frame) {
925 if (comp_unit)
927 "no global variables in current compile unit: {0}\n",
928 comp_unit->GetPrimaryFile());
929 else
930 result.AppendErrorWithFormat("no debug information for frame %u",
931 frame->GetFrameIndex());
932 } else
933 result.AppendError("'target variable' takes one or more global "
934 "variable names as arguments\n");
935 }
936 } else {
937 SymbolContextList sc_list;
938 // We have one or more compile unit or shlib
939 if (num_shlibs > 0) {
940 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
941 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
942 ModuleSpec module_spec(module_file);
943
944 ModuleSP module_sp(
945 target->GetImages().FindFirstModule(module_spec));
946 if (module_sp) {
947 if (num_compile_units > 0) {
948 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
949 module_sp->FindCompileUnits(
950 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
951 } else {
952 SymbolContext sc;
953 sc.module_sp = module_sp;
954 sc_list.Append(sc);
955 }
956 } else {
957 // Didn't find matching shlib/module in target...
959 "target doesn't contain the specified shared library: %s",
960 module_file.GetPath().c_str());
961 }
962 }
963 } else {
964 // No shared libraries, we just want to find globals for the compile
965 // units files that were specified
966 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
967 target->GetImages().FindCompileUnits(
968 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
969 }
970
971 for (const SymbolContext &sc : sc_list) {
972 if (sc.comp_unit) {
973 const bool can_create = true;
974 VariableListSP comp_unit_varlist_sp(
975 sc.comp_unit->GetVariableList(can_create));
976 if (comp_unit_varlist_sp)
977 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
978 result);
979 } else if (sc.module_sp) {
980 // Get all global variables for this module
981 lldb_private::RegularExpression all_globals_regex(
982 llvm::StringRef(".")); // Any global with at least one character
983 VariableList variable_list;
984 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
985 variable_list);
986 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, result);
987 }
988 }
989 }
990 }
991
992 m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
993 m_cmd_name);
994 if (result.GetStatus() != eReturnStatusFailed)
996 }
997
1004};
1005
1006#pragma mark CommandObjectTargetModulesSearchPathsAdd
1007
1009public:
1011 : CommandObjectParsed(interpreter, "target modules search-paths add",
1012 "Add new image search paths substitution pairs to "
1013 "the current target.",
1014 nullptr, eCommandRequiresTarget) {
1016 CommandArgumentData old_prefix_arg;
1017 CommandArgumentData new_prefix_arg;
1018
1019 // Define the first variant of this arg pair.
1020 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1021 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1022
1023 // Define the first variant of this arg pair.
1024 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1025 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1026
1027 // There are two required arguments that must always occur together, i.e.
1028 // an argument "pair". Because they must always occur together, they are
1029 // treated as two variants of one argument rather than two independent
1030 // arguments. Push them both into the first argument position for
1031 // m_arguments...
1032
1033 arg.push_back(old_prefix_arg);
1034 arg.push_back(new_prefix_arg);
1035
1036 m_arguments.push_back(arg);
1037 }
1038
1040
1041protected:
1042 void DoExecute(Args &command, CommandReturnObject &result) override {
1043 Target &target = GetTarget();
1044 const size_t argc = command.GetArgumentCount();
1045 if (argc & 1) {
1046 result.AppendError("add requires an even number of arguments\n");
1047 } else {
1048 for (size_t i = 0; i < argc; i += 2) {
1049 const char *from = command.GetArgumentAtIndex(i);
1050 const char *to = command.GetArgumentAtIndex(i + 1);
1051
1052 if (from[0] && to[0]) {
1054 "target modules search path adding ImageSearchPath "
1055 "pair: '%s' -> '%s'",
1056 from, to);
1057 bool last_pair = ((argc - i) == 2);
1059 from, to, last_pair); // Notify if this is the last pair
1061 } else {
1062 if (from[0])
1063 result.AppendError("<path-prefix> can't be empty\n");
1064 else
1065 result.AppendError("<new-path-prefix> can't be empty\n");
1066 }
1067 }
1068 }
1069 }
1070};
1071
1072#pragma mark CommandObjectTargetModulesSearchPathsClear
1073
1075public:
1077 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1078 "Clear all current image search path substitution "
1079 "pairs from the current target.",
1080 "target modules search-paths clear",
1081 eCommandRequiresTarget) {}
1082
1084
1085protected:
1086 void DoExecute(Args &command, CommandReturnObject &result) override {
1087 Target &target = GetTarget();
1088 bool notify = true;
1089 target.GetImageSearchPathList().Clear(notify);
1091 }
1092};
1093
1094#pragma mark CommandObjectTargetModulesSearchPathsInsert
1095
1097public:
1099 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1100 "Insert a new image search path substitution pair "
1101 "into the current target at the specified index.",
1102 nullptr, eCommandRequiresTarget) {
1105 CommandArgumentData index_arg;
1106 CommandArgumentData old_prefix_arg;
1107 CommandArgumentData new_prefix_arg;
1108
1109 // Define the first and only variant of this arg.
1110 index_arg.arg_type = eArgTypeIndex;
1111 index_arg.arg_repetition = eArgRepeatPlain;
1112
1113 // Put the one and only variant into the first arg for m_arguments:
1114 arg1.push_back(index_arg);
1115
1116 // Define the first variant of this arg pair.
1117 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1118 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1119
1120 // Define the first variant of this arg pair.
1121 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1122 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1123
1124 // There are two required arguments that must always occur together, i.e.
1125 // an argument "pair". Because they must always occur together, they are
1126 // treated as two variants of one argument rather than two independent
1127 // arguments. Push them both into the same argument position for
1128 // m_arguments...
1129
1130 arg2.push_back(old_prefix_arg);
1131 arg2.push_back(new_prefix_arg);
1132
1133 // Add arguments to m_arguments.
1134 m_arguments.push_back(arg1);
1135 m_arguments.push_back(arg2);
1136 }
1137
1139
1140 void
1142 OptionElementVector &opt_element_vector) override {
1143 if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1144 return;
1145
1146 Target *target = m_exe_ctx.GetTargetPtr();
1147 const PathMappingList &list = target->GetImageSearchPathList();
1148 const size_t num = list.GetSize();
1149 ConstString old_path, new_path;
1150 for (size_t i = 0; i < num; ++i) {
1151 if (!list.GetPathsAtIndex(i, old_path, new_path))
1152 break;
1153 StreamString strm;
1154 strm << old_path << " -> " << new_path;
1155 request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1156 }
1157 }
1158
1159protected:
1160 void DoExecute(Args &command, CommandReturnObject &result) override {
1161 Target &target = GetTarget();
1162 size_t argc = command.GetArgumentCount();
1163 // check for at least 3 arguments and an odd number of parameters
1164 if (argc >= 3 && argc & 1) {
1165 uint32_t insert_idx;
1166
1167 if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1168 result.AppendErrorWithFormat(
1169 "<index> parameter is not an integer: '%s'",
1170 command.GetArgumentAtIndex(0));
1171 return;
1172 }
1173
1174 // shift off the index
1175 command.Shift();
1176 argc = command.GetArgumentCount();
1177
1178 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1179 const char *from = command.GetArgumentAtIndex(i);
1180 const char *to = command.GetArgumentAtIndex(i + 1);
1181
1182 if (from[0] && to[0]) {
1183 bool last_pair = ((argc - i) == 2);
1184 target.GetImageSearchPathList().Insert(from, to, insert_idx,
1185 last_pair);
1187 } else {
1188 if (from[0])
1189 result.AppendError("<path-prefix> can't be empty\n");
1190 else
1191 result.AppendError("<new-path-prefix> can't be empty\n");
1192 return;
1193 }
1194 }
1195 } else {
1196 result.AppendError("insert requires at least three arguments\n");
1197 }
1198 }
1199};
1200
1201#pragma mark CommandObjectTargetModulesSearchPathsList
1202
1204public:
1206 : CommandObjectParsed(interpreter, "target modules search-paths list",
1207 "List all current image search path substitution "
1208 "pairs in the current target.",
1209 "target modules search-paths list",
1210 eCommandRequiresTarget) {}
1211
1213
1214protected:
1215 void DoExecute(Args &command, CommandReturnObject &result) override {
1216 Target &target = GetTarget();
1217 target.GetImageSearchPathList().Dump(&result.GetOutputStream());
1219 }
1220};
1221
1222#pragma mark CommandObjectTargetModulesSearchPathsQuery
1223
1225public:
1228 interpreter, "target modules search-paths query",
1229 "Transform a path using the first applicable image search path.",
1230 nullptr, eCommandRequiresTarget) {
1232 }
1233
1235
1236protected:
1237 void DoExecute(Args &command, CommandReturnObject &result) override {
1238 Target &target = GetTarget();
1239 if (command.GetArgumentCount() != 1) {
1240 result.AppendError("query requires one argument\n");
1241 return;
1242 }
1243
1244 ConstString orig(command.GetArgumentAtIndex(0));
1245 ConstString transformed;
1246 if (target.GetImageSearchPathList().RemapPath(orig, transformed))
1247 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1248 else
1249 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1250
1252 }
1253};
1254
1255// Static Helper functions
1256static void DumpModuleArchitecture(Stream &strm, Module *module,
1257 bool full_triple, uint32_t width) {
1258 if (module) {
1259 StreamString arch_strm;
1260
1261 if (full_triple)
1262 module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1263 else
1264 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1265 std::string arch_str = std::string(arch_strm.GetString());
1266
1267 if (width)
1268 strm.Printf("%-*s", width, arch_str.c_str());
1269 else
1270 strm.PutCString(arch_str);
1271 }
1272}
1273
1274static void DumpModuleUUID(Stream &strm, Module *module) {
1275 if (module && module->GetUUID().IsValid())
1276 module->GetUUID().Dump(strm);
1277 else
1278 strm.PutCString(" ");
1279}
1280
1282 Stream &strm, Module *module,
1283 const FileSpec &file_spec,
1284 lldb::DescriptionLevel desc_level) {
1285 uint32_t num_matches = 0;
1286 if (module) {
1287 SymbolContextList sc_list;
1288 num_matches = module->ResolveSymbolContextsForFileSpec(
1289 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1290
1291 bool first_module = true;
1292 for (const SymbolContext &sc : sc_list) {
1293 if (!first_module)
1294 strm << "\n\n";
1295
1296 strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1297 << module->GetFileSpec().GetFilename() << "\n";
1298 LineTable *line_table = sc.comp_unit->GetLineTable();
1299 if (line_table)
1300 line_table->GetDescription(
1301 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1302 desc_level);
1303 else
1304 strm << "No line table";
1305
1306 first_module = false;
1307 }
1308 }
1309 return num_matches;
1310}
1311
1312static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1313 uint32_t width) {
1314 if (file_spec_ptr) {
1315 if (width > 0) {
1316 std::string fullpath = file_spec_ptr->GetPath();
1317 strm.Printf("%-*s", width, fullpath.c_str());
1318 return;
1319 } else {
1320 file_spec_ptr->Dump(strm.AsRawOstream());
1321 return;
1322 }
1323 }
1324 // Keep the width spacing correct if things go wrong...
1325 if (width > 0)
1326 strm.Printf("%-*s", width, "");
1327}
1328
1329static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1330 uint32_t width) {
1331 if (file_spec_ptr) {
1332 if (width > 0)
1333 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1334 else
1335 file_spec_ptr->GetDirectory().Dump(&strm);
1336 return;
1337 }
1338 // Keep the width spacing correct if things go wrong...
1339 if (width > 0)
1340 strm.Printf("%-*s", width, "");
1341}
1342
1343static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1344 uint32_t width) {
1345 if (file_spec_ptr) {
1346 if (width > 0)
1347 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1348 else
1349 file_spec_ptr->GetFilename().Dump(&strm);
1350 return;
1351 }
1352 // Keep the width spacing correct if things go wrong...
1353 if (width > 0)
1354 strm.Printf("%-*s", width, "");
1355}
1356
1357static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1358 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1359 const size_t num_modules = module_list.GetSize();
1360 if (num_modules == 0)
1361 return 0;
1362
1363 size_t num_dumped = 0;
1364 strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1365 strm.IndentMore();
1366 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1367 if (module_sp) {
1368 if (num_dumped++ > 0) {
1369 strm.EOL();
1370 strm.EOL();
1371 }
1372 ObjectFile *objfile = module_sp->GetObjectFile();
1373 if (objfile)
1374 objfile->Dump(&strm);
1375 else {
1376 strm.Format("No object file for module: {0:F}\n",
1377 module_sp->GetFileSpec());
1378 }
1379 }
1380 }
1381 strm.IndentLess();
1382 return num_dumped;
1383}
1384
1385static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1386 Module *module, SortOrder sort_order,
1387 Mangled::NamePreference name_preference) {
1388 if (!module)
1389 return;
1390 if (Symtab *symtab = module->GetSymtab())
1391 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1392 sort_order, name_preference);
1393}
1394
1395static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1396 Module *module) {
1397 if (module) {
1398 SectionList *section_list = module->GetSectionList();
1399 if (section_list) {
1400 strm.Printf("Sections for '%s' (%s):\n",
1401 module->GetSpecificationDescription().c_str(),
1403 section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1404 interpreter.GetExecutionContext().GetTargetPtr(), true,
1405 UINT32_MAX);
1406 }
1407 }
1408}
1409
1410static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1411 if (module) {
1412 if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1413 symbol_file->Dump(strm);
1414 return true;
1415 }
1416 }
1417 return false;
1418}
1419
1421 Module *module, bool errors_only,
1422 bool load_all_debug_info) {
1423 if (module) {
1424 if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) {
1426 if (symbol_file->GetSeparateDebugInfo(d, errors_only,
1427 load_all_debug_info)) {
1428 list.AddItem(
1429 std::make_shared<StructuredData::Dictionary>(std::move(d)));
1430 return true;
1431 }
1432 }
1433 }
1434 return false;
1435}
1436
1437static void DumpDwoFilesTable(Stream &strm,
1438 StructuredData::Array &dwo_listings) {
1439 strm.PutCString("Dwo ID Err Dwo Path");
1440 strm.EOL();
1441 strm.PutCString(
1442 "------------------ --- -----------------------------------------");
1443 strm.EOL();
1444 dwo_listings.ForEach([&strm](StructuredData::Object *dwo) {
1446 if (!dict)
1447 return false;
1448
1449 uint64_t dwo_id;
1450 if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id))
1451 strm.Printf("0x%16.16" PRIx64 " ", dwo_id);
1452 else
1453 strm.Printf("0x???????????????? ");
1454
1455 llvm::StringRef error;
1456 if (dict->GetValueForKeyAsString("error", error))
1457 strm << "E " << error;
1458 else {
1459 llvm::StringRef resolved_dwo_path;
1460 if (dict->GetValueForKeyAsString("resolved_dwo_path",
1461 resolved_dwo_path)) {
1462 strm << " " << resolved_dwo_path;
1463 if (resolved_dwo_path.ends_with(".dwp")) {
1464 llvm::StringRef dwo_name;
1465 if (dict->GetValueForKeyAsString("dwo_name", dwo_name))
1466 strm << "(" << dwo_name << ")";
1467 }
1468 }
1469 }
1470 strm.EOL();
1471 return true;
1472 });
1473}
1474
1475static void DumpOsoFilesTable(Stream &strm,
1476 StructuredData::Array &oso_listings) {
1477 strm.PutCString("Mod Time Err Oso Path");
1478 strm.EOL();
1479 strm.PutCString("------------------ --- ---------------------");
1480 strm.EOL();
1481 oso_listings.ForEach([&strm](StructuredData::Object *oso) {
1483 if (!dict)
1484 return false;
1485
1486 uint32_t oso_mod_time;
1487 if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time))
1488 strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time);
1489
1490 llvm::StringRef error;
1491 if (dict->GetValueForKeyAsString("error", error))
1492 strm << "E " << error;
1493 else {
1494 llvm::StringRef oso_path;
1495 if (dict->GetValueForKeyAsString("oso_path", oso_path))
1496 strm << " " << oso_path;
1497 }
1498 strm.EOL();
1499 return true;
1500 });
1501}
1502
1503static void
1504DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,
1505 bool verbose, bool all_ranges, Stream &strm,
1506 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1507 strm.IndentMore();
1508 strm.Indent(" Address: ");
1509 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1510 strm.PutCString(" (");
1511 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1512 strm.PutCString(")\n");
1513 strm.Indent(" Summary: ");
1514 const uint32_t save_indent = strm.GetIndentLevel();
1515 strm.SetIndentLevel(save_indent + 13);
1516 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
1517 Address::DumpStyleInvalid, UINT32_MAX, false, settings);
1518 strm.SetIndentLevel(save_indent);
1519 // Print out detailed address information when verbose is enabled
1520 if (verbose) {
1521 strm.EOL();
1522 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1523 Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);
1524 }
1525 strm.IndentLess();
1526}
1527
1528static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1529 Module *module, uint32_t resolve_mask,
1530 lldb::addr_t raw_addr, lldb::addr_t offset,
1531 bool verbose, bool all_ranges) {
1532 if (module) {
1533 lldb::addr_t addr = raw_addr - offset;
1534 Address so_addr;
1535 SymbolContext sc;
1536 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1537 if (target && target->HasLoadedSections()) {
1538 if (!target->ResolveLoadAddress(addr, so_addr))
1539 return false;
1540 else if (so_addr.GetModule().get() != module)
1541 return false;
1542 } else {
1543 if (!module->ResolveFileAddress(addr, so_addr))
1544 return false;
1545 }
1546
1547 ExecutionContextScope *exe_scope =
1549 DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
1550 return true;
1551 }
1552
1553 return false;
1554}
1555
1556static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1557 Stream &strm, Module *module,
1558 const char *name, bool name_is_regex,
1559 bool verbose, bool all_ranges) {
1560 if (!module)
1561 return 0;
1562
1563 Symtab *symtab = module->GetSymtab();
1564 if (!symtab)
1565 return 0;
1566
1567 SymbolContext sc;
1568 const bool use_color = interpreter.GetDebugger().GetUseColor();
1569 std::vector<uint32_t> match_indexes;
1570 ConstString symbol_name(name);
1571 uint32_t num_matches = 0;
1572 if (name_is_regex) {
1573 RegularExpression name_regexp(symbol_name.GetStringRef());
1574 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1575 name_regexp, eSymbolTypeAny, match_indexes);
1576 } else {
1577 num_matches =
1578 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1579 }
1580
1581 if (num_matches > 0) {
1582 strm.Indent();
1583 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1584 name_is_regex ? "the regular expression " : "", name);
1585 DumpFullpath(strm, &module->GetFileSpec(), 0);
1586 strm.PutCString(":\n");
1587 strm.IndentMore();
1589 name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),
1590 interpreter.GetDebugger().GetRegexMatchAnsiSuffix());
1591 for (uint32_t i = 0; i < num_matches; ++i) {
1592 const Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1593 if (symbol) {
1594 if (symbol->ValueIsAddress()) {
1597 symbol->GetAddressRef(), verbose, all_ranges, strm,
1598 use_color && name_is_regex
1599 ? std::optional<Stream::HighlightSettings>{settings}
1600 : std::nullopt);
1601 strm.EOL();
1602 } else {
1603 strm.IndentMore();
1604 strm.Indent(" Name: ");
1606 symbol->GetDisplayName().GetStringRef(),
1607 use_color && name_is_regex
1608 ? std::optional<Stream::HighlightSettings>{settings}
1609 : std::nullopt);
1610 strm.EOL();
1611 strm.Indent(" Value: ");
1612 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1613 if (symbol->GetByteSizeIsValid()) {
1614 strm.Indent(" Size: ");
1615 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1616 }
1617 strm.IndentLess();
1618 }
1619 }
1620 }
1621 strm.IndentLess();
1622 }
1623 return num_matches;
1624}
1625
1627 ExecutionContextScope *exe_scope, Stream &strm,
1628 const SymbolContextList &sc_list, bool verbose, bool all_ranges,
1629 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1630 strm.IndentMore();
1631 bool first_module = true;
1632 for (const SymbolContext &sc : sc_list) {
1633 if (!first_module)
1634 strm.EOL();
1635
1636 Address addr;
1637 if (sc.line_entry.IsValid())
1638 addr = sc.line_entry.range.GetBaseAddress();
1639 else if (sc.block && sc.block->GetContainingInlinedBlock())
1640 sc.block->GetContainingInlinedBlock()->GetStartAddress(addr);
1641 else
1642 addr = sc.GetFunctionOrSymbolAddress();
1643
1644 DumpAddress(exe_scope, addr, verbose, all_ranges, strm, settings);
1645 first_module = false;
1646 }
1647 strm.IndentLess();
1648}
1649
1651 Stream &strm, Module *module,
1652 const char *name, bool name_is_regex,
1653 const ModuleFunctionSearchOptions &options,
1654 bool verbose, bool all_ranges) {
1655 if (module && name && name[0]) {
1656 SymbolContextList sc_list;
1657 size_t num_matches = 0;
1658 if (name_is_regex) {
1659 RegularExpression function_name_regex((llvm::StringRef(name)));
1660 module->FindFunctions(function_name_regex, options, sc_list);
1661 } else {
1662 ConstString function_name(name);
1663 module->FindFunctions(function_name, CompilerDeclContext(),
1664 eFunctionNameTypeAuto, options, sc_list);
1665 }
1666 num_matches = sc_list.GetSize();
1667 if (num_matches) {
1668 strm.Indent();
1669 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1670 num_matches > 1 ? "es" : "");
1671 DumpFullpath(strm, &module->GetFileSpec(), 0);
1672 strm.PutCString(":\n");
1675 strm, sc_list, verbose, all_ranges);
1676 }
1677 return num_matches;
1678 }
1679 return 0;
1680}
1681
1682static size_t LookupTypeInModule(Target *target,
1683 CommandInterpreter &interpreter, Stream &strm,
1684 Module *module, const char *name_cstr,
1685 bool name_is_regex) {
1686 if (module && name_cstr && name_cstr[0]) {
1687 TypeQuery query(name_cstr);
1688 TypeResults results;
1689 module->FindTypes(query, results);
1690
1691 TypeList type_list;
1692 SymbolContext sc;
1693 if (module)
1694 sc.module_sp = module->shared_from_this();
1695 // Sort the type results and put the results that matched in \a module
1696 // first if \a module was specified.
1697 sc.SortTypeList(results.GetTypeMap(), type_list);
1698 if (type_list.Empty())
1699 return 0;
1700
1701 const uint64_t num_matches = type_list.GetSize();
1702
1703 strm.Indent();
1704 strm.Printf("%" PRIu64 " match%s found in ", num_matches,
1705 num_matches > 1 ? "es" : "");
1706 DumpFullpath(strm, &module->GetFileSpec(), 0);
1707 strm.PutCString(":\n");
1708 for (TypeSP type_sp : type_list.Types()) {
1709 if (!type_sp)
1710 continue;
1711 // Resolve the clang type so that any forward references to types
1712 // that haven't yet been parsed will get parsed.
1713 type_sp->GetFullCompilerType();
1714 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1715 // Print all typedef chains
1716 TypeSP typedef_type_sp(type_sp);
1717 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1718 while (typedefed_type_sp) {
1719 strm.EOL();
1720 strm.Printf(" typedef '%s': ",
1721 typedef_type_sp->GetName().GetCString());
1722 typedefed_type_sp->GetFullCompilerType();
1723 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1724 target);
1725 typedef_type_sp = typedefed_type_sp;
1726 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1727 }
1728 strm.EOL();
1729 }
1730 return type_list.GetSize();
1731 }
1732 return 0;
1733}
1734
1735static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1736 Stream &strm, Module &module,
1737 const char *name_cstr, bool name_is_regex) {
1738 TypeQuery query(name_cstr);
1739 TypeResults results;
1740 module.FindTypes(query, results);
1741 TypeList type_list;
1742 SymbolContext sc;
1743 sc.module_sp = module.shared_from_this();
1744 sc.SortTypeList(results.GetTypeMap(), type_list);
1745 if (type_list.Empty())
1746 return 0;
1747
1748 strm.Indent();
1749 strm.PutCString("Best match found in ");
1750 DumpFullpath(strm, &module.GetFileSpec(), 0);
1751 strm.PutCString(":\n");
1752
1753 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1754 if (type_sp) {
1755 // Resolve the clang type so that any forward references to types that
1756 // haven't yet been parsed will get parsed.
1757 type_sp->GetFullCompilerType();
1758 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1759 // Print all typedef chains.
1760 TypeSP typedef_type_sp(type_sp);
1761 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1762 while (typedefed_type_sp) {
1763 strm.EOL();
1764 strm.Printf(" typedef '%s': ",
1765 typedef_type_sp->GetName().GetCString());
1766 typedefed_type_sp->GetFullCompilerType();
1767 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1768 target);
1769 typedef_type_sp = typedefed_type_sp;
1770 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1771 }
1772 }
1773 strm.EOL();
1774 return type_list.GetSize();
1775}
1776
1778 Stream &strm, Module *module,
1779 const FileSpec &file_spec,
1780 uint32_t line, bool check_inlines,
1781 bool verbose, bool all_ranges) {
1782 if (module && file_spec) {
1783 SymbolContextList sc_list;
1784 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1785 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1786 if (num_matches > 0) {
1787 strm.Indent();
1788 strm.Printf("%u match%s found in ", num_matches,
1789 num_matches > 1 ? "es" : "");
1790 strm << file_spec;
1791 if (line > 0)
1792 strm.Printf(":%u", line);
1793 strm << " in ";
1794 DumpFullpath(strm, &module->GetFileSpec(), 0);
1795 strm.PutCString(":\n");
1798 strm, sc_list, verbose, all_ranges);
1799 return num_matches;
1800 }
1801 }
1802 return 0;
1803}
1804
1805static size_t FindModulesByName(Target *target, const char *module_name,
1806 ModuleList &module_list,
1807 bool check_global_list) {
1808 FileSpec module_file_spec(module_name);
1809 ModuleSpec module_spec(module_file_spec);
1810
1811 const size_t initial_size = module_list.GetSize();
1812
1813 if (check_global_list) {
1814 // Check the global list
1815 std::lock_guard<std::recursive_mutex> guard(
1817 const size_t num_modules = Module::GetNumberAllocatedModules();
1818 ModuleSP module_sp;
1819 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1820 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1821
1822 if (module) {
1823 if (module->MatchesModuleSpec(module_spec)) {
1824 module_sp = module->shared_from_this();
1825 module_list.AppendIfNeeded(module_sp);
1826 }
1827 }
1828 }
1829 } else {
1830 if (target) {
1831 target->GetImages().FindModules(module_spec, module_list);
1832 const size_t num_matches = module_list.GetSize();
1833
1834 // Not found in our module list for our target, check the main shared
1835 // module list in case it is a extra file used somewhere else
1836 if (num_matches == 0) {
1837 module_spec.GetArchitecture() = target->GetArchitecture();
1838 ModuleList::FindSharedModules(module_spec, module_list);
1839 }
1840 } else {
1841 ModuleList::FindSharedModules(module_spec, module_list);
1842 }
1843 }
1844
1845 return module_list.GetSize() - initial_size;
1846}
1847
1848#pragma mark CommandObjectTargetModulesModuleAutoComplete
1849
1850// A base command object class that can auto complete with module file
1851// paths
1852
1854 : public CommandObjectParsed {
1855public:
1857 const char *name,
1858 const char *help,
1859 const char *syntax,
1860 uint32_t flags = 0)
1861 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1863 }
1864
1866
1867 void
1873};
1874
1875#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1876
1877// A base command object class that can auto complete with module source
1878// file paths
1879
1881 : public CommandObjectParsed {
1882public:
1884 CommandInterpreter &interpreter, const char *name, const char *help,
1885 const char *syntax, uint32_t flags)
1886 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1888 }
1889
1891
1892 void
1898};
1899
1900#pragma mark CommandObjectTargetModulesDumpObjfile
1901
1904public:
1907 interpreter, "target modules dump objfile",
1908 "Dump the object file headers from one or more target modules.",
1909 nullptr, eCommandRequiresTarget) {}
1910
1912
1913protected:
1914 void DoExecute(Args &command, CommandReturnObject &result) override {
1915 Target &target = GetTarget();
1916
1917 size_t num_dumped = 0;
1918 if (command.GetArgumentCount() == 0) {
1919 // Dump all headers for all modules images
1920 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1921 target.GetImages());
1922 if (num_dumped == 0) {
1923 result.AppendError("the target has no associated executable images");
1924 }
1925 } else {
1926 // Find the modules that match the basename or full path.
1927 ModuleList module_list;
1928 const char *arg_cstr;
1929 for (int arg_idx = 0;
1930 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1931 ++arg_idx) {
1932 size_t num_matched =
1933 FindModulesByName(&target, arg_cstr, module_list, true);
1934 if (num_matched == 0) {
1936 "unable to find an image that matches '{0}'", arg_cstr);
1937 }
1938 }
1939 // Dump all the modules we found.
1940 num_dumped =
1941 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1942 }
1943
1944 if (num_dumped > 0) {
1946 } else {
1947 result.AppendError("no matching executable images found");
1948 }
1949 }
1950};
1951
1952#define LLDB_OPTIONS_target_modules_dump_symtab
1953#include "CommandOptions.inc"
1954
1957public:
1960 interpreter, "target modules dump symtab",
1961 "Dump the symbol table from one or more target modules.", nullptr,
1962 eCommandRequiresTarget) {}
1963
1965
1966 Options *GetOptions() override { return &m_options; }
1967
1968 class CommandOptions : public Options {
1969 public:
1970 CommandOptions() = default;
1971
1972 ~CommandOptions() override = default;
1973
1974 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1975 ExecutionContext *execution_context) override {
1976 Status error;
1977 const int short_option = m_getopt_table[option_idx].val;
1978
1979 switch (short_option) {
1980 case 'm':
1981 m_prefer_mangled.SetCurrentValue(true);
1982 m_prefer_mangled.SetOptionWasSet();
1983 break;
1984
1985 case 's':
1987 option_arg, GetDefinitions()[option_idx].enum_values,
1989 break;
1990
1991 default:
1992 llvm_unreachable("Unimplemented option");
1993 }
1994 return error;
1995 }
1996
1997 void OptionParsingStarting(ExecutionContext *execution_context) override {
1999 m_prefer_mangled.Clear();
2000 }
2001
2002 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2003 return llvm::ArrayRef(g_target_modules_dump_symtab_options);
2004 }
2005
2008 };
2009
2010protected:
2011 void DoExecute(Args &command, CommandReturnObject &result) override {
2012 Target &target = GetTarget();
2013 uint32_t num_dumped = 0;
2014 Mangled::NamePreference name_preference =
2015 (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2017
2018 if (command.GetArgumentCount() == 0) {
2019 // Dump all sections for all modules images
2020 const ModuleList &module_list = target.GetImages();
2021 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
2022 const size_t num_modules = module_list.GetSize();
2023 if (num_modules > 0) {
2024 result.GetOutputStream().Format(
2025 "Dumping symbol table for {0} modules.\n", num_modules);
2026 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2027 if (num_dumped > 0) {
2028 result.GetOutputStream().EOL();
2029 result.GetOutputStream().EOL();
2030 }
2032 "Interrupted in dump all symtabs with {0} "
2033 "of {1} dumped.", num_dumped, num_modules))
2034 break;
2035
2036 num_dumped++;
2038 module_sp.get(), m_options.m_sort_order,
2039 name_preference);
2040 }
2041 } else {
2042 result.AppendError("the target has no associated executable images");
2043 return;
2044 }
2045 } else {
2046 // Dump specified images (by basename or fullpath)
2047 const char *arg_cstr;
2048 for (int arg_idx = 0;
2049 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2050 ++arg_idx) {
2051 ModuleList module_list;
2052 const size_t num_matches =
2053 FindModulesByName(&target, arg_cstr, module_list, true);
2054 if (num_matches > 0) {
2055 for (ModuleSP module_sp : module_list.Modules()) {
2056 if (module_sp) {
2057 if (num_dumped > 0) {
2058 result.GetOutputStream().EOL();
2059 result.GetOutputStream().EOL();
2060 }
2062 "Interrupted in dump symtab list with {0} of {1} dumped.",
2063 num_dumped, num_matches))
2064 break;
2065
2066 num_dumped++;
2068 module_sp.get(), m_options.m_sort_order,
2069 name_preference);
2070 }
2071 }
2072 } else
2074 "unable to find an image that matches '{0}'", arg_cstr);
2075 }
2076 }
2077
2078 if (num_dumped > 0)
2080 else {
2081 result.AppendError("no matching executable images found");
2082 }
2083 }
2084
2086};
2087
2088#pragma mark CommandObjectTargetModulesDumpSections
2089
2090// Image section dumping command
2091
2094public:
2097 interpreter, "target modules dump sections",
2098 "Dump the sections from one or more target modules.",
2099 //"target modules dump sections [<file1> ...]")
2100 nullptr, eCommandRequiresTarget) {}
2101
2103
2104protected:
2105 void DoExecute(Args &command, CommandReturnObject &result) override {
2106 Target &target = GetTarget();
2107 uint32_t num_dumped = 0;
2108
2109 if (command.GetArgumentCount() == 0) {
2110 // Dump all sections for all modules images
2111 const size_t num_modules = target.GetImages().GetSize();
2112 if (num_modules == 0) {
2113 result.AppendError("the target has no associated executable images");
2114 return;
2115 }
2116
2117 result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2118 num_modules);
2119 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2121 "Interrupted in dump all sections with {0} of {1} dumped",
2122 image_idx, num_modules))
2123 break;
2124
2125 num_dumped++;
2128 target.GetImages().GetModulePointerAtIndex(image_idx));
2129 }
2130 } else {
2131 // Dump specified images (by basename or fullpath)
2132 const char *arg_cstr;
2133 for (int arg_idx = 0;
2134 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2135 ++arg_idx) {
2136 ModuleList module_list;
2137 const size_t num_matches =
2138 FindModulesByName(&target, arg_cstr, module_list, true);
2139 if (num_matches > 0) {
2140 for (size_t i = 0; i < num_matches; ++i) {
2142 "Interrupted in dump section list with {0} of {1} dumped.",
2143 i, num_matches))
2144 break;
2145
2146 Module *module = module_list.GetModulePointerAtIndex(i);
2147 if (module) {
2148 num_dumped++;
2150 module);
2151 }
2152 }
2153 } else {
2154 // Check the global list
2155 std::lock_guard<std::recursive_mutex> guard(
2157
2159 "unable to find an image that matches '{0}'", arg_cstr);
2160 }
2161 }
2162 }
2163
2164 if (num_dumped > 0)
2166 else {
2167 result.AppendError("no matching executable images found");
2168 }
2169 }
2170};
2171
2173public:
2176 interpreter, "target modules dump pcm-info",
2177 "Dump information about the given clang module (pcm).") {
2178 // Take a single file argument.
2180 }
2181
2183
2184protected:
2185 void DoExecute(Args &command, CommandReturnObject &result) override {
2186 if (command.GetArgumentCount() != 1) {
2187 result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument",
2188 m_cmd_name.c_str());
2189 return;
2190 }
2191
2192 const char *pcm_path = command.GetArgumentAtIndex(0);
2193 const FileSpec pcm_file{pcm_path};
2194
2195 if (pcm_file.GetFileNameExtension() != ".pcm") {
2196 result.AppendError("file must have a .pcm extension");
2197 return;
2198 }
2199
2200 if (!FileSystem::Instance().Exists(pcm_file)) {
2201 result.AppendError("pcm file does not exist");
2202 return;
2203 }
2204
2205 const char *clang_args[] = {"clang", pcm_path};
2206 clang::CompilerInstance compiler(clang::createInvocation(clang_args));
2207 compiler.setVirtualFileSystem(
2208 FileSystem::Instance().GetVirtualFileSystem());
2209 compiler.createDiagnostics();
2210
2211 // Pass empty deleter to not attempt to free memory that was allocated
2212 // outside of the current scope, possibly statically.
2213 std::shared_ptr<llvm::raw_ostream> Out(
2214 &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});
2215 clang::DumpModuleInfoAction dump_module_info(Out);
2216 // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2217 compiler.getPCHContainerOperations()->registerReader(
2218 std::make_unique<clang::ObjectFilePCHContainerReader>());
2219
2220 if (compiler.ExecuteAction(dump_module_info))
2222 }
2223};
2224
2225#pragma mark CommandObjectTargetModulesDumpClangAST
2226
2227// Clang AST dumping command
2228
2231public:
2234 interpreter, "target modules dump ast",
2235 "Dump the clang ast for a given module's symbol file.",
2236 "target modules dump ast [--filter <name>] [<file1> ...]",
2237 eCommandRequiresTarget),
2238 m_filter(LLDB_OPT_SET_1, false, "filter", 'f', 0, eArgTypeName,
2239 "Dump only the decls whose names contain the specified filter "
2240 "string.",
2241 /*default_value=*/"") {
2243 m_option_group.Finalize();
2244 }
2245
2246 Options *GetOptions() override { return &m_option_group; }
2247
2249
2252
2253protected:
2254 void DoExecute(Args &command, CommandReturnObject &result) override {
2255 Target &target = GetTarget();
2256
2257 const ModuleList &module_list = target.GetImages();
2258 const size_t num_modules = module_list.GetSize();
2259 if (num_modules == 0) {
2260 result.AppendError("the target has no associated executable images");
2261 return;
2262 }
2263
2264 llvm::StringRef filter = m_filter.GetOptionValue().GetCurrentValueAsRef();
2265
2266 if (command.GetArgumentCount() == 0) {
2267 // Dump all ASTs for all modules images
2268 result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2269 num_modules);
2270 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2271 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
2272 break;
2273 if (SymbolFile *sf = module_sp->GetSymbolFile())
2274 sf->DumpClangAST(result.GetOutputStream(), filter,
2275 GetCommandInterpreter().GetDebugger().GetUseColor());
2276 }
2278 return;
2279 }
2280
2281 // Dump specified ASTs (by basename or fullpath)
2282 for (const Args::ArgEntry &arg : command.entries()) {
2283 ModuleList module_list;
2284 const size_t num_matches =
2285 FindModulesByName(&target, arg.c_str(), module_list, true);
2286 if (num_matches == 0) {
2287 // Check the global list
2288 std::lock_guard<std::recursive_mutex> guard(
2290
2292 "unable to find an image that matches '{0}'", arg.c_str());
2293 continue;
2294 }
2295
2296 for (size_t i = 0; i < num_matches; ++i) {
2298 "Interrupted in dump clang ast list with {0} of {1} dumped.",
2299 i, num_matches))
2300 break;
2301
2302 Module *m = module_list.GetModulePointerAtIndex(i);
2303 if (SymbolFile *sf = m->GetSymbolFile())
2304 sf->DumpClangAST(result.GetOutputStream(), filter,
2305 GetCommandInterpreter().GetDebugger().GetUseColor());
2306 }
2307 }
2309 }
2310};
2311
2312#pragma mark CommandObjectTargetModulesDumpSymfile
2313
2314// Image debug symbol dumping command
2315
2318public:
2321 interpreter, "target modules dump symfile",
2322 "Dump the debug symbol file for one or more target modules.",
2323 //"target modules dump symfile [<file1> ...]")
2324 nullptr, eCommandRequiresTarget) {}
2325
2327
2328protected:
2329 void DoExecute(Args &command, CommandReturnObject &result) override {
2330 Target &target = GetTarget();
2331 uint32_t num_dumped = 0;
2332
2333 if (command.GetArgumentCount() == 0) {
2334 // Dump all sections for all modules images
2335 const ModuleList &target_modules = target.GetImages();
2336 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2337 const size_t num_modules = target_modules.GetSize();
2338 if (num_modules == 0) {
2339 result.AppendError("the target has no associated executable images");
2340 return;
2341 }
2342 result.GetOutputStream().Format(
2343 "Dumping debug symbols for {0} modules.\n", num_modules);
2344 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2345 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2346 "debug symbols with {0} of {1} modules dumped",
2347 num_dumped, num_modules))
2348 break;
2349
2350 if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2351 num_dumped++;
2352 }
2353 } else {
2354 // Dump specified images (by basename or fullpath)
2355 const char *arg_cstr;
2356 for (int arg_idx = 0;
2357 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2358 ++arg_idx) {
2359 ModuleList module_list;
2360 const size_t num_matches =
2361 FindModulesByName(&target, arg_cstr, module_list, true);
2362 if (num_matches > 0) {
2363 for (size_t i = 0; i < num_matches; ++i) {
2364 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2365 "of {1} requested modules",
2366 i, num_matches))
2367 break;
2368 Module *module = module_list.GetModulePointerAtIndex(i);
2369 if (module) {
2370 if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2371 num_dumped++;
2372 }
2373 }
2374 } else
2376 "unable to find an image that matches '{0}'", arg_cstr);
2377 }
2378 }
2379
2380 if (num_dumped > 0)
2382 else {
2383 result.AppendError("no matching executable images found");
2384 }
2385 }
2386};
2387
2388#pragma mark CommandObjectTargetModulesDumpLineTable
2389#define LLDB_OPTIONS_target_modules_dump
2390#include "CommandOptions.inc"
2391
2392// Image debug line table dumping command
2393
2396public:
2399 interpreter, "target modules dump line-table",
2400 "Dump the line table for one or more compilation units.", nullptr,
2401 eCommandRequiresTarget) {}
2402
2404
2405 Options *GetOptions() override { return &m_options; }
2406
2407protected:
2408 void DoExecute(Args &command, CommandReturnObject &result) override {
2409 Target *target = m_exe_ctx.GetTargetPtr();
2410 uint32_t total_num_dumped = 0;
2411
2412 if (command.GetArgumentCount() == 0) {
2413 result.AppendError("file option must be specified");
2414 return;
2415 } else {
2416 // Dump specified images (by basename or fullpath)
2417 const char *arg_cstr;
2418 for (int arg_idx = 0;
2419 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2420 ++arg_idx) {
2421 FileSpec file_spec(arg_cstr);
2422
2423 const ModuleList &target_modules = target->GetImages();
2424 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2425 size_t num_modules = target_modules.GetSize();
2426 if (num_modules > 0) {
2427 uint32_t num_dumped = 0;
2428 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2430 "Interrupted in dump all line tables with "
2431 "{0} of {1} dumped", num_dumped,
2432 num_modules))
2433 break;
2434
2436 m_interpreter, result.GetOutputStream(), module_sp.get(),
2437 file_spec,
2440 num_dumped++;
2441 }
2442 if (num_dumped == 0)
2443 result.AppendWarningWithFormatv("no source filenames matched '{0}'",
2444 arg_cstr);
2445 else
2446 total_num_dumped += num_dumped;
2447 }
2448 }
2449 }
2450
2451 if (total_num_dumped > 0)
2453 else {
2454 result.AppendError("no source filenames matched any command arguments");
2455 }
2456 }
2457
2458 class CommandOptions : public Options {
2459 public:
2461
2462 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2463 ExecutionContext *execution_context) override {
2464 assert(option_idx == 0 && "We only have one option.");
2465 m_verbose = true;
2466
2467 return Status();
2468 }
2469
2470 void OptionParsingStarting(ExecutionContext *execution_context) override {
2471 m_verbose = false;
2472 }
2473
2474 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2475 return llvm::ArrayRef(g_target_modules_dump_options);
2476 }
2477
2479 };
2480
2482};
2483
2484#pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2485#define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2486#include "CommandOptions.inc"
2487
2488// Image debug separate debug info dumping command
2489
2492public:
2494 CommandInterpreter &interpreter)
2496 interpreter, "target modules dump separate-debug-info",
2497 "List the separate debug info symbol files for one or more target "
2498 "modules.",
2499 nullptr, eCommandRequiresTarget) {}
2500
2502
2503 Options *GetOptions() override { return &m_options; }
2504
2505 class CommandOptions : public Options {
2506 public:
2507 CommandOptions() = default;
2508
2509 ~CommandOptions() override = default;
2510
2511 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2512 ExecutionContext *execution_context) override {
2513 Status error;
2514 const int short_option = m_getopt_table[option_idx].val;
2515
2516 switch (short_option) {
2517 case 'f':
2518 m_load_all_debug_info.SetCurrentValue(true);
2519 m_load_all_debug_info.SetOptionWasSet();
2520 break;
2521 case 'j':
2522 m_json.SetCurrentValue(true);
2523 m_json.SetOptionWasSet();
2524 break;
2525 case 'e':
2526 m_errors_only.SetCurrentValue(true);
2527 m_errors_only.SetOptionWasSet();
2528 break;
2529 default:
2530 llvm_unreachable("Unimplemented option");
2531 }
2532 return error;
2533 }
2534
2535 void OptionParsingStarting(ExecutionContext *execution_context) override {
2536 m_json.Clear();
2537 m_errors_only.Clear();
2538 m_load_all_debug_info.Clear();
2539 }
2540
2541 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2542 return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options);
2543 }
2544
2548 };
2549
2550protected:
2551 void DoExecute(Args &command, CommandReturnObject &result) override {
2552 Target &target = GetTarget();
2553 uint32_t num_dumped = 0;
2554
2555 StructuredData::Array separate_debug_info_lists_by_module;
2556 if (command.GetArgumentCount() == 0) {
2557 // Dump all sections for all modules images
2558 const ModuleList &target_modules = target.GetImages();
2559 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2560 const size_t num_modules = target_modules.GetSize();
2561 if (num_modules == 0) {
2562 result.AppendError("the target has no associated executable images");
2563 return;
2564 }
2565 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2567 GetDebugger(),
2568 "Interrupted in dumping all "
2569 "separate debug info with {0} of {1} modules dumped",
2570 num_dumped, num_modules))
2571 break;
2572
2573 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2574 module_sp.get(),
2575 bool(m_options.m_errors_only),
2576 bool(m_options.m_load_all_debug_info)))
2577 num_dumped++;
2578 }
2579 } else {
2580 // Dump specified images (by basename or fullpath)
2581 const char *arg_cstr;
2582 for (int arg_idx = 0;
2583 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2584 ++arg_idx) {
2585 ModuleList module_list;
2586 const size_t num_matches =
2587 FindModulesByName(&target, arg_cstr, module_list, true);
2588 if (num_matches > 0) {
2589 for (size_t i = 0; i < num_matches; ++i) {
2591 "Interrupted dumping {0} "
2592 "of {1} requested modules",
2593 i, num_matches))
2594 break;
2595 Module *module = module_list.GetModulePointerAtIndex(i);
2596 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2597 module, bool(m_options.m_errors_only),
2598 bool(m_options.m_load_all_debug_info)))
2599 num_dumped++;
2600 }
2601 } else
2603 "unable to find an image that matches '{0}'", arg_cstr);
2604 }
2605 }
2606
2607 if (num_dumped > 0) {
2608 Stream &strm = result.GetOutputStream();
2609 // Display the debug info files in some format.
2610 if (m_options.m_json) {
2611 // JSON format
2612 separate_debug_info_lists_by_module.Dump(strm,
2613 /*pretty_print=*/true);
2614 } else {
2615 // Human-readable table format
2616 separate_debug_info_lists_by_module.ForEach(
2617 [&result, &strm](StructuredData::Object *obj) {
2618 if (!obj) {
2619 return false;
2620 }
2621
2622 // Each item in `separate_debug_info_lists_by_module` should be a
2623 // valid structured data dictionary.
2624 StructuredData::Dictionary *separate_debug_info_list =
2625 obj->GetAsDictionary();
2626 if (!separate_debug_info_list) {
2627 return false;
2628 }
2629
2630 llvm::StringRef type;
2631 llvm::StringRef symfile;
2632 StructuredData::Array *files;
2633 if (!(separate_debug_info_list->GetValueForKeyAsString("type",
2634 type) &&
2635 separate_debug_info_list->GetValueForKeyAsString("symfile",
2636 symfile) &&
2637 separate_debug_info_list->GetValueForKeyAsArray(
2638 "separate-debug-info-files", files))) {
2639 assert(false);
2640 }
2641
2642 strm << "Symbol file: " << symfile;
2643 strm.EOL();
2644 strm << "Type: \"" << type << "\"";
2645 strm.EOL();
2646 if (type == "dwo") {
2647 DumpDwoFilesTable(strm, *files);
2648 } else if (type == "oso") {
2649 DumpOsoFilesTable(strm, *files);
2650 } else {
2652 "found unsupported debug info type '{0}'", type);
2653 }
2654 return true;
2655 });
2656 }
2658 } else {
2659 result.AppendError("no matching executable images found");
2660 }
2661 }
2662
2664};
2665
2666#pragma mark CommandObjectTargetModulesDump
2667
2668// Dump multi-word command for target modules
2669
2671public:
2672 // Constructors and Destructors
2675 interpreter, "target modules dump",
2676 "Commands for dumping information about one or more target "
2677 "modules.",
2678 "target modules dump "
2679 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2680 "debug-info] "
2681 "[<file1> <file2> ...]") {
2682 LoadSubCommand("objfile",
2684 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2686 "symtab",
2688 LoadSubCommand("sections",
2690 interpreter)));
2691 LoadSubCommand("symfile",
2693 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2695 "ast", CommandObjectSP(
2696 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2697 LoadSubCommand("line-table",
2699 interpreter)));
2701 "pcm-info",
2704 LoadSubCommand("separate-debug-info",
2707 interpreter)));
2708 }
2709
2711};
2712
2714public:
2716 : CommandObjectParsed(interpreter, "target modules add",
2717 "Add a new module to the current target's modules.",
2718 "target modules add [<module>]",
2719 eCommandRequiresTarget),
2720 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2722 "Fullpath to a stand alone debug "
2723 "symbols file for when debug symbols "
2724 "are not in the executable.") {
2728 m_option_group.Finalize();
2730 }
2731
2733
2734 Options *GetOptions() override { return &m_option_group; }
2735
2736protected:
2740
2741 void DoExecute(Args &args, CommandReturnObject &result) override {
2742 Target &target = GetTarget();
2743 bool flush = false;
2744
2745 const size_t argc = args.GetArgumentCount();
2746 if (argc == 0) {
2747 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2748 // We are given a UUID only, go locate the file
2749 ModuleSpec module_spec;
2750 module_spec.GetUUID() =
2751 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2752 if (m_symbol_file.GetOptionValue().OptionWasSet())
2753 module_spec.GetSymbolFileSpec() =
2754 m_symbol_file.GetOptionValue().GetCurrentValue();
2755 Status error;
2757 ModuleSP module_sp(
2758 target.GetOrCreateModule(module_spec, true /* notify */));
2759 if (module_sp) {
2761 return;
2762 } else {
2763 StreamString strm;
2764 module_spec.GetUUID().Dump(strm);
2765 if (module_spec.GetFileSpec()) {
2766 if (module_spec.GetSymbolFileSpec()) {
2767 result.AppendErrorWithFormat(
2768 "Unable to create the executable or symbol file with "
2769 "UUID %s with path %s and symbol file %s",
2770 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2771 module_spec.GetSymbolFileSpec().GetPath().c_str());
2772 } else {
2773 result.AppendErrorWithFormat(
2774 "Unable to create the executable or symbol file with "
2775 "UUID %s with path %s",
2776 strm.GetData(),
2777 module_spec.GetFileSpec().GetPath().c_str());
2778 }
2779 } else {
2780 result.AppendErrorWithFormat("Unable to create the executable "
2781 "or symbol file with UUID %s",
2782 strm.GetData());
2783 }
2784 return;
2785 }
2786 } else {
2787 StreamString strm;
2788 module_spec.GetUUID().Dump(strm);
2789 result.AppendErrorWithFormat(
2790 "Unable to locate the executable or symbol file with UUID %s",
2791 strm.GetData());
2792 result.SetError(std::move(error));
2793 return;
2794 }
2795 } else {
2796 result.AppendError(
2797 "one or more executable image paths must be specified");
2798 return;
2799 }
2800 } else {
2801 for (auto &entry : args.entries()) {
2802 if (entry.ref().empty())
2803 continue;
2804
2805 FileSpec file_spec(entry.ref());
2806 if (FileSystem::Instance().Exists(file_spec)) {
2807 ModuleSpec module_spec(file_spec);
2808 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2809 module_spec.GetUUID() =
2810 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2811 if (m_symbol_file.GetOptionValue().OptionWasSet())
2812 module_spec.GetSymbolFileSpec() =
2813 m_symbol_file.GetOptionValue().GetCurrentValue();
2814 if (!module_spec.GetArchitecture().IsValid())
2815 module_spec.GetArchitecture() = target.GetArchitecture();
2816 Status error;
2817 ModuleSP module_sp(
2818 target.GetOrCreateModule(module_spec, true /* notify */, &error));
2819 if (!module_sp) {
2820 const char *error_cstr = error.AsCString();
2821 if (error_cstr)
2822 result.AppendError(error_cstr);
2823 else
2824 result.AppendErrorWithFormat("unsupported module: %s",
2825 entry.c_str());
2826 return;
2827 } else {
2828 flush = true;
2829 }
2831 } else {
2832 std::string resolved_path = file_spec.GetPath();
2833 if (resolved_path != entry.ref()) {
2834 result.AppendErrorWithFormat(
2835 "invalid module path '%s' with resolved path '%s'",
2836 entry.ref().str().c_str(), resolved_path.c_str());
2837 break;
2838 }
2839 result.AppendErrorWithFormat("invalid module path '%s'",
2840 entry.c_str());
2841 break;
2842 }
2843 }
2844 }
2845
2846 if (flush) {
2847 ProcessSP process = target.GetProcessSP();
2848 if (process)
2849 process->Flush();
2850 }
2851 }
2852};
2853
2856public:
2859 interpreter, "target modules load",
2860 "Set the load addresses for one or more sections in a target "
2861 "module.",
2862 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2863 "<address> [<sect-name> <address> ....]",
2864 eCommandRequiresTarget),
2865 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2866 "Fullpath or basename for module to load.", ""),
2867 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2868 "Write file contents to the memory.", false, true),
2869 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2870 "Set PC to the entry point."
2871 " Only applicable with '--load' option.",
2872 false, true),
2873 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2874 "Set the load address for all sections to be the "
2875 "virtual address in the file plus the offset.",
2876 0) {
2883 m_option_group.Finalize();
2884 }
2885
2887
2888 Options *GetOptions() override { return &m_option_group; }
2889
2890protected:
2891 void DoExecute(Args &args, CommandReturnObject &result) override {
2892 Target &target = GetTarget();
2893 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2894 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2895
2896 const size_t argc = args.GetArgumentCount();
2897 ModuleSpec module_spec;
2898 bool search_using_module_spec = false;
2899
2900 // Allow "load" option to work without --file or --uuid option.
2901 if (load) {
2902 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2903 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2904 ModuleList &module_list = target.GetImages();
2905 if (module_list.GetSize() == 1) {
2906 search_using_module_spec = true;
2907 module_spec.GetFileSpec() =
2908 module_list.GetModuleAtIndex(0)->GetFileSpec();
2909 }
2910 }
2911 }
2912
2913 if (m_file_option.GetOptionValue().OptionWasSet()) {
2914 search_using_module_spec = true;
2915 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2916 const bool use_global_module_list = true;
2917 ModuleList module_list;
2918 const size_t num_matches = FindModulesByName(
2919 &target, arg_cstr, module_list, use_global_module_list);
2920 if (num_matches == 1) {
2921 module_spec.GetFileSpec() =
2922 module_list.GetModuleAtIndex(0)->GetFileSpec();
2923 } else if (num_matches > 1) {
2924 search_using_module_spec = false;
2925 result.AppendErrorWithFormat("more than 1 module matched by name '%s'",
2926 arg_cstr);
2927 } else {
2928 search_using_module_spec = false;
2929 result.AppendErrorWithFormat("no object file for module '%s'",
2930 arg_cstr);
2931 }
2932 }
2933
2934 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2935 search_using_module_spec = true;
2936 module_spec.GetUUID() =
2937 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2938 }
2939
2940 if (search_using_module_spec) {
2941 ModuleList matching_modules;
2942 target.GetImages().FindModules(module_spec, matching_modules);
2943 const size_t num_matches = matching_modules.GetSize();
2944
2945 char path[PATH_MAX];
2946 if (num_matches == 1) {
2947 Module *module = matching_modules.GetModulePointerAtIndex(0);
2948 if (module) {
2949 ObjectFile *objfile = module->GetObjectFile();
2950 if (objfile) {
2951 SectionList *section_list = module->GetSectionList();
2952 if (section_list) {
2953 bool changed = false;
2954 if (argc == 0) {
2955 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2956 const addr_t slide =
2957 m_slide_option.GetOptionValue().GetCurrentValue();
2958 const bool slide_is_offset = true;
2959 module->SetLoadAddress(target, slide, slide_is_offset,
2960 changed);
2961 } else {
2962 result.AppendError("one or more section name + load "
2963 "address pair must be specified");
2964 return;
2965 }
2966 } else {
2967 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2968 result.AppendError("The \"--slide <offset>\" option can't "
2969 "be used in conjunction with setting "
2970 "section load addresses.\n");
2971 return;
2972 }
2973
2974 for (size_t i = 0; i < argc; i += 2) {
2975 const char *sect_name = args.GetArgumentAtIndex(i);
2976 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2977 if (sect_name && load_addr_cstr) {
2978 ConstString const_sect_name(sect_name);
2979 addr_t load_addr;
2980 if (llvm::to_integer(load_addr_cstr, load_addr)) {
2981 SectionSP section_sp(
2982 section_list->FindSectionByName(const_sect_name));
2983 if (section_sp) {
2984 if (section_sp->IsThreadSpecific()) {
2985 result.AppendErrorWithFormat(
2986 "thread specific sections are not yet "
2987 "supported (section '%s')",
2988 sect_name);
2989 break;
2990 } else {
2991 if (target.SetSectionLoadAddress(section_sp,
2992 load_addr))
2993 changed = true;
2995 "section '{0}' loaded at {1:x}", sect_name,
2996 load_addr);
2997 }
2998 } else {
2999 result.AppendErrorWithFormat("no section found that "
3000 "matches the section "
3001 "name '%s'",
3002 sect_name);
3003 break;
3004 }
3005 } else {
3006 result.AppendErrorWithFormat(
3007 "invalid load address string '%s'", load_addr_cstr);
3008 break;
3009 }
3010 } else {
3011 if (sect_name)
3012 result.AppendError("section names must be followed by "
3013 "a load address.\n");
3014 else
3015 result.AppendError("one or more section name + load "
3016 "address pair must be specified.\n");
3017 break;
3018 }
3019 }
3020 }
3021
3022 if (changed) {
3023 target.ModulesDidLoad(matching_modules);
3024 Process *process = m_exe_ctx.GetProcessPtr();
3025 if (process)
3026 process->Flush();
3027 }
3028 if (load) {
3029 ProcessSP process = target.CalculateProcess();
3030 Address file_entry = objfile->GetEntryPointAddress();
3031 if (!process) {
3032 result.AppendError("No process");
3033 return;
3034 }
3035 if (set_pc && !file_entry.IsValid()) {
3036 result.AppendError("No entry address in object file");
3037 return;
3038 }
3039 std::vector<ObjectFile::LoadableData> loadables(
3040 objfile->GetLoadableData(target));
3041 if (loadables.size() == 0) {
3042 result.AppendError("No loadable sections");
3043 return;
3044 }
3045 Status error = process->WriteObjectFile(std::move(loadables));
3046 if (error.Fail()) {
3047 result.AppendError(error.AsCString());
3048 return;
3049 }
3050 if (set_pc) {
3051 ThreadList &thread_list = process->GetThreadList();
3052 RegisterContextSP reg_context(
3053 thread_list.GetSelectedThread()->GetRegisterContext());
3054 addr_t file_entry_addr = file_entry.GetLoadAddress(&target);
3055 if (!reg_context->SetPC(file_entry_addr)) {
3056 result.AppendErrorWithFormat("failed to set PC value to "
3057 "0x%" PRIx64,
3058 file_entry_addr);
3059 }
3060 }
3061 }
3062 } else {
3063 module->GetFileSpec().GetPath(path, sizeof(path));
3064 result.AppendErrorWithFormat("no sections in object file '%s'",
3065 path);
3066 }
3067 } else {
3068 module->GetFileSpec().GetPath(path, sizeof(path));
3069 result.AppendErrorWithFormat("no object file for module '%s'",
3070 path);
3071 }
3072 } else {
3073 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3074 if (module_spec_file) {
3075 module_spec_file->GetPath(path, sizeof(path));
3076 result.AppendErrorWithFormat("invalid module '%s'", path);
3077 } else
3078 result.AppendError("no module spec");
3079 }
3080 } else {
3081 std::string uuid_str;
3082
3083 if (module_spec.GetFileSpec())
3084 module_spec.GetFileSpec().GetPath(path, sizeof(path));
3085 else
3086 path[0] = '\0';
3087
3088 if (module_spec.GetUUIDPtr())
3089 uuid_str = module_spec.GetUUID().GetAsString();
3090 if (num_matches > 1) {
3091 result.AppendErrorWithFormat(
3092 "multiple modules match%s%s%s%s:", path[0] ? " file=" : "", path,
3093 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
3094 for (size_t i = 0; i < num_matches; ++i) {
3095 if (matching_modules.GetModulePointerAtIndex(i)
3096 ->GetFileSpec()
3097 .GetPath(path, sizeof(path)))
3098 result.AppendMessageWithFormatv("{0}", path);
3099 }
3100 } else {
3101 result.AppendErrorWithFormat(
3102 "no modules were found that match%s%s%s%s",
3103 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
3104 uuid_str.c_str());
3105 }
3106 }
3107 } else {
3108 result.AppendError("either the \"--file <module>\" or the \"--uuid "
3109 "<uuid>\" option must be specified.\n");
3110 }
3111 if (result.GetStatus() != eReturnStatusFailed)
3113 }
3114
3121};
3122
3123#pragma mark CommandObjectTargetModulesList
3124// List images with associated information
3125#define LLDB_OPTIONS_target_modules_list
3126#include "CommandOptions.inc"
3127
3129public:
3130 class CommandOptions : public Options {
3131 public:
3132 CommandOptions() = default;
3133
3134 ~CommandOptions() override = default;
3135
3136 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3137 ExecutionContext *execution_context) override {
3138 Status error;
3139
3140 const int short_option = m_getopt_table[option_idx].val;
3141 if (short_option == 'g') {
3143 } else if (short_option == 'a') {
3145 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3146 } else {
3147 unsigned long width = 0;
3148 option_arg.getAsInteger(0, width);
3149 m_format_array.push_back(std::make_pair(short_option, width));
3150 }
3151 return error;
3152 }
3153
3154 void OptionParsingStarting(ExecutionContext *execution_context) override {
3155 m_format_array.clear();
3158 }
3159
3160 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3161 return llvm::ArrayRef(g_target_modules_list_options);
3162 }
3163
3164 // Instance variables to hold the values for command options.
3165 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3169 };
3170
3173 interpreter, "target modules list",
3174 "List current executable and dependent shared library images.") {
3176 }
3177
3179
3180 Options *GetOptions() override { return &m_options; }
3181
3182protected:
3183 void DoExecute(Args &command, CommandReturnObject &result) override {
3184 Target &target = GetTarget();
3185 const bool use_global_module_list = m_options.m_use_global_module_list;
3186 // Define a local module list here to ensure it lives longer than any
3187 // "locker" object which might lock its contents below (through the
3188 // "module_list_ptr" variable).
3189 ModuleList module_list;
3190 // Dump all sections for all modules images
3191 Stream &strm = result.GetOutputStream();
3192
3193 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3194 Address module_address;
3195 if (module_address.SetLoadAddress(m_options.m_module_addr, &target)) {
3196 ModuleSP module_sp(module_address.GetModule());
3197 if (module_sp) {
3198 PrintModule(target, module_sp.get(), 0, strm);
3200 } else {
3201 result.AppendErrorWithFormat(
3202 "Couldn't find module matching address: 0x%" PRIx64,
3203 m_options.m_module_addr);
3204 }
3205 } else {
3206 result.AppendErrorWithFormat(
3207 "Couldn't find module containing address: 0x%" PRIx64,
3208 m_options.m_module_addr);
3209 }
3210 return;
3211 }
3212
3213 size_t num_modules = 0;
3214
3215 // This locker will be locked on the mutex in module_list_ptr if it is
3216 // non-nullptr. Otherwise it will lock the
3217 // AllocationModuleCollectionMutex when accessing the global module list
3218 // directly.
3219 std::unique_lock<std::recursive_mutex> guard(
3221
3222 const ModuleList *module_list_ptr = nullptr;
3223 const size_t argc = command.GetArgumentCount();
3224 if (argc == 0) {
3225 if (use_global_module_list) {
3226 guard.lock();
3227 num_modules = Module::GetNumberAllocatedModules();
3228 } else {
3229 module_list_ptr = &target.GetImages();
3230 }
3231 } else {
3232 for (const Args::ArgEntry &arg : command) {
3233 // Dump specified images (by basename or fullpath)
3234 const size_t num_matches = FindModulesByName(
3235 &target, arg.c_str(), module_list, use_global_module_list);
3236 if (num_matches == 0) {
3237 if (argc == 1) {
3238 result.AppendErrorWithFormat("no modules found that match '%s'",
3239 arg.c_str());
3240 return;
3241 }
3242 }
3243 }
3244
3245 module_list_ptr = &module_list;
3246 }
3247
3248 std::unique_lock<std::recursive_mutex> lock;
3249 if (module_list_ptr != nullptr) {
3250 lock =
3251 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3252
3253 num_modules = module_list_ptr->GetSize();
3254 }
3255
3256 if (num_modules > 0) {
3257 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3258 ModuleSP module_sp;
3259 Module *module;
3260 if (module_list_ptr) {
3261 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3262 module = module_sp.get();
3263 } else {
3264 module = Module::GetAllocatedModuleAtIndex(image_idx);
3265 module_sp = module->shared_from_this();
3266 }
3267
3268 const size_t indent = strm.Printf("[%3u] ", image_idx);
3269 PrintModule(target, module, indent, strm);
3270 }
3272 } else {
3273 if (argc) {
3274 if (use_global_module_list)
3275 result.AppendError(
3276 "the global module list has no matching modules");
3277 else
3278 result.AppendError("the target has no matching modules");
3279 } else {
3280 if (use_global_module_list)
3281 result.AppendError("the global module list is empty");
3282 else
3283 result.AppendError(
3284 "the target has no associated executable images");
3285 }
3286 return;
3287 }
3288 }
3289
3290 void PrintModule(Target &target, Module *module, int indent, Stream &strm) {
3291 if (module == nullptr) {
3292 strm.PutCString("Null module");
3293 return;
3294 }
3295
3296 bool dump_object_name = false;
3297 if (m_options.m_format_array.empty()) {
3298 m_options.m_format_array.push_back(std::make_pair('u', 0));
3299 m_options.m_format_array.push_back(std::make_pair('h', 0));
3300 m_options.m_format_array.push_back(std::make_pair('f', 0));
3301 m_options.m_format_array.push_back(std::make_pair('S', 0));
3302 }
3303 const size_t num_entries = m_options.m_format_array.size();
3304 bool print_space = false;
3305 for (size_t i = 0; i < num_entries; ++i) {
3306 if (print_space)
3307 strm.PutChar(' ');
3308 print_space = true;
3309 const char format_char = m_options.m_format_array[i].first;
3310 uint32_t width = m_options.m_format_array[i].second;
3311 switch (format_char) {
3312 case 'A':
3313 DumpModuleArchitecture(strm, module, false, width);
3314 break;
3315
3316 case 't':
3317 DumpModuleArchitecture(strm, module, true, width);
3318 break;
3319
3320 case 'f':
3321 DumpFullpath(strm, &module->GetFileSpec(), width);
3322 dump_object_name = true;
3323 break;
3324
3325 case 'd':
3326 DumpDirectory(strm, &module->GetFileSpec(), width);
3327 break;
3328
3329 case 'b':
3330 DumpBasename(strm, &module->GetFileSpec(), width);
3331 dump_object_name = true;
3332 break;
3333
3334 case 'h':
3335 case 'o':
3336 // Image header address
3337 {
3338 uint32_t addr_nibble_width =
3339 target.GetArchitecture().GetAddressByteSize() * 2;
3340
3341 ObjectFile *objfile = module->GetObjectFile();
3342 if (objfile) {
3343 Address base_addr(objfile->GetBaseAddress());
3344 if (base_addr.IsValid()) {
3345 if (target.HasLoadedSections()) {
3346 lldb::addr_t load_addr = base_addr.GetLoadAddress(&target);
3347 if (load_addr == LLDB_INVALID_ADDRESS) {
3348 base_addr.Dump(&strm, &target,
3351 } else {
3352 if (format_char == 'o') {
3353 // Show the offset of slide for the image
3354 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3355 addr_nibble_width,
3356 load_addr - base_addr.GetFileAddress());
3357 } else {
3358 // Show the load address of the image
3359 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3360 addr_nibble_width, load_addr);
3361 }
3362 }
3363 break;
3364 }
3365 // The address was valid, but the image isn't loaded, output the
3366 // address in an appropriate format
3367 base_addr.Dump(&strm, &target, Address::DumpStyleFileAddress);
3368 break;
3369 }
3370 }
3371 strm.Printf("%*s", addr_nibble_width + 2, "");
3372 }
3373 break;
3374
3375 case 'r': {
3376 size_t ref_count = 0;
3377 char in_shared_cache = 'Y';
3378
3379 ModuleSP module_sp(module->shared_from_this());
3380 if (!ModuleList::ModuleIsInCache(module))
3381 in_shared_cache = 'N';
3382 if (module_sp) {
3383 // Take one away to make sure we don't count our local "module_sp"
3384 ref_count = module_sp.use_count() - 1;
3385 }
3386 if (width)
3387 strm.Printf("{%c %*" PRIu64 "}", in_shared_cache, width, (uint64_t)ref_count);
3388 else
3389 strm.Printf("{%c %" PRIu64 "}", in_shared_cache, (uint64_t)ref_count);
3390 } break;
3391
3392 case 's':
3393 case 'S': {
3394 if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3395 const FileSpec symfile_spec =
3396 symbol_file->GetObjectFile()->GetFileSpec();
3397 if (format_char == 'S') {
3398 // Dump symbol file only if different from module file
3399 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3400 print_space = false;
3401 break;
3402 }
3403 // Add a newline and indent past the index
3404 strm.Printf("\n%*s", indent, "");
3405 }
3406 DumpFullpath(strm, &symfile_spec, width);
3407 dump_object_name = true;
3408 break;
3409 }
3410 strm.Printf("%.*s", width, "<NONE>");
3411 } break;
3412
3413 case 'm':
3414 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3415 llvm::AlignStyle::Left, width));
3416 break;
3417
3418 case 'p':
3419 strm.Printf("%p", static_cast<void *>(module));
3420 break;
3421
3422 case 'u':
3423 DumpModuleUUID(strm, module);
3424 break;
3425
3426 default:
3427 break;
3428 }
3429 }
3430 if (dump_object_name) {
3431 const char *object_name = module->GetObjectName().GetCString();
3432 if (object_name)
3433 strm.Printf("(%s)", object_name);
3434 }
3435 strm.EOL();
3436 }
3437
3439};
3440
3441#pragma mark CommandObjectTargetModulesShowUnwind
3442
3443// Lookup unwind information in images
3444#define LLDB_OPTIONS_target_modules_show_unwind
3445#include "CommandOptions.inc"
3446
3448public:
3449 enum {
3456 };
3457
3458 class CommandOptions : public Options {
3459 public:
3460 CommandOptions() = default;
3461
3462 ~CommandOptions() override = default;
3463
3464 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3465 ExecutionContext *execution_context) override {
3466 Status error;
3467
3468 const int short_option = m_getopt_table[option_idx].val;
3469
3470 switch (short_option) {
3471 case 'a': {
3472 m_str = std::string(option_arg);
3474 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3478 "invalid address string '%s'", option_arg.str().c_str());
3479 break;
3480 }
3481
3482 case 'n':
3483 m_str = std::string(option_arg);
3485 break;
3486
3487 case 'c':
3488 bool value, success;
3489 value = OptionArgParser::ToBoolean(option_arg, false, &success);
3490 if (success) {
3491 m_cached = value;
3492 } else {
3494 "invalid boolean value '{}' passed for -c option", option_arg);
3495 }
3496 break;
3497
3498 default:
3499 llvm_unreachable("Unimplemented option");
3500 }
3501
3502 return error;
3503 }
3504
3505 void OptionParsingStarting(ExecutionContext *execution_context) override {
3507 m_str.clear();
3509 m_cached = false;
3510 }
3511
3512 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3513 return llvm::ArrayRef(g_target_modules_show_unwind_options);
3514 }
3515
3516 // Instance variables to hold the values for command options.
3517
3518 int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3519 // parsing options
3520 std::string m_str; // Holds name lookup
3521 lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3522 bool m_cached = true;
3523 };
3524
3527 interpreter, "target modules show-unwind",
3528 "Show synthesized unwind instructions for a function.", nullptr,
3529 eCommandRequiresTarget | eCommandRequiresProcess |
3530 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3531
3533
3534 Options *GetOptions() override { return &m_options; }
3535
3536protected:
3537 void DoExecute(Args &command, CommandReturnObject &result) override {
3538 Target *target = m_exe_ctx.GetTargetPtr();
3539 Process *process = m_exe_ctx.GetProcessPtr();
3540 ABI *abi = nullptr;
3541 if (process)
3542 abi = process->GetABI().get();
3543
3544 if (process == nullptr) {
3545 result.AppendError(
3546 "You must have a process running to use this command.");
3547 return;
3548 }
3549
3550 ThreadList threads(process->GetThreadList());
3551 if (threads.GetSize() == 0) {
3552 result.AppendError("the process must be paused to use this command");
3553 return;
3554 }
3555
3556 ThreadSP thread(threads.GetThreadAtIndex(0));
3557 if (!thread) {
3558 result.AppendError("the process must be paused to use this command");
3559 return;
3560 }
3561
3562 SymbolContextList sc_list;
3563
3564 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3565 ConstString function_name(m_options.m_str.c_str());
3566 ModuleFunctionSearchOptions function_options;
3567 function_options.include_symbols = true;
3568 function_options.include_inlines = false;
3569 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3570 function_options, sc_list);
3571 } else if (m_options.m_type == eLookupTypeAddress && target) {
3572 Address addr;
3573 if (target->ResolveLoadAddress(m_options.m_addr, addr)) {
3574 SymbolContext sc;
3575 ModuleSP module_sp(addr.GetModule());
3576 module_sp->ResolveSymbolContextForAddress(addr,
3577 eSymbolContextEverything, sc);
3578 if (sc.function || sc.symbol) {
3579 sc_list.Append(sc);
3580 }
3581 }
3582 } else {
3583 result.AppendError(
3584 "address-expression or function name option must be specified.");
3585 return;
3586 }
3587
3588 if (sc_list.GetSize() == 0) {
3589 result.AppendErrorWithFormat("no unwind data found that matches '%s'",
3590 m_options.m_str.c_str());
3591 return;
3592 }
3593
3594 for (const SymbolContext &sc : sc_list) {
3595 if (sc.symbol == nullptr && sc.function == nullptr)
3596 continue;
3597 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3598 continue;
3599 Address addr = sc.GetFunctionOrSymbolAddress();
3600 if (!addr.IsValid())
3601 continue;
3602 ConstString funcname(sc.GetFunctionName());
3603 if (funcname.IsEmpty())
3604 continue;
3605 addr_t start_addr = addr.GetLoadAddress(target);
3606 if (abi)
3607 start_addr = abi->FixCodeAddress(start_addr);
3608
3609 UnwindTable &uw_table = sc.module_sp->GetUnwindTable();
3610 FuncUnwindersSP func_unwinders_sp =
3611 m_options.m_cached
3612 ? uw_table.GetFuncUnwindersContainingAddress(Address(start_addr),
3613 sc)
3615 Address(start_addr), sc);
3616 if (!func_unwinders_sp)
3617 continue;
3618
3619 result.GetOutputStream().Format(
3620 "UNWIND PLANS for {0}`{1} (start addr {2:x})\n",
3621 sc.module_sp->GetPlatformFileSpec().GetFilename(), funcname,
3622 start_addr);
3623
3624 Args args;
3626 size_t count = args.GetArgumentCount();
3627 for (size_t i = 0; i < count; i++) {
3628 const char *trap_func_name = args.GetArgumentAtIndex(i);
3629 if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3630 result.GetOutputStream().Printf(
3631 "This function is "
3632 "treated as a trap handler function via user setting.\n");
3633 }
3634 PlatformSP platform_sp(target->GetPlatform());
3635 if (platform_sp) {
3636 const std::vector<ConstString> trap_handler_names(
3637 platform_sp->GetTrapHandlerSymbolNames());
3638 for (ConstString trap_name : trap_handler_names) {
3639 if (trap_name == funcname) {
3640 result.GetOutputStream().Printf(
3641 "This function's "
3642 "name is listed by the platform as a trap handler.\n");
3643 }
3644 }
3645 }
3646
3647 result.GetOutputStream().Printf("\n");
3648
3649 if (std::shared_ptr<const UnwindPlan> plan_sp =
3650 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread)) {
3651 result.GetOutputStream().Format(
3652 "Asynchronous (not restricted to call-sites) UnwindPlan is '{0}'\n",
3653 plan_sp->GetSourceName());
3654 }
3655 if (std::shared_ptr<const UnwindPlan> plan_sp =
3656 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread)) {
3657 result.GetOutputStream().Format(
3658 "Synchronous (restricted to call-sites) UnwindPlan is '{0}'\n",
3659 plan_sp->GetSourceName());
3660 }
3661 if (std::shared_ptr<const UnwindPlan> plan_sp =
3662 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3663 result.GetOutputStream().Format("Fast UnwindPlan is '{0}'\n",
3664 plan_sp->GetSourceName());
3665 }
3666
3667 result.GetOutputStream().Printf("\n");
3668
3669 if (std::shared_ptr<const UnwindPlan> plan_sp =
3670 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread)) {
3671 result.GetOutputStream().Printf(
3672 "Assembly language inspection UnwindPlan:\n");
3673 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3675 result.GetOutputStream().Printf("\n");
3676 }
3677
3678 if (std::shared_ptr<const UnwindPlan> plan_sp =
3679 func_unwinders_sp->GetObjectFileUnwindPlan(*target)) {
3680 result.GetOutputStream().Printf("object file UnwindPlan:\n");
3681 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3683 result.GetOutputStream().Printf("\n");
3684 }
3685
3686 if (std::shared_ptr<const UnwindPlan> plan_sp =
3687 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,
3688 *thread)) {
3689 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3690 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3692 result.GetOutputStream().Printf("\n");
3693 }
3694
3695 if (std::shared_ptr<const UnwindPlan> plan_sp =
3696 func_unwinders_sp->GetEHFrameUnwindPlan(*target)) {
3697 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3698 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3700 result.GetOutputStream().Printf("\n");
3701 }
3702
3703 if (std::shared_ptr<const UnwindPlan> plan_sp =
3704 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target,
3705 *thread)) {
3706 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3707 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3709 result.GetOutputStream().Printf("\n");
3710 }
3711
3712 if (std::shared_ptr<const UnwindPlan> plan_sp =
3713 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3714 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3715 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3717 result.GetOutputStream().Printf("\n");
3718 }
3719
3720 if (std::shared_ptr<const UnwindPlan> plan_sp =
3721 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3722 *thread)) {
3723 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3724 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3726 result.GetOutputStream().Printf("\n");
3727 }
3728
3729 if (std::shared_ptr<const UnwindPlan> plan_sp =
3730 func_unwinders_sp->GetArmUnwindUnwindPlan(*target)) {
3731 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3732 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3734 result.GetOutputStream().Printf("\n");
3735 }
3736
3737 if (std::shared_ptr<const UnwindPlan> plan_sp =
3738 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3739 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3740 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3742 result.GetOutputStream().Printf("\n");
3743 }
3744
3745 if (std::shared_ptr<const UnwindPlan> plan_sp =
3746 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target)) {
3747 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3748 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3750 result.GetOutputStream().Printf("\n");
3751 }
3752
3753 if (std::shared_ptr<const UnwindPlan> plan_sp =
3754 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3755 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3756 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3758 result.GetOutputStream().Printf("\n");
3759 }
3760
3761 ABISP abi_sp = process->GetABI();
3762 if (abi_sp) {
3763 if (UnwindPlanSP plan_sp = abi_sp->CreateDefaultUnwindPlan()) {
3764 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3765 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3767 result.GetOutputStream().Printf("\n");
3768 }
3769
3770 if (UnwindPlanSP plan_sp = abi_sp->CreateFunctionEntryUnwindPlan()) {
3771 result.GetOutputStream().Printf(
3772 "Arch default at entry point UnwindPlan:\n");
3773 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3775 result.GetOutputStream().Printf("\n");
3776 }
3777 }
3778
3779 result.GetOutputStream().Printf("\n");
3780 }
3782 }
3783
3785};
3786
3787// Lookup information in images
3788#define LLDB_OPTIONS_target_modules_lookup
3789#include "CommandOptions.inc"
3790
3792public:
3793 enum {
3797 eLookupTypeFileLine, // Line is optional
3802 };
3803
3804 class CommandOptions : public Options {
3805 public:
3807
3808 ~CommandOptions() override = default;
3809
3810 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3811 ExecutionContext *execution_context) override {
3812 Status error;
3813
3814 const int short_option = m_getopt_table[option_idx].val;
3815
3816 switch (short_option) {
3817 case 'a': {
3819 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3821 } break;
3822
3823 case 'o':
3824 if (option_arg.getAsInteger(0, m_offset))
3826 "invalid offset string '%s'", option_arg.str().c_str());
3827 break;
3828
3829 case 's':
3830 m_str = std::string(option_arg);
3832 break;
3833
3834 case 'f':
3835 m_file.SetFile(option_arg, FileSpec::Style::native);
3837 break;
3838
3839 case 'i':
3840 m_include_inlines = false;
3841 break;
3842
3843 case 'l':
3844 if (option_arg.getAsInteger(0, m_line_number))
3846 "invalid line number string '%s'", option_arg.str().c_str());
3847 else if (m_line_number == 0)
3848 error = Status::FromErrorString("zero is an invalid line number");
3850 break;
3851
3852 case 'F':
3853 m_str = std::string(option_arg);
3855 break;
3856
3857 case 'n':
3858 m_str = std::string(option_arg);
3860 break;
3861
3862 case 't':
3863 m_str = std::string(option_arg);
3865 break;
3866
3867 case 'v':
3868 m_verbose = true;
3869 break;
3870
3871 case 'A':
3872 m_print_all = true;
3873 break;
3874
3875 case 'r':
3876 m_use_regex = true;
3877 break;
3878
3879 case '\x01':
3880 m_all_ranges = true;
3881 break;
3882 default:
3883 llvm_unreachable("Unimplemented option");
3884 }
3885
3886 return error;
3887 }
3888
3889 void OptionParsingStarting(ExecutionContext *execution_context) override {
3891 m_str.clear();
3892 m_file.Clear();
3894 m_offset = 0;
3895 m_line_number = 0;
3896 m_use_regex = false;
3897 m_include_inlines = true;
3898 m_all_ranges = false;
3899 m_verbose = false;
3900 m_print_all = false;
3901 }
3902
3903 Status OptionParsingFinished(ExecutionContext *execution_context) override {
3904 Status status;
3905 if (m_all_ranges && !m_verbose) {
3906 status =
3907 Status::FromErrorString("--show-variable-ranges must be used in "
3908 "conjunction with --verbose.");
3909 }
3910 return status;
3911 }
3912
3913 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3914 return llvm::ArrayRef(g_target_modules_lookup_options);
3915 }
3916
3917 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3918 std::string m_str; // Holds name lookup
3919 FileSpec m_file; // Files for file lookups
3920 lldb::addr_t m_addr; // Holds the address to lookup
3922 m_offset; // Subtract this offset from m_addr before doing lookups.
3923 uint32_t m_line_number; // Line number for file+line lookups
3924 bool m_use_regex; // Name lookups in m_str are regular expressions.
3925 bool m_include_inlines; // Check for inline entries when looking up by
3926 // file/line.
3927 bool m_all_ranges; // Print all ranges or single range.
3928 bool m_verbose; // Enable verbose lookup info
3929 bool m_print_all; // Print all matches, even in cases where there's a best
3930 // match.
3931 };
3932
3934 : CommandObjectParsed(interpreter, "target modules lookup",
3935 "Look up information within executable and "
3936 "dependent shared library images.",
3937 nullptr, eCommandRequiresTarget) {
3939 }
3940
3942
3943 Options *GetOptions() override { return &m_options; }
3944
3946 bool &syntax_error) {
3947 switch (m_options.m_type) {
3948 case eLookupTypeAddress:
3952 case eLookupTypeSymbol:
3953 default:
3954 return false;
3955 case eLookupTypeType:
3956 break;
3957 }
3958
3959 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3960
3961 if (!frame)
3962 return false;
3963
3964 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3965
3966 if (!sym_ctx.module_sp)
3967 return false;
3968
3969 switch (m_options.m_type) {
3970 default:
3971 return false;
3972 case eLookupTypeType:
3973 if (!m_options.m_str.empty()) {
3975 result.GetOutputStream(), *sym_ctx.module_sp,
3976 m_options.m_str.c_str(), m_options.m_use_regex)) {
3978 return true;
3979 }
3980 }
3981 break;
3982 }
3983
3984 return false;
3985 }
3986
3987 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3988 CommandReturnObject &result, bool &syntax_error) {
3989 switch (m_options.m_type) {
3990 case eLookupTypeAddress:
3991 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3993 m_interpreter, result.GetOutputStream(), module,
3994 eSymbolContextEverything |
3995 (m_options.m_verbose
3996 ? static_cast<int>(eSymbolContextVariable)
3997 : 0),
3998 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
3999 m_options.m_all_ranges)) {
4001 return true;
4002 }
4003 }
4004 break;
4005
4006 case eLookupTypeSymbol:
4007 if (!m_options.m_str.empty()) {
4009 module, m_options.m_str.c_str(),
4010 m_options.m_use_regex, m_options.m_verbose,
4011 m_options.m_all_ranges)) {
4013 return true;
4014 }
4015 }
4016 break;
4017
4019 if (m_options.m_file) {
4021 m_interpreter, result.GetOutputStream(), module,
4022 m_options.m_file, m_options.m_line_number,
4023 m_options.m_include_inlines, m_options.m_verbose,
4024 m_options.m_all_ranges)) {
4026 return true;
4027 }
4028 }
4029 break;
4030
4033 if (!m_options.m_str.empty()) {
4034 ModuleFunctionSearchOptions function_options;
4035 function_options.include_symbols =
4037 function_options.include_inlines = m_options.m_include_inlines;
4038
4040 module, m_options.m_str.c_str(),
4041 m_options.m_use_regex, function_options,
4042 m_options.m_verbose,
4043 m_options.m_all_ranges)) {
4045 return true;
4046 }
4047 }
4048 break;
4049
4050 case eLookupTypeType:
4051 if (!m_options.m_str.empty()) {
4053 &GetTarget(), m_interpreter, result.GetOutputStream(), module,
4054 m_options.m_str.c_str(), m_options.m_use_regex)) {
4056 return true;
4057 }
4058 }
4059 break;
4060
4061 default:
4062 m_options.GenerateOptionUsage(
4063 result.GetErrorStream(), *this,
4064 GetCommandInterpreter().GetDebugger().GetTerminalWidth(),
4065 GetCommandInterpreter().GetDebugger().GetUseColor());
4066 syntax_error = true;
4067 break;
4068 }
4069
4071 return false;
4072 }
4073
4074protected:
4075 void DoExecute(Args &command, CommandReturnObject &result) override {
4076 Target &target = GetTarget();
4077 bool syntax_error = false;
4078 uint32_t i;
4079 uint32_t num_successful_lookups = 0;
4080 // Dump all sections for all modules images
4081
4082 if (command.GetArgumentCount() == 0) {
4083 // Where it is possible to look in the current symbol context first,
4084 // try that. If this search was successful and --all was not passed,
4085 // don't print anything else.
4086 if (LookupHere(m_interpreter, result, syntax_error)) {
4087 result.GetOutputStream().EOL();
4088 num_successful_lookups++;
4089 if (!m_options.m_print_all) {
4091 return;
4092 }
4093 }
4094
4095 // Dump all sections for all other modules
4096
4097 const ModuleList &target_modules = target.GetImages();
4098 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4099 if (target_modules.GetSize() == 0) {
4100 result.AppendError("the target has no associated executable images");
4101 return;
4102 }
4103
4104 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
4105 if (LookupInModule(m_interpreter, module_sp.get(), result,
4106 syntax_error)) {
4107 result.GetOutputStream().EOL();
4108 num_successful_lookups++;
4109 }
4110 }
4111 } else {
4112 // Dump specified images (by basename or fullpath)
4113 const char *arg_cstr;
4114 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
4115 !syntax_error;
4116 ++i) {
4117 ModuleList module_list;
4118 const size_t num_matches =
4119 FindModulesByName(&target, arg_cstr, module_list, false);
4120 if (num_matches > 0) {
4121 for (size_t j = 0; j < num_matches; ++j) {
4122 Module *module = module_list.GetModulePointerAtIndex(j);
4123 if (module) {
4124 if (LookupInModule(m_interpreter, module, result, syntax_error)) {
4125 result.GetOutputStream().EOL();
4126 num_successful_lookups++;
4127 }
4128 }
4129 }
4130 } else
4132 "unable to find an image that matches '{0}'", arg_cstr);
4133 }
4134 }
4135
4136 if (num_successful_lookups > 0)
4138 else
4140 }
4141
4143};
4144
4145#pragma mark CommandObjectMultiwordImageSearchPaths
4146
4147// CommandObjectMultiwordImageSearchPaths
4148
4150 : public CommandObjectMultiword {
4151public:
4154 interpreter, "target modules search-paths",
4155 "Commands for managing module search paths for a target.",
4156 "target modules search-paths <subcommand> [<subcommand-options>]") {
4158 "add", CommandObjectSP(
4162 interpreter)));
4164 "insert",
4169 interpreter)));
4172 interpreter)));
4173 }
4174
4176};
4177
4178#pragma mark CommandObjectTargetModules
4179
4180// CommandObjectTargetModules
4181
4183public:
4184 // Constructors and Destructors
4186 : CommandObjectMultiword(interpreter, "target modules",
4187 "Commands for accessing information for one or "
4188 "more target modules.",
4189 "target modules <sub-command> ...") {
4191 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4193 interpreter)));
4195 interpreter)));
4197 interpreter)));
4199 "lookup",
4202 "search-paths",
4206 "show-unwind",
4208 }
4209
4210 ~CommandObjectTargetModules() override = default;
4211
4212private:
4213 // For CommandObjectTargetModules only
4217};
4218
4220public:
4223 interpreter, "target symbols add",
4224 "Add a debug symbol file to one of the target's current modules by "
4225 "specifying a path to a debug symbols file or by using the options "
4226 "to specify a module.",
4227 "target symbols add <cmd-options> [<symfile>]",
4228 eCommandRequiresTarget),
4230 LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,
4232 "Locate the debug symbols for the shared library specified by "
4233 "name."),
4235 LLDB_OPT_SET_2, false, "frame", 'F',
4236 "Locate the debug symbols for the currently selected frame.", false,
4237 true),
4238 m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4239 "Locate the debug symbols for every frame in "
4240 "the current call stack.",
4241 false, true)
4242
4243 {
4251 m_option_group.Finalize();
4253 }
4254
4256
4257 Options *GetOptions() override { return &m_option_group; }
4258
4259protected:
4260 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4261 CommandReturnObject &result) {
4262 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4263 if (!symbol_fspec) {
4264 result.AppendError(
4265 "one or more executable image paths must be specified");
4266 return false;
4267 }
4268
4269 char symfile_path[PATH_MAX];
4270 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4271
4272 if (!module_spec.GetUUID().IsValid()) {
4273 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4274 module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
4275 }
4276
4277 // Now module_spec represents a symbol file for a module that might exist
4278 // in the current target. Let's find possible matches.
4279 ModuleList matching_modules;
4280
4281 // First extract all module specs from the symbol file
4282 lldb_private::ModuleSpecList symfile_module_specs =
4284 0);
4285 if (symfile_module_specs.GetSize() > 0) {
4286 // Now extract the module spec that matches the target architecture
4287 ModuleSpec target_arch_module_spec;
4288 ModuleSpec symfile_module_spec;
4289 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4290 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4291 symfile_module_spec)) {
4292 if (symfile_module_spec.GetUUID().IsValid()) {
4293 // It has a UUID, look for this UUID in the target modules
4294 ModuleSpec symfile_uuid_module_spec;
4295 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4296 target->GetImages().FindModules(symfile_uuid_module_spec,
4297 matching_modules);
4298 }
4299 }
4300
4301 if (matching_modules.IsEmpty()) {
4302 // No matches yet. Iterate through the module specs to find a UUID
4303 // value that we can match up to an image in our target.
4304 const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4305 for (size_t i = 0;
4306 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4307 if (symfile_module_specs.GetModuleSpecAtIndex(
4308 i, symfile_module_spec)) {
4309 if (symfile_module_spec.GetUUID().IsValid()) {
4310 // It has a UUID. Look for this UUID in the target modules.
4311 ModuleSpec symfile_uuid_module_spec;
4312 symfile_uuid_module_spec.GetUUID() =
4313 symfile_module_spec.GetUUID();
4314 target->GetImages().FindModules(symfile_uuid_module_spec,
4315 matching_modules);
4316 }
4317 }
4318 }
4319 }
4320 }
4321
4322 // Just try to match up the file by basename if we have no matches at
4323 // this point. For example, module foo might have symbols in foo.debug.
4324 if (matching_modules.IsEmpty())
4325 target->GetImages().FindModules(module_spec, matching_modules);
4326
4327 while (matching_modules.IsEmpty()) {
4328 ConstString filename_no_extension(
4330 // Empty string returned, let's bail
4331 if (!filename_no_extension)
4332 break;
4333
4334 // Check if there was no extension to strip and the basename is the same
4335 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4336 break;
4337
4338 // Replace basename with one fewer extension
4339 module_spec.GetFileSpec().SetFilename(filename_no_extension);
4340 target->GetImages().FindModules(module_spec, matching_modules);
4341 }
4342
4343 if (matching_modules.GetSize() > 1) {
4344 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4345 "use the --uuid option to resolve the "
4346 "ambiguity",
4347 symfile_path);
4348 return false;
4349 }
4350
4351 if (matching_modules.GetSize() == 1) {
4352 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4353
4354 // The module has not yet created its symbol vendor, we can just give
4355 // the existing target module the symfile path to use for when it
4356 // decides to create it!
4357 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4358
4359 SymbolFile *symbol_file =
4360 module_sp->GetSymbolFile(true, &result.GetErrorStream());
4361 if (symbol_file) {
4362 ObjectFile *object_file = symbol_file->GetObjectFile();
4363 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4364 // Provide feedback that the symfile has been successfully added.
4365 const FileSpec &module_fs = module_sp->GetFileSpec();
4367 "symbol file '{0}' has been added to '{1}'", symfile_path,
4368 module_fs.GetPath().c_str());
4369
4370 // Let clients know something changed in the module if it is
4371 // currently loaded
4372 ModuleList module_list;
4373 module_list.Append(module_sp);
4374 target->SymbolsDidLoad(module_list);
4375
4376 // Make sure we load any scripting resources that may be embedded
4377 // in the debug info files in case the platform supports that.
4378 std::list<Status> errors;
4379 module_list.LoadScriptingResourcesInTarget(target, errors);
4380 for (const auto &err : errors)
4381 result.AppendWarning(err.AsCString());
4382
4383 flush = true;
4385 return true;
4386 }
4387 }
4388 // Clear the symbol file spec if anything went wrong
4389 module_sp->SetSymbolFileFileSpec(FileSpec());
4390 }
4391
4392 StreamString ss_symfile_uuid;
4393 if (module_spec.GetUUID().IsValid()) {
4394 ss_symfile_uuid << " (";
4395 module_spec.GetUUID().Dump(ss_symfile_uuid);
4396 ss_symfile_uuid << ')';
4397 }
4398 result.AppendErrorWithFormat(
4399 "symbol file '%s'%s does not match any existing module%s", symfile_path,
4400 ss_symfile_uuid.GetData(),
4401 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4402 ? "\n please specify the full path to the symbol file"
4403 : "");
4404 return false;
4405 }
4406
4408 CommandReturnObject &result, bool &flush) {
4409 Status error;
4411 if (module_spec.GetSymbolFileSpec())
4412 return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4413 result);
4414 } else {
4415 result.SetError(std::move(error));
4416 }
4417 return false;
4418 }
4419
4420 bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4421 assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4422
4423 ModuleSpec module_spec;
4424 module_spec.GetUUID() =
4425 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4426
4427 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4428 StreamString error_strm;
4429 error_strm.PutCString("unable to find debug symbols for UUID ");
4430 module_spec.GetUUID().Dump(error_strm);
4431 result.AppendError(error_strm.GetString());
4432 return false;
4433 }
4434
4435 return true;
4436 }
4437
4438 bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4439 assert(m_file_option.GetOptionValue().OptionWasSet());
4440
4441 ModuleSpec module_spec;
4442 module_spec.GetFileSpec() =
4443 m_file_option.GetOptionValue().GetCurrentValue();
4444
4445 Target *target = m_exe_ctx.GetTargetPtr();
4446 ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4447 if (module_sp) {
4448 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4449 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4450 module_spec.GetUUID() = module_sp->GetUUID();
4451 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4452 } else {
4453 module_spec.GetArchitecture() = target->GetArchitecture();
4454 }
4455
4456 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4457 StreamString error_strm;
4458 error_strm.PutCString(
4459 "unable to find debug symbols for the executable file ");
4460 error_strm << module_spec.GetFileSpec();
4461 result.AppendError(error_strm.GetString());
4462 return false;
4463 }
4464
4465 return true;
4466 }
4467
4468 bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4469 assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4470
4471 Process *process = m_exe_ctx.GetProcessPtr();
4472 if (!process) {
4473 result.AppendError(
4474 "a process must exist in order to use the --frame option");
4475 return false;
4476 }
4477
4478 const StateType process_state = process->GetState();
4479 if (!StateIsStoppedState(process_state, true)) {
4480 result.AppendErrorWithFormat("process is not stopped: %s",
4481 StateAsCString(process_state));
4482 return false;
4483 }
4484
4485 StackFrame *frame = m_exe_ctx.GetFramePtr();
4486 if (!frame) {
4487 result.AppendError("invalid current frame");
4488 return false;
4489 }
4490
4491 ModuleSP frame_module_sp(
4492 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4493 if (!frame_module_sp) {
4494 result.AppendError("frame has no module");
4495 return false;
4496 }
4497
4498 ModuleSpec module_spec;
4499 module_spec.GetUUID() = frame_module_sp->GetUUID();
4500 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4501 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4502
4503 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4504 result.AppendError("unable to find debug symbols for the current frame");
4505 return false;
4506 }
4507
4508 return true;
4509 }
4510
4511 bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4512 assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4513
4514 Process *process = m_exe_ctx.GetProcessPtr();
4515 if (!process) {
4516 result.AppendError(
4517 "a process must exist in order to use the --stack option");
4518 return false;
4519 }
4520
4521 const StateType process_state = process->GetState();
4522 if (!StateIsStoppedState(process_state, true)) {
4523 result.AppendErrorWithFormat("process is not stopped: %s",
4524 StateAsCString(process_state));
4525 return false;
4526 }
4527
4528 Thread *thread = m_exe_ctx.GetThreadPtr();
4529 if (!thread) {
4530 result.AppendError("invalid current thread");
4531 return false;
4532 }
4533
4534 bool symbols_found = false;
4535 uint32_t frame_count = thread->GetStackFrameCount();
4536 for (uint32_t i = 0; i < frame_count; ++i) {
4537 lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4538
4539 ModuleSP frame_module_sp(
4540 frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4541 if (!frame_module_sp)
4542 continue;
4543
4544 ModuleSpec module_spec;
4545 module_spec.GetUUID() = frame_module_sp->GetUUID();
4546 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4547 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4548
4549 bool current_frame_flush = false;
4550 if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4551 symbols_found = true;
4552 flush |= current_frame_flush;
4553 }
4554
4555 if (!symbols_found) {
4556 result.AppendError(
4557 "unable to find debug symbols in the current call stack");
4558 return false;
4559 }
4560
4561 return true;
4562 }
4563
4564 void DoExecute(Args &args, CommandReturnObject &result) override {
4565 Target *target = m_exe_ctx.GetTargetPtr();
4567 bool flush = false;
4568 ModuleSpec module_spec;
4569 const bool uuid_option_set =
4570 m_uuid_option_group.GetOptionValue().OptionWasSet();
4571 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4572 const bool frame_option_set =
4573 m_current_frame_option.GetOptionValue().OptionWasSet();
4574 const bool stack_option_set =
4575 m_current_stack_option.GetOptionValue().OptionWasSet();
4576 const size_t argc = args.GetArgumentCount();
4577
4578 if (argc == 0) {
4579 if (uuid_option_set)
4580 AddSymbolsForUUID(result, flush);
4581 else if (file_option_set)
4582 AddSymbolsForFile(result, flush);
4583 else if (frame_option_set)
4584 AddSymbolsForFrame(result, flush);
4585 else if (stack_option_set)
4586 AddSymbolsForStack(result, flush);
4587 else
4588 result.AppendError("one or more symbol file paths must be specified, "
4589 "or options must be specified");
4590 } else {
4591 if (uuid_option_set) {
4592 result.AppendError("specify either one or more paths to symbol files "
4593 "or use the --uuid option without arguments");
4594 } else if (frame_option_set) {
4595 result.AppendError("specify either one or more paths to symbol files "
4596 "or use the --frame option without arguments");
4597 } else if (file_option_set && argc > 1) {
4598 result.AppendError("specify at most one symbol file path when "
4599 "--shlib option is set");
4600 } else {
4601 PlatformSP platform_sp(target->GetPlatform());
4602
4603 for (auto &entry : args.entries()) {
4604 if (!entry.ref().empty()) {
4605 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4606 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4607 FileSystem::Instance().Resolve(symbol_file_spec);
4608 if (file_option_set) {
4609 module_spec.GetFileSpec() =
4610 m_file_option.GetOptionValue().GetCurrentValue();
4611 }
4612 if (platform_sp) {
4613 FileSpec symfile_spec;
4614 if (platform_sp
4615 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4616 .Success())
4617 module_spec.GetSymbolFileSpec() = symfile_spec;
4618 }
4619
4620 bool symfile_exists =
4622
4623 if (symfile_exists) {
4624 if (!AddModuleSymbols(target, module_spec, flush, result))
4625 break;
4626 } else {
4627 std::string resolved_symfile_path =
4628 module_spec.GetSymbolFileSpec().GetPath();
4629 if (resolved_symfile_path != entry.ref()) {
4630 result.AppendErrorWithFormat(
4631 "invalid module path '%s' with resolved path '%s'",
4632 entry.c_str(), resolved_symfile_path.c_str());
4633 break;
4634 }
4635 result.AppendErrorWithFormat("invalid module path '%s'",
4636 entry.c_str());
4637 break;
4638 }
4639 }
4640 }
4641 }
4642 }
4643
4644 if (flush) {
4645 Process *process = m_exe_ctx.GetProcessPtr();
4646 if (process)
4647 process->Flush();
4648 }
4649 }
4650
4656};
4657
4658#pragma mark CommandObjectTargetSymbols
4659
4660// CommandObjectTargetSymbols
4661
4663public:
4664 // Constructors and Destructors
4667 interpreter, "target symbols",
4668 "Commands for adding and managing debug symbol files.",
4669 "target symbols <sub-command> ...") {
4671 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4672 }
4673
4674 ~CommandObjectTargetSymbols() override = default;
4675
4676private:
4677 // For CommandObjectTargetModules only
4681};
4682
4683#pragma mark CommandObjectTargetStopHookAdd
4684
4685// CommandObjectTargetStopHookAdd
4686#define LLDB_OPTIONS_target_stop_hook_add
4687#include "CommandOptions.inc"
4688
4691public:
4693 public:
4695
4696 ~CommandOptions() override = default;
4697
4698 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4699 return llvm::ArrayRef(g_target_stop_hook_add_options);
4700 }
4701
4702 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4703 ExecutionContext *execution_context) override {
4704 Status error;
4705 const int short_option =
4706 g_target_stop_hook_add_options[option_idx].short_option;
4707
4708 switch (short_option) {
4709 case 'c':
4710 m_class_name = std::string(option_arg);
4711 m_sym_ctx_specified = true;
4712 break;
4713
4714 case 'e':
4715 if (option_arg.getAsInteger(0, m_line_end)) {
4717 "invalid end line number: \"%s\"", option_arg.str().c_str());
4718 break;
4719 }
4720 m_sym_ctx_specified = true;
4721 break;
4722
4723 case 'G': {
4724 bool value, success;
4725 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4726 if (success) {
4727 m_auto_continue = value;
4728 } else
4730 "invalid boolean value '%s' passed for -G option",
4731 option_arg.str().c_str());
4732 } break;
4733 case 'l':
4734 if (option_arg.getAsInteger(0, m_line_start)) {
4736 "invalid start line number: \"%s\"", option_arg.str().c_str());
4737 break;
4738 }
4739 m_sym_ctx_specified = true;
4740 break;
4741
4742 case 'i':
4743 m_no_inlines = true;
4744 break;
4745
4746 case 'n':
4747 m_function_name = std::string(option_arg);
4748 m_func_name_type_mask |= eFunctionNameTypeAuto;
4749 m_sym_ctx_specified = true;
4750 break;
4751
4752 case 'f':
4753 m_file_name = std::string(option_arg);
4754 m_sym_ctx_specified = true;
4755 break;
4756
4757 case 's':
4758 m_module_name = std::string(option_arg);
4759 m_sym_ctx_specified = true;
4760 break;
4761
4762 case 't':
4763 if (option_arg.getAsInteger(0, m_thread_id))
4765 "invalid thread id string '%s'", option_arg.str().c_str());
4766 m_thread_specified = true;
4767 break;
4768
4769 case 'T':
4770 m_thread_name = std::string(option_arg);
4771 m_thread_specified = true;
4772 break;
4773
4774 case 'q':
4775 m_queue_name = std::string(option_arg);
4776 m_thread_specified = true;
4777 break;
4778
4779 case 'x':
4780 if (option_arg.getAsInteger(0, m_thread_index))
4782 "invalid thread index string '%s'", option_arg.str().c_str());
4783 m_thread_specified = true;
4784 break;
4785
4786 case 'o':
4787 m_use_one_liner = true;
4788 m_one_liner.push_back(std::string(option_arg));
4789 break;
4790
4791 case 'I': {
4792 bool value, success;
4793 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4794 if (success)
4795 m_at_initial_stop = value;
4796 else
4798 "invalid boolean value '%s' passed for -F option",
4799 option_arg.str().c_str());
4800 } break;
4801
4802 default:
4803 llvm_unreachable("Unimplemented option");
4804 }
4805 return error;
4806 }
4807
4808 void OptionParsingStarting(ExecutionContext *execution_context) override {
4809 m_class_name.clear();
4810 m_function_name.clear();
4811 m_line_start = 0;
4813 m_file_name.clear();
4814 m_module_name.clear();
4815 m_func_name_type_mask = eFunctionNameTypeAuto;
4818 m_thread_name.clear();
4819 m_queue_name.clear();
4820
4821 m_no_inlines = false;
4822 m_sym_ctx_specified = false;
4823 m_thread_specified = false;
4824
4825 m_use_one_liner = false;
4826 m_one_liner.clear();
4827 m_auto_continue = false;
4828 m_at_initial_stop = true;
4829 }
4830
4831 std::string m_class_name;
4832 std::string m_function_name;
4833 uint32_t m_line_start = 0;
4835 std::string m_file_name;
4836 std::string m_module_name;
4838 eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4841 std::string m_thread_name;
4842 std::string m_queue_name;
4844 bool m_no_inlines = false;
4846 // Instance variables to hold the values for one_liner options.
4847 bool m_use_one_liner = false;
4848 std::vector<std::string> m_one_liner;
4850
4851 bool m_auto_continue = false;
4852 };
4853
4855 : CommandObjectParsed(interpreter, "target stop-hook add",
4856 "Add a hook to be executed when the target stops."
4857 "The hook can either be a list of commands or an "
4858 "appropriately defined Python class. You can also "
4859 "add filters so the hook only runs a certain stop "
4860 "points.",
4861 "target stop-hook add"),
4864 m_python_class_options("scripted stop-hook", true, 'P') {
4866 R"(
4867Command Based stop-hooks:
4868-------------------------
4869 Stop hooks can run a list of lldb commands by providing one or more
4870 --one-liner options. The commands will get run in the order they are added.
4871 Or you can provide no commands, in which case you will enter a command editor
4872 where you can enter the commands to be run.
4873
4874Python Based Stop Hooks:
4875------------------------
4876 Stop hooks can be implemented with a suitably defined Python class, whose name
4877 is passed in the --python-class option.
4878
4879 When the stop hook is added, the class is initialized by calling:
4880
4881 def __init__(self, target, extra_args, internal_dict):
4882
4883 target: The target that the stop hook is being added to.
4884 extra_args: An SBStructuredData Dictionary filled with the -key -value
4885 option pairs passed to the command.
4886 dict: An implementation detail provided by lldb.
4887
4888 Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4889 The method has the signature:
4891 def handle_stop(self, exe_ctx, stream):
4892
4893 exe_ctx: An SBExecutionContext for the thread that has stopped.
4894 stream: An SBStream, anything written to this stream will be printed in the
4895 the stop message when the process stops.
4896
4897 Return Value: The method returns "should_stop". If should_stop is false
4898 from all the stop hook executions on threads that stopped
4899 with a reason, then the process will continue. Note that this
4900 will happen only after all the stop hooks are run.
4901
4902Filter Options:
4903---------------
4904 Stop hooks can be set to always run, or to only run when the stopped thread
4905 matches the filter options passed on the command line. The available filter
4906 options include a shared library or a thread or queue specification,
4907 a line range in a source file, a function name or a class name.
4908 )");
4911 LLDB_OPT_SET_FROM_TO(4, 6));
4912 m_all_options.Append(&m_options);
4913 m_all_options.Finalize();
4914 }
4915
4916 ~CommandObjectTargetStopHookAdd() override = default;
4917
4918 Options *GetOptions() override { return &m_all_options; }
4919
4920protected:
4921 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4922 if (interactive) {
4923 if (lldb::LockableStreamFileSP output_sp =
4924 io_handler.GetOutputStreamFileSP()) {
4925 LockedStreamFile locked_stream = output_sp->Lock();
4926 locked_stream.PutCString(
4927 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4928 }
4929 }
4930 }
4931
4932 void IOHandlerInputComplete(IOHandler &io_handler,
4933 std::string &line) override {
4934 if (m_stop_hook_sp) {
4935 if (line.empty()) {
4936 if (lldb::LockableStreamFileSP error_sp =
4937 io_handler.GetErrorStreamFileSP()) {
4938 LockedStreamFile locked_stream = error_sp->Lock();
4939 locked_stream.Printf("error: stop hook #%" PRIu64
4940 " aborted, no commands.\n",
4941 m_stop_hook_sp->GetID());
4942 }
4944 } else {
4945 // The IOHandler editor is only for command lines stop hooks:
4946 Target::StopHookCommandLine *hook_ptr =
4947 static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4948
4949 hook_ptr->SetActionFromString(line);
4950 if (lldb::LockableStreamFileSP output_sp =
4951 io_handler.GetOutputStreamFileSP()) {
4952 LockedStreamFile locked_stream = output_sp->Lock();
4953 locked_stream.Printf("Stop hook #%" PRIu64 " added.\n",
4954 m_stop_hook_sp->GetID());
4955 }
4956 }
4957 m_stop_hook_sp.reset();
4958 }
4959 io_handler.SetIsDone(true);
4960 }
4961
4962 void DoExecute(Args &command, CommandReturnObject &result) override {
4963 m_stop_hook_sp.reset();
4964
4965 Target &target = GetTarget();
4966 Target::StopHookSP new_hook_sp =
4967 target.CreateStopHook(m_python_class_options.GetName().empty() ?
4968 Target::StopHook::StopHookKind::CommandBased
4969 : Target::StopHook::StopHookKind::ScriptBased);
4970
4971 // First step, make the specifier.
4972 std::unique_ptr<SymbolContextSpecifier> specifier_up;
4973 if (m_options.m_sym_ctx_specified) {
4974 specifier_up = std::make_unique<SymbolContextSpecifier>(
4975 GetDebugger().GetSelectedTarget());
4976
4977 if (!m_options.m_module_name.empty()) {
4978 specifier_up->AddSpecification(
4979 m_options.m_module_name.c_str(),
4981 }
4982
4983 if (!m_options.m_class_name.empty()) {
4984 specifier_up->AddSpecification(
4985 m_options.m_class_name.c_str(),
4987 }
4988
4989 if (!m_options.m_file_name.empty()) {
4990 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
4992 }
4993
4994 if (m_options.m_line_start != 0) {
4995 specifier_up->AddLineSpecification(
4996 m_options.m_line_start,
4998 }
4999
5000 if (m_options.m_line_end != UINT_MAX) {
5001 specifier_up->AddLineSpecification(
5003 }
5004
5005 if (!m_options.m_function_name.empty()) {
5006 specifier_up->AddSpecification(
5007 m_options.m_function_name.c_str(),
5009 }
5010 }
5011
5012 if (specifier_up)
5013 new_hook_sp->SetSpecifier(specifier_up.release());
5014
5015 // Should we run at the initial stop:
5016 new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);
5017
5018 // Next see if any of the thread options have been entered:
5019
5020 if (m_options.m_thread_specified) {
5021 ThreadSpec *thread_spec = new ThreadSpec();
5022
5023 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
5024 thread_spec->SetTID(m_options.m_thread_id);
5025 }
5026
5027 if (m_options.m_thread_index != UINT32_MAX)
5028 thread_spec->SetIndex(m_options.m_thread_index);
5029
5030 if (!m_options.m_thread_name.empty())
5031 thread_spec->SetName(m_options.m_thread_name.c_str());
5033 if (!m_options.m_queue_name.empty())
5034 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5036 new_hook_sp->SetThreadSpecifier(thread_spec);
5037 }
5038
5039 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
5041 // This is a command line stop hook:
5042 Target::StopHookCommandLine *hook_ptr =
5043 static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
5045 result.AppendMessageWithFormatv("Stop hook #{0} added.",
5046 new_hook_sp->GetID());
5047 } else if (!m_python_class_options.GetName().empty()) {
5048 // This is a scripted stop hook:
5049 Target::StopHookScripted *hook_ptr =
5050 static_cast<Target::StopHookScripted *>(new_hook_sp.get());
5051 Status error = hook_ptr->SetScriptCallback(
5052 m_python_class_options.GetName(),
5053 m_python_class_options.GetStructuredData());
5054 if (error.Success())
5055 result.AppendMessageWithFormatv("Stop hook #{0} added.",
5056 new_hook_sp->GetID());
5057 else {
5058 // FIXME: Set the stop hook ID counter back.
5059 result.AppendErrorWithFormat("Couldn't add stop hook: %s",
5060 error.AsCString());
5061 target.UndoCreateStopHook(new_hook_sp->GetID());
5062 return;
5063 }
5064 } else {
5065 m_stop_hook_sp = new_hook_sp;
5066 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
5067 *this); // IOHandlerDelegate
5068 }
5070 }
5071
5072private:
5074 OptionGroupPythonClassWithDict m_python_class_options;
5075 OptionGroupOptions m_all_options;
5076
5078};
5079
5080#pragma mark CommandObjectTargetStopHookDelete
5081
5082// CommandObjectTargetStopHookDelete
5083
5085public:
5087 : CommandObjectParsed(interpreter, "target stop-hook delete",
5088 "Delete a stop-hook.",
5089 "target stop-hook delete [<idx>]") {
5091 R"(
5092Deletes the stop hook by index.
5093
5094At any given stop, all enabled stop hooks that pass the stop filter will
5095get a chance to run. That means if one stop-hook deletes another stop hook
5096while executing, the deleted stop hook will still fire for the stop at which
5097it was deleted.
5098 )");
5100 }
5101
5102 ~CommandObjectTargetStopHookDelete() override = default;
5103
5104 void
5106 OptionElementVector &opt_element_vector) override {
5107 if (request.GetCursorIndex())
5108 return;
5109 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5110 }
5111
5112protected:
5113 void DoExecute(Args &command, CommandReturnObject &result) override {
5114 Target &target = GetTarget();
5115 // FIXME: see if we can use the breakpoint id style parser?
5116 size_t num_args = command.GetArgumentCount();
5117 if (num_args == 0) {
5118 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
5120 return;
5121 } else {
5122 target.RemoveAllStopHooks();
5123 }
5124 } else {
5125 for (size_t i = 0; i < num_args; i++) {
5126 lldb::user_id_t user_id;
5127 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5128 result.AppendErrorWithFormat("invalid stop hook id: \"%s\"",
5129 command.GetArgumentAtIndex(i));
5130 return;
5131 }
5132 if (!target.RemoveStopHookByID(user_id)) {
5133 result.AppendErrorWithFormat("unknown stop hook id: \"%s\"",
5134 command.GetArgumentAtIndex(i));
5135 return;
5136 }
5137 }
5138 }
5140 }
5141};
5142
5143#pragma mark CommandObjectTargetStopHookEnableDisable
5144
5145// CommandObjectTargetStopHookEnableDisable
5146
5148public:
5150 bool enable, const char *name,
5151 const char *help, const char *syntax)
5152 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
5154 }
5155
5157
5158 void
5160 OptionElementVector &opt_element_vector) override {
5161 if (request.GetCursorIndex())
5162 return;
5163 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5164 }
5165
5166protected:
5167 void DoExecute(Args &command, CommandReturnObject &result) override {
5168 Target &target = GetTarget();
5169 // FIXME: see if we can use the breakpoint id style parser?
5170 size_t num_args = command.GetArgumentCount();
5171 bool success;
5172
5173 if (num_args == 0) {
5175 } else {
5176 for (size_t i = 0; i < num_args; i++) {
5177 lldb::user_id_t user_id;
5178 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5179 result.AppendErrorWithFormat("invalid stop hook id: \"%s\"",
5180 command.GetArgumentAtIndex(i));
5181 return;
5182 }
5183 success = target.SetStopHookActiveStateByID(user_id, m_enable);
5184 if (!success) {
5185 result.AppendErrorWithFormat("unknown stop hook id: \"%s\"",
5186 command.GetArgumentAtIndex(i));
5187 return;
5188 }
5189 }
5190 }
5192 }
5193
5194private:
5196};
5197
5198#pragma mark CommandObjectTargetStopHookList
5199
5200// CommandObjectTargetStopHookList
5201#define LLDB_OPTIONS_target_stop_hook_list
5202#include "CommandOptions.inc"
5203
5205public:
5207 : CommandObjectParsed(interpreter, "target stop-hook list",
5208 "List all stop-hooks.") {}
5209
5211
5212 Options *GetOptions() override { return &m_options; }
5213
5214 class CommandOptions : public Options {
5215 public:
5216 CommandOptions() = default;
5217 ~CommandOptions() override = default;
5218
5219 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5220 ExecutionContext *execution_context) override {
5221 Status error;
5222 const int short_option = m_getopt_table[option_idx].val;
5223
5224 switch (short_option) {
5225 case 'i':
5226 m_internal = true;
5227 break;
5228 default:
5229 llvm_unreachable("Unimplemented option");
5230 }
5231
5232 return error;
5233 }
5234
5235 void OptionParsingStarting(ExecutionContext *execution_context) override {
5236 m_internal = false;
5237 }
5238
5239 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5240 return llvm::ArrayRef(g_target_stop_hook_list_options);
5241 }
5242
5243 // Instance variables to hold the values for command options.
5244 bool m_internal = false;
5245 };
5246
5247protected:
5248 void DoExecute(Args &command, CommandReturnObject &result) override {
5249 Target &target = GetTarget();
5250
5251 bool printed_hook = false;
5252 for (auto &hook : target.GetStopHooks(m_options.m_internal)) {
5253 if (printed_hook)
5254 result.GetOutputStream().PutCString("\n");
5255 hook->GetDescription(result.GetOutputStream(), eDescriptionLevelFull);
5256 printed_hook = true;
5257 }
5258
5259 if (!printed_hook)
5260 result.GetOutputStream().PutCString("No stop hooks.\n");
5261
5263 }
5264
5265private:
5267};
5268
5269#pragma mark CommandObjectMultiwordTargetStopHooks
5270
5271// CommandObjectMultiwordTargetStopHooks
5272
5274public:
5277 interpreter, "target stop-hook",
5278 "Commands for operating on debugger target stop-hooks.",
5279 "target stop-hook <subcommand> [<subcommand-options>]") {
5281 new CommandObjectTargetStopHookAdd(interpreter)));
5283 "delete",
5285 LoadSubCommand("disable",
5287 interpreter, false, "target stop-hook disable [<id>]",
5288 "Disable a stop-hook.", "target stop-hook disable")));
5289 LoadSubCommand("enable",
5291 interpreter, true, "target stop-hook enable [<id>]",
5292 "Enable a stop-hook.", "target stop-hook enable")));
5294 interpreter)));
5295 }
5296
5298};
5299
5300#pragma mark CommandObjectTargetHookAdd
5301
5302#define LLDB_OPTIONS_target_hook_add
5303#include "CommandOptions.inc"
5304
5307public:
5309 public:
5310 CommandOptions() = default;
5311 ~CommandOptions() override = default;
5312
5313 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5314 return llvm::ArrayRef(g_target_hook_add_options);
5315 }
5316
5317 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5318 ExecutionContext *execution_context) override {
5319 Status error;
5320 const int short_option =
5321 g_target_hook_add_options[option_idx].short_option;
5322 switch (short_option) {
5323 case 'o':
5324 m_use_one_liner = true;
5325 m_one_liner.push_back(std::string(option_arg));
5326 break;
5327 case 'L':
5328 m_on_load = true;
5329 break;
5330 case 'u':
5331 m_on_unload = true;
5332 break;
5333 case 'S':
5334 m_on_stop = true;
5335 break;
5336 case 's':
5337 m_module_name = std::string(option_arg);
5338 m_sym_ctx_specified = true;
5339 break;
5340 case 'x': {
5341 uint32_t thread_index;
5342 if (option_arg.getAsInteger(0, thread_index))
5343 error = Status::FromErrorStringWithFormat("invalid thread index '%s'",
5344 option_arg.str().c_str());
5345 else
5346 m_thread_index = thread_index;
5347 m_thread_specified = true;
5348 break;
5349 }
5350 case 't': {
5351 lldb::tid_t thread_id;
5352 if (option_arg.getAsInteger(0, thread_id))
5353 error = Status::FromErrorStringWithFormat("invalid thread id '%s'",
5354 option_arg.str().c_str());
5355 else
5356 m_thread_id = thread_id;
5357 m_thread_specified = true;
5358 break;
5359 }
5360 case 'T':
5361 m_thread_name = std::string(option_arg);
5362 m_thread_specified = true;
5363 break;
5364 case 'q':
5365 m_queue_name = std::string(option_arg);
5366 m_thread_specified = true;
5367 break;
5368 case 'f':
5369 m_file_name = std::string(option_arg);
5370 m_sym_ctx_specified = true;
5371 break;
5372 case 'l': {
5373 uint32_t line;
5374 if (option_arg.getAsInteger(0, line))
5376 "invalid start line number '%s'", option_arg.str().c_str());
5377 else
5378 m_line_start = line;
5379 m_sym_ctx_specified = true;
5380 break;
5381 }
5382 case 'e': {
5383 uint32_t line;
5384 if (option_arg.getAsInteger(0, line))
5386 "invalid end line number '%s'", option_arg.str().c_str());
5387 else
5388 m_line_end = line;
5389 m_sym_ctx_specified = true;
5390 break;
5391 }
5392 case 'c':
5393 m_class_name = std::string(option_arg);
5394 m_sym_ctx_specified = true;
5395 break;
5396 case 'n':
5397 m_function_name = std::string(option_arg);
5398 m_sym_ctx_specified = true;
5399 break;
5400 case 'G': {
5401 bool value, success;
5402 value = OptionArgParser::ToBoolean(option_arg, false, &success);
5403 if (success)
5404 m_auto_continue = value;
5405 else
5407 "invalid boolean value '%s' passed for -G option",
5408 option_arg.str().c_str());
5409 break;
5410 }
5411 case 'I': {
5412 bool value, success;
5413 value = OptionArgParser::ToBoolean(option_arg, true, &success);
5414 if (success)
5415 m_at_initial_stop = value;
5416 else
5418 "invalid boolean value '%s' passed for -I option",
5419 option_arg.str().c_str());
5420 break;
5421 }
5422 default:
5423 llvm_unreachable("unhandled option");
5424 }
5425 return error;
5426 }
5427
5428 void OptionParsingStarting(ExecutionContext *execution_context) override {
5429 m_use_one_liner = false;
5430 m_one_liner.clear();
5431 m_on_load = false;
5432 m_on_unload = false;
5433 m_on_stop = false;
5434 m_sym_ctx_specified = false;
5435 m_thread_specified = false;
5436 m_module_name.clear();
5437 m_file_name.clear();
5438 m_class_name.clear();
5439 m_function_name.clear();
5440 m_line_start = 0;
5441 m_line_end = UINT_MAX;
5444 m_thread_name.clear();
5445 m_queue_name.clear();
5446 m_auto_continue = false;
5447 m_at_initial_stop = true;
5448 }
5449
5450 std::vector<std::string> m_one_liner;
5451 bool m_use_one_liner = false;
5452 bool m_on_load = false;
5453 bool m_on_unload = false;
5454 bool m_on_stop = false;
5455
5456 // Filter options (for stop trigger).
5459 std::string m_module_name;
5460 std::string m_file_name;
5461 std::string m_class_name;
5462 std::string m_function_name;
5463 uint32_t m_line_start = 0;
5464 uint32_t m_line_end = UINT_MAX;
5467 std::string m_thread_name;
5468 std::string m_queue_name;
5469 bool m_auto_continue = false;
5471 };
5472
5475 interpreter, "target hook add",
5476 "Add a hook to be executed on target lifecycle events.",
5477 "target hook add"),
5480 m_python_class_options("scripted hook", false, 'P') {
5481 SetHelpLong(R"help(
5482Command-based hooks:
5483--------------------
5484 Specify which triggers the hook responds to with --on-load (-L),
5485 --on-unload (-u), and/or --on-stop (-S). At least one trigger is required.
5486 Provide commands with --one-liner (-o), or omit -o to enter an interactive
5487 command editor. All commands run for every trigger the hook is signed up
5488 for; there is no per-trigger command list.
5489
5490 Examples:
5491 target hook add -L -o "script print('module loaded')"
5492 target hook add -L -u -o "script print('module event')"
5493 target hook add -S -o "bt"
5494 target hook add -L -u -S -o "script print('all events')"
5495 target hook add -S -s mylib.so -n main -o "bt"
5496 target hook add -S -G true -o "thread info"
5498Python class hooks:
5499-------------------
5500 Provide a Python class with --python-class (-P). The class controls which
5501 events it handles by implementing the corresponding methods; you do not
5502 specify triggers on the command line. Use -k <key> -v <value> to pass
5503 extra_args to the class constructor.
5504
5505 Examples:
5506 target hook add -P mymodule.MyHook
5507 target hook add -P mymodule.MyHook -k verbose -v true
5509 The Python class should implement at least one of these methods:
5510
5511 class MyHook:
5512 def __init__(self, target, extra_args, internal_dict):
5513 self.target = target
5514 def handle_module_loaded(self, stream):
5515 pass
5516 def handle_module_unloaded(self, stream):
5517 pass
5518 def handle_stop(self, exe_ctx, stream):
5519 return True # True = should_stop, False = continue
5520
5521Filter options:
5522---------------
5523 Filters (-s, -f, -l, -e, -c, -n, -x, -t, -T, -q) restrict when the hook
5524 fires. They apply to both command-based and Python class hooks.
5525)help");
5526 // Python class options (-P, -k, -v) are placed in Set 2 (dst_mask).
5527 // src_mask must cover Set 1 | Set 2 to match the internal usage masks of
5528 // OptionGroupPythonClassWithDict (class=Set1, key/value=Set2).
5529 // Since -o, -L, -u, -S are Group<1> only, the parser prevents mixing.
5532 m_all_options.Append(&m_options);
5533 m_all_options.Finalize();
5534 }
5536 ~CommandObjectTargetHookAdd() override = default;
5537
5538 Options *GetOptions() override { return &m_all_options; }
5539
5540protected:
5541 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
5542 if (interactive) {
5543 if (lldb::LockableStreamFileSP output_sp =
5544 io_handler.GetOutputStreamFileSP()) {
5545 LockedStreamFile locked_stream = output_sp->Lock();
5546 locked_stream.PutCString(
5547 "Enter your hook command(s). Type 'DONE' to end.\n");
5548 }
5549 }
5550 }
5551
5552 void IOHandlerInputComplete(IOHandler &io_handler,
5553 std::string &line) override {
5554 if (m_hook_sp) {
5555 if (line.empty()) {
5556 if (lldb::LockableStreamFileSP error_sp =
5557 io_handler.GetErrorStreamFileSP()) {
5558 LockedStreamFile locked_stream = error_sp->Lock();
5559 locked_stream.Printf("error: hook #%" PRIu64
5560 " aborted, no commands.\n",
5561 m_hook_sp->GetID());
5562 }
5564 } else {
5565 auto *hook = static_cast<Target::HookCommandLine *>(m_hook_sp.get());
5566 hook->SetActionFromString(line);
5567 if (lldb::LockableStreamFileSP output_sp =
5568 io_handler.GetOutputStreamFileSP()) {
5569 LockedStreamFile locked_stream = output_sp->Lock();
5570 locked_stream.Printf("Hook #%" PRIu64 " added.\n",
5571 m_hook_sp->GetID());
5572 }
5573 }
5574 m_hook_sp.reset();
5575 }
5576 io_handler.SetIsDone(true);
5577 }
5578
5579 void DoExecute(Args &command, CommandReturnObject &result) override {
5580 m_hook_sp.reset();
5581 Target &target = GetTarget();
5582
5583 bool is_python_class = !m_python_class_options.GetName().empty();
5584
5585 // Command-based hooks require at least one explicit trigger.
5586 if (!is_python_class && !m_options.m_on_load && !m_options.m_on_unload &&
5587 !m_options.m_on_stop) {
5588 result.AppendError("at least one trigger must be specified: "
5589 "--on-load (-L), --on-unload (-u), or --on-stop (-S)");
5590 return;
5591 }
5592
5593 Target::Hook::HookKind hook_kind =
5594 is_python_class ? Target::Hook::HookKind::ScriptBased
5595 : Target::Hook::HookKind::CommandBased;
5596
5597 Target::HookSP new_hook_sp = target.CreateHook(hook_kind);
5598
5599 if (!is_python_class) {
5600 // Build trigger mask from explicit command-line flags.
5601 auto *cmd_hook =
5602 static_cast<Target::HookCommandLine *>(new_hook_sp.get());
5603 uint32_t trigger_mask = 0;
5604 if (m_options.m_on_load)
5605 trigger_mask |= Target::Hook::kModulesLoaded;
5606 if (m_options.m_on_unload)
5607 trigger_mask |= Target::Hook::kModulesUnloaded;
5608 if (m_options.m_on_stop)
5609 trigger_mask |= Target::Hook::kProcessStop;
5610 cmd_hook->SetTriggerMask(trigger_mask);
5611 }
5612 // Python class hooks: triggers are computed in SetScriptCallback based
5613 // on which callback methods the class implements.
5614
5615 // Set up symbol context specifier if filter options were provided.
5616 if (m_options.m_sym_ctx_specified) {
5617 auto specifier_up = std::make_unique<SymbolContextSpecifier>(
5618 GetDebugger().GetSelectedTarget());
5619
5620 if (!m_options.m_module_name.empty())
5621 specifier_up->AddSpecification(
5622 m_options.m_module_name.c_str(),
5624
5625 if (!m_options.m_class_name.empty())
5626 specifier_up->AddSpecification(
5627 m_options.m_class_name.c_str(),
5629
5630 if (!m_options.m_file_name.empty())
5631 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
5633
5634 if (m_options.m_line_start != 0)
5635 specifier_up->AddLineSpecification(
5636 m_options.m_line_start,
5638
5639 if (m_options.m_line_end != UINT_MAX)
5640 specifier_up->AddLineSpecification(
5642
5643 if (!m_options.m_function_name.empty())
5644 specifier_up->AddSpecification(
5645 m_options.m_function_name.c_str(),
5647
5648 new_hook_sp->SetSCSpecifier(specifier_up.release());
5649 }
5650
5651 // Set up thread specifier.
5652 if (m_options.m_thread_specified) {
5653 ThreadSpec *thread_spec = new ThreadSpec();
5654
5655 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5656 thread_spec->SetTID(m_options.m_thread_id);
5658 if (m_options.m_thread_index != UINT32_MAX)
5659 thread_spec->SetIndex(m_options.m_thread_index);
5660
5661 if (!m_options.m_thread_name.empty())
5662 thread_spec->SetName(m_options.m_thread_name.c_str());
5663
5664 if (!m_options.m_queue_name.empty())
5665 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5666
5667 new_hook_sp->SetThreadSpecifier(thread_spec);
5668 }
5669
5670 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
5671 new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);
5672
5674 auto *hook = static_cast<Target::HookCommandLine *>(new_hook_sp.get());
5676 result.AppendMessageWithFormatv("Hook #{0} added.\n",
5677 new_hook_sp->GetID());
5678 } else if (!m_python_class_options.GetName().empty()) {
5679 auto *hook = static_cast<Target::HookScripted *>(new_hook_sp.get());
5680 Status callback_error =
5681 hook->SetScriptCallback(m_python_class_options.GetName(),
5682 m_python_class_options.GetStructuredData());
5683 if (callback_error.Fail()) {
5684 result.AppendErrorWithFormat("couldn't add hook: %s",
5685 callback_error.AsCString());
5686 target.UndoCreateHook(new_hook_sp->GetID());
5687 return;
5688 }
5689 result.AppendMessageWithFormatv("Hook #{0} added.\n",
5690 new_hook_sp->GetID());
5691 } else {
5692 m_hook_sp = new_hook_sp;
5693 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // prompt
5694 *this); // delegate
5695 }
5697 }
5698
5699private:
5701 OptionGroupPythonClassWithDict m_python_class_options;
5702 OptionGroupOptions m_all_options;
5704};
5705
5706#pragma mark CommandObjectTargetHookDelete
5707
5709public:
5711 : CommandObjectParsed(interpreter, "target hook delete", "Delete a hook.",
5712 "target hook delete [<id>]") {
5714 }
5715
5717
5718protected:
5719 void DoExecute(Args &command, CommandReturnObject &result) override {
5720 Target &target = GetTarget();
5721 if (command.GetArgumentCount() == 0) {
5722 if (!m_interpreter.Confirm("Delete all hooks?", true)) {
5724 return;
5725 }
5726 target.RemoveAllHooks();
5728 return;
5729 }
5730
5731 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
5732 lldb::user_id_t user_id;
5733 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5734 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5735 command.GetArgumentAtIndex(i));
5736 return;
5737 }
5738 if (!target.RemoveHookByID(user_id)) {
5739 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5740 command.GetArgumentAtIndex(i));
5741 return;
5742 }
5743 }
5745 }
5746};
5747
5748#pragma mark CommandObjectTargetHookEnableDisable
5749
5751public:
5753 bool enable, const char *name,
5754 const char *help, const char *syntax)
5755 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
5757 }
5758
5760
5761protected:
5762 void DoExecute(Args &command, CommandReturnObject &result) override {
5763 Target &target = GetTarget();
5764
5765 // No IDs = apply to all hooks.
5766 if (command.GetArgumentCount() == 0) {
5769 return;
5770 }
5771
5772 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
5773 lldb::user_id_t user_id;
5774 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5775 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5776 command.GetArgumentAtIndex(i));
5777 return;
5778 }
5779 if (!target.SetHookEnabledStateByID(user_id, m_enable)) {
5780 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5781 command.GetArgumentAtIndex(i));
5782 return;
5783 }
5784 }
5786 }
5787
5788private:
5790};
5791
5792#pragma mark CommandObjectTargetHookModify
5793
5794#define LLDB_OPTIONS_target_hook_modify
5795#include "CommandOptions.inc"
5796
5797/// Modify trigger settings on a hook. Only valid for command-based hooks;
5798/// scripted hooks derive their triggers from the class methods.
5800public:
5801 class CommandOptions : public Options {
5802 public:
5803 CommandOptions() = default;
5804 ~CommandOptions() override = default;
5805
5806 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5807 return llvm::ArrayRef(g_target_hook_modify_options);
5808 }
5809
5810 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5811 ExecutionContext *execution_context) override {
5812 Status error;
5813 const int short_option =
5814 g_target_hook_modify_options[option_idx].short_option;
5815 switch (short_option) {
5816 case 'e':
5817 m_enable_trigger = option_arg.str();
5818 break;
5819 case 'd':
5820 m_disable_trigger = option_arg.str();
5821 break;
5822 default:
5823 llvm_unreachable("unhandled option");
5824 }
5825 return error;
5826 }
5827
5828 void OptionParsingStarting(ExecutionContext *execution_context) override {
5829 m_enable_trigger.clear();
5830 m_disable_trigger.clear();
5831 }
5832
5833 std::string m_enable_trigger;
5835 };
5836
5838 : CommandObjectParsed(interpreter, "target hook modify",
5839 "Modify trigger settings on a hook.",
5840 "target hook modify [--enable-trigger <name>] "
5841 "[--disable-trigger <name>] [<id>]") {
5843 SetHelpLong(R"help(
5844Modify trigger settings on command-based hooks. Scripted hooks derive their
5845triggers from the class methods and cannot be modified.
5847If no hook ID is given, the last added hook is modified.
5849Valid trigger names: load, unload, stop.
5850
5851Examples:
5852 target hook modify --enable-trigger stop 1
5853 target hook modify --disable-trigger load 1
5854 target hook modify --enable-trigger stop (modifies last added hook)
5855)help");
5856 }
5857
5858 ~CommandObjectTargetHookModify() override = default;
5859
5860 Options *GetOptions() override { return &m_options; }
5862protected:
5863 static uint32_t ParseTriggerName(llvm::StringRef name) {
5864 if (name == "load")
5866 if (name == "unload")
5868 if (name == "stop")
5870 return 0;
5871 }
5872
5873 void DoExecute(Args &command, CommandReturnObject &result) override {
5874 Target &target = GetTarget();
5875
5876 if (m_options.m_enable_trigger.empty() &&
5877 m_options.m_disable_trigger.empty()) {
5878 result.AppendError("at least one of --enable-trigger or "
5879 "--disable-trigger must be specified");
5880 return;
5881 }
5882
5883 // Resolve the hook ID. Default to last added if not specified.
5884 Target::HookSP hook_sp;
5885 if (command.GetArgumentCount() == 0) {
5886 size_t num_hooks = target.GetNumHooks();
5887 if (num_hooks == 0) {
5888 result.AppendError("no hooks exist");
5889 return;
5890 }
5891 hook_sp = target.GetHookAtIndex(num_hooks - 1);
5892 } else {
5893 lldb::user_id_t user_id;
5894 if (!llvm::to_integer(command.GetArgumentAtIndex(0), user_id)) {
5895 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5896 command.GetArgumentAtIndex(0));
5897 return;
5898 }
5899 hook_sp = target.GetHookByID(user_id);
5900 if (!hook_sp) {
5901 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5902 command.GetArgumentAtIndex(0));
5903 return;
5904 }
5905 }
5906
5907 // Reject trigger modification on scripted hooks.
5908 if (hook_sp->GetHookKind() != Target::Hook::HookKind::CommandBased) {
5909 result.AppendError("cannot modify triggers on a scripted hook; "
5910 "triggers are determined by the class methods");
5911 return;
5912 }
5913 auto *cmd_hook = static_cast<Target::HookCommandLine *>(hook_sp.get());
5914
5915 if (!m_options.m_enable_trigger.empty()) {
5916 uint32_t trigger = ParseTriggerName(m_options.m_enable_trigger);
5917 if (!trigger) {
5918 result.AppendErrorWithFormat("unknown trigger name: \"%s\". "
5919 "Valid names: load, unload, stop",
5920 m_options.m_enable_trigger.c_str());
5921 return;
5922 }
5923 cmd_hook->AddTrigger(trigger);
5924 }
5925
5926 if (!m_options.m_disable_trigger.empty()) {
5927 uint32_t trigger = ParseTriggerName(m_options.m_disable_trigger);
5928 if (!trigger) {
5929 result.AppendErrorWithFormat("unknown trigger name: \"%s\". "
5930 "Valid names: load, unload, stop",
5931 m_options.m_disable_trigger.c_str());
5932 return;
5933 }
5934 cmd_hook->RemoveTrigger(trigger);
5935 }
5936
5938 }
5939
5940private:
5942};
5943
5944#pragma mark CommandObjectTargetHookList
5945
5947public:
5949 : CommandObjectParsed(interpreter, "target hook list", "List all hooks.",
5950 "target hook list") {}
5951
5952 ~CommandObjectTargetHookList() override = default;
5953
5954protected:
5955 void DoExecute(Args &command, CommandReturnObject &result) override {
5956 Target &target = GetTarget();
5957 size_t num_hooks = target.GetNumHooks();
5958 if (num_hooks == 0) {
5959 result.GetOutputStream().PutCString("No hooks.\n");
5960 } else {
5961 for (size_t i = 0; i < num_hooks; i++) {
5962 Target::HookSP hook_sp = target.GetHookAtIndex(i);
5963 if (hook_sp)
5964 hook_sp->GetDescription(result.GetOutputStream(),
5966 }
5967 }
5969 }
5970};
5971
5972#pragma mark CommandObjectMultiwordTargetHooks
5973
5975public:
5978 interpreter, "target hook",
5979 "Commands for operating on target hooks.",
5980 "target hook <subcommand> [<subcommand-options>]") {
5982 "add", CommandObjectSP(new CommandObjectTargetHookAdd(interpreter)));
5984 interpreter)));
5985 LoadSubCommand("disable",
5987 interpreter, false, "target hook disable",
5988 "Disable a hook.", "target hook disable [<id> ...]")));
5989 LoadSubCommand("enable",
5991 interpreter, true, "target hook enable",
5992 "Enable a hook.", "target hook enable [<id> ...]")));
5994 "list", CommandObjectSP(new CommandObjectTargetHookList(interpreter)));
5996 interpreter)));
5997 }
5998
6000};
6001
6002#pragma mark CommandObjectTargetDumpTypesystem
6003
6004/// Dumps the TypeSystem of the selected Target.
6006public:
6009 interpreter, "target dump typesystem",
6010 "Dump the state of the target's internal type system. Intended to "
6011 "be used for debugging LLDB itself.",
6012 nullptr, eCommandRequiresTarget) {}
6013
6015
6016protected:
6017 void DoExecute(Args &command, CommandReturnObject &result) override {
6018 // Go over every scratch TypeSystem and dump to the command output.
6019 for (lldb::TypeSystemSP ts : GetTarget().GetScratchTypeSystems())
6020 if (ts)
6021 ts->Dump(result.GetOutputStream().AsRawOstream(), "",
6022 GetCommandInterpreter().GetDebugger().GetUseColor());
6023
6025 }
6026};
6027
6028#pragma mark CommandObjectTargetDumpSectionLoadList
6029
6030/// Dumps the SectionLoadList of the selected Target.
6032public:
6035 interpreter, "target dump section-load-list",
6036 "Dump the state of the target's internal section load list. "
6037 "Intended to be used for debugging LLDB itself.",
6038 nullptr, eCommandRequiresTarget) {}
6039
6041
6042protected:
6043 void DoExecute(Args &command, CommandReturnObject &result) override {
6044 Target &target = GetTarget();
6045 target.DumpSectionLoadList(result.GetOutputStream());
6047 }
6048};
6049
6050#pragma mark CommandObjectTargetDump
6051
6052/// Multi-word command for 'target dump'.
6054public:
6055 // Constructors and Destructors
6058 interpreter, "target dump",
6059 "Commands for dumping information about the target.",
6060 "target dump [typesystem|section-load-list]") {
6062 "typesystem",
6064 LoadSubCommand("section-load-list",
6066 interpreter)));
6067 }
6068
6069 ~CommandObjectTargetDump() override = default;
6070};
6071
6072#pragma mark CommandObjectTargetFrameProvider
6073
6074#define LLDB_OPTIONS_target_frame_provider_register
6075#include "CommandOptions.inc"
6076
6078public:
6081 interpreter, "target frame-provider register",
6082 "Register frame provider for all threads in this target.", nullptr,
6083 eCommandRequiresTarget),
6084
6085 m_class_options("target frame-provider", true, 'C', 'k', 'v', 0) {
6088 m_all_options.Finalize();
6089 }
6090
6092
6093 Options *GetOptions() override { return &m_all_options; }
6094
6095 std::optional<std::string> GetRepeatCommand(Args &current_command_args,
6096 uint32_t index) override {
6097 return std::string("");
6098 }
6099
6100protected:
6101 void DoExecute(Args &command, CommandReturnObject &result) override {
6102 ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
6103 m_class_options.GetName(), m_class_options.GetStructuredData());
6104
6105 Target *target = m_exe_ctx.GetTargetPtr();
6106 if (!target)
6107 target = &GetDebugger().GetDummyTarget();
6108
6109 // Create the interface for calling static methods.
6111 GetDebugger()
6114
6115 // Create a descriptor from the metadata (applies to all threads by
6116 // default).
6117 ScriptedFrameProviderDescriptor descriptor(metadata_sp);
6118 descriptor.interface_sp = interface_sp;
6119
6120 auto id_or_err = target->AddScriptedFrameProviderDescriptor(descriptor);
6121 if (!id_or_err) {
6122 result.SetError(id_or_err.takeError());
6123 return;
6124 }
6125
6127 "successfully registered scripted frame provider '{0}' for target",
6128 m_class_options.GetName().c_str());
6129 }
6130
6133};
6134
6136public:
6139 interpreter, "target frame-provider clear",
6140 "Clear all registered frame providers from this target.", nullptr,
6141 eCommandRequiresTarget) {}
6142
6144
6145protected:
6146 void DoExecute(Args &command, CommandReturnObject &result) override {
6147 Target *target = m_exe_ctx.GetTargetPtr();
6148 if (!target) {
6149 result.AppendError("invalid target");
6150 return;
6151 }
6152
6154
6156 }
6157};
6158
6160public:
6163 interpreter, "target frame-provider list",
6164 "List all registered frame providers for the target.", nullptr,
6165 eCommandRequiresTarget) {}
6166
6168
6169protected:
6170 void DoExecute(Args &command, CommandReturnObject &result) override {
6171 Target *target = m_exe_ctx.GetTargetPtr();
6172 if (!target)
6173 target = &GetDebugger().GetDummyTarget();
6174
6175 const auto &descriptors = target->GetScriptedFrameProviderDescriptors();
6176 if (descriptors.empty()) {
6177 result.AppendMessage("no frame providers registered for this target.");
6179 return;
6180 }
6181
6182 Stream &strm = result.GetOutputStream();
6183 strm << llvm::formatv("{0} frame provider(s) registered:\n\n",
6184 descriptors.size());
6185
6186 for (const auto &entry : descriptors) {
6187 const ScriptedFrameProviderDescriptor &descriptor = entry.second;
6188 descriptor.Dump(&strm);
6189 strm.PutChar('\n');
6190 }
6191
6193 }
6194};
6195
6197public:
6200 interpreter, "target frame-provider remove",
6201 "Remove a registered frame provider from the target by id.",
6202 "target frame-provider remove <provider-id>",
6203 eCommandRequiresTarget) {
6205 }
6206
6208
6209protected:
6210 void DoExecute(Args &command, CommandReturnObject &result) override {
6211 Target *target = m_exe_ctx.GetTargetPtr();
6212 if (!target)
6213 target = &GetDebugger().GetDummyTarget();
6214
6215 std::vector<uint32_t> removed_provider_ids;
6216 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
6217 uint32_t provider_id = 0;
6218 if (!llvm::to_integer(command[i].ref(), provider_id)) {
6219 result.AppendError("target frame-provider remove requires integer "
6220 "provider id argument");
6221 return;
6222 }
6223
6224 if (!target->RemoveScriptedFrameProviderDescriptor(provider_id)) {
6225 result.AppendErrorWithFormat(
6226 "no frame provider named '%u' found in target", provider_id);
6227 return;
6228 }
6229 removed_provider_ids.push_back(provider_id);
6230 }
6231
6232 if (size_t num_removed_providers = removed_provider_ids.size()) {
6234 "Successfully removed {0} frame-providers.", num_removed_providers);
6236 } else {
6237 result.AppendError("0 frame providers removed.\n");
6238 }
6239 }
6240};
6241
6243public:
6246 interpreter, "target frame-provider",
6247 "Commands for registering and viewing frame providers for the "
6248 "target.",
6249 "target frame-provider [<sub-command-options>] ") {
6250 LoadSubCommand("register",
6252 interpreter)));
6253 LoadSubCommand("clear",
6255 new CommandObjectTargetFrameProviderClear(interpreter)));
6257 "list",
6260 "remove", CommandObjectSP(
6261 new CommandObjectTargetFrameProviderRemove(interpreter)));
6262 }
6263
6265};
6266
6267#pragma mark CommandObjectMultiwordTarget
6268
6269// CommandObjectMultiwordTarget
6270
6272 CommandInterpreter &interpreter)
6273 : CommandObjectMultiword(interpreter, "target",
6274 "Commands for operating on debugger targets.",
6275 "target <subcommand> [<subcommand-options>]") {
6276 LoadSubCommand("create",
6277 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
6278 LoadSubCommand("delete",
6279 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
6280 LoadSubCommand("dump",
6281 CommandObjectSP(new CommandObjectTargetDump(interpreter)));
6283 "frame-provider",
6285 LoadSubCommand("list",
6286 CommandObjectSP(new CommandObjectTargetList(interpreter)));
6287 LoadSubCommand("select",
6288 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
6289 LoadSubCommand("show-launch-environment",
6291 interpreter)));
6293 "stop-hook",
6296 interpreter)));
6297 LoadSubCommand("modules",
6299 LoadSubCommand("symbols",
6301 LoadSubCommand("variable",
6303}
6304
static bool GetSeparateDebugInfoList(StructuredData::Array &list, Module *module, bool errors_only, bool load_all_debug_info)
static uint32_t DumpTargetList(TargetList &target_list, bool show_stopped_process_status, Stream &strm)
static void DumpModuleUUID(Stream &strm, Module *module)
static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, Module *module)
static void DumpModuleArchitecture(Stream &strm, Module *module, bool full_triple, uint32_t width)
static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, uint32_t resolve_mask, lldb::addr_t raw_addr, lldb::addr_t offset, bool verbose, bool all_ranges)
static void DumpTargetInfo(uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose, bool all_ranges)
static size_t LookupTypeInModule(Target *target, CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name_cstr, bool name_is_regex)
static bool DumpModuleSymbolFile(Stream &strm, Module *module)
static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static void DumpDwoFilesTable(Stream &strm, StructuredData::Array &dwo_listings)
static size_t LookupFunctionInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, const ModuleFunctionSearchOptions &options, bool verbose, bool all_ranges)
static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter, Stream &strm, Module &module, const char *name_cstr, bool name_is_regex)
static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, lldb::DescriptionLevel desc_level)
static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list)
static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines, bool verbose, bool all_ranges)
static void DumpSymbolContextList(ExecutionContextScope *exe_scope, Stream &strm, const SymbolContextList &sc_list, bool verbose, bool all_ranges, std::optional< Stream::HighlightSettings > settings=std::nullopt)
static void DumpOsoFilesTable(Stream &strm, StructuredData::Array &oso_listings)
static size_t FindModulesByName(Target *target, const char *module_name, ModuleList &module_list, bool check_global_list)
static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order, Mangled::NamePreference name_preference)
static llvm::raw_ostream & error(Stream &strm)
#define INTERRUPT_REQUESTED(debugger,...)
This handy define will keep you from having to generate a report for the interruption by hand.
Definition Debugger.h:494
#define LLDB_LOGF(log,...)
Definition Log.h:378
#define LLDB_SCOPED_TIMERF(...)
Definition Timer.h:86
CommandObjectMultiwordTargetHooks(CommandInterpreter &interpreter)
~CommandObjectMultiwordTargetHooks() override=default
~CommandObjectMultiwordTargetStopHooks() override=default
CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
OptionGroupPlatform m_platform_options
~CommandObjectTargetCreate() override=default
OptionGroupArchitecture m_arch_option
CommandObjectTargetCreate(CommandInterpreter &interpreter)
OptionGroupDependents m_add_dependents
void DoExecute(Args &command, CommandReturnObject &result) override
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTargetDelete(CommandInterpreter &interpreter)
~CommandObjectTargetDelete() override=default
Dumps the SectionLoadList of the selected Target.
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetDumpSectionLoadList() override=default
CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter)
Dumps the TypeSystem of the selected Target.
CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
~CommandObjectTargetDumpTypesystem() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
Multi-word command for 'target dump'.
CommandObjectTargetDump(CommandInterpreter &interpreter)
~CommandObjectTargetDump() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetFrameProviderClear(CommandInterpreter &interpreter)
~CommandObjectTargetFrameProviderClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetFrameProviderList() override=default
CommandObjectTargetFrameProviderList(CommandInterpreter &interpreter)
OptionGroupPythonClassWithDict m_class_options
~CommandObjectTargetFrameProviderRegister() override=default
CommandObjectTargetFrameProviderRegister(CommandInterpreter &interpreter)
std::optional< std::string > GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetFrameProviderRemove() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetFrameProviderRemove(CommandInterpreter &interpreter)
~CommandObjectTargetFrameProvider() override=default
CommandObjectTargetFrameProvider(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectTargetHookAdd(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
OptionGroupPythonClassWithDict m_python_class_options
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
~CommandObjectTargetHookAdd() override=default
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectTargetHookDelete(CommandInterpreter &interpreter)
~CommandObjectTargetHookDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetHookEnableDisable() override=default
CommandObjectTargetHookEnableDisable(CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax)
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetHookList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetHookList() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
Modify trigger settings on a hook.
void DoExecute(Args &command, CommandReturnObject &result) override
static uint32_t ParseTriggerName(llvm::StringRef name)
CommandObjectTargetHookModify(CommandInterpreter &interpreter)
~CommandObjectTargetHookModify() override=default
CommandObjectTargetList(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetList() override=default
CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetModulesAdd() override=default
CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesDumpClangAST() override=default
~CommandObjectTargetModulesDumpClangPCMInfo() override=default
CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
~CommandObjectTargetModulesDumpLineTable() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesDumpObjfile() override=default
CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSections() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override=default
CommandObjectTargetModulesDumpSeparateDebugInfoFiles(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSymfile() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSymtab() override=default
~CommandObjectTargetModulesDump() override=default
CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
~CommandObjectTargetModulesImageSearchPaths() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
std::vector< std::pair< char, uint32_t > > FormatWidthCollection
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectTargetModulesList(CommandInterpreter &interpreter)
~CommandObjectTargetModulesList() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void PrintModule(Target &target, Module *module, int indent, Stream &strm)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetModulesLoad() override=default
CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
void OptionParsingStarting(ExecutionContext *execution_context) override
Status OptionParsingFinished(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
bool LookupInModule(CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
~CommandObjectTargetModulesLookup() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, uint32_t flags=0)
~CommandObjectTargetModulesModuleAutoComplete() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSearchPathsAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsClear() override=default
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSearchPathsInsert() override=default
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsList() override=default
CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsQuery() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesShowUnwind() override=default
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, uint32_t flags)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSourceFileAutoComplete() override=default
~CommandObjectTargetModules() override=default
const CommandObjectTargetModules & operator=(const CommandObjectTargetModules &)=delete
CommandObjectTargetModules(const CommandObjectTargetModules &)=delete
CommandObjectTargetModules(CommandInterpreter &interpreter)
~CommandObjectTargetSelect() override=default
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTargetSelect(CommandInterpreter &interpreter)
CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetShowLaunchEnvironment() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
~CommandObjectTargetStopHookAdd() override=default
OptionGroupPythonClassWithDict m_python_class_options
void DoExecute(Args &command, CommandReturnObject &result) override
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
~CommandObjectTargetStopHookDelete() override=default
~CommandObjectTargetStopHookEnableDisable() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetStopHookList() override=default
CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush)
bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, CommandReturnObject &result, bool &flush)
bool AddSymbolsForStack(CommandReturnObject &result, bool &flush)
CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush)
~CommandObjectTargetSymbolsAdd() override=default
void DoExecute(Args &args, CommandReturnObject &result) override
bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush, CommandReturnObject &result)
bool AddSymbolsForFile(CommandReturnObject &result, bool &flush)
const CommandObjectTargetSymbols & operator=(const CommandObjectTargetSymbols &)=delete
CommandObjectTargetSymbols(CommandInterpreter &interpreter)
~CommandObjectTargetSymbols() override=default
CommandObjectTargetSymbols(const CommandObjectTargetSymbols &)=delete
void DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, CommandReturnObject &result)
void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
static size_t GetVariableCallback(void *baton, const char *name, VariableList &variable_list)
static const uint32_t SHORT_OPTION_SHLB
CommandObjectTargetVariable(CommandInterpreter &interpreter)
OptionGroupFileList m_option_shared_libraries
void DoExecute(Args &args, CommandReturnObject &result) override
OptionGroupFileList m_option_compile_units
static const uint32_t SHORT_OPTION_FILE
OptionGroupValueObjectDisplay m_varobj_options
~CommandObjectTargetVariable() override=default
~OptionGroupDependents() override=default
OptionGroupDependents()=default
LoadDependentFiles m_load_dependent_files
OptionGroupDependents(const OptionGroupDependents &)=delete
const OptionGroupDependents & operator=(const OptionGroupDependents &)=delete
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t, const char *, ExecutionContext *)=delete
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc)
Some targets might use bits in a code address to indicate a mode switch.
Definition ABI.cpp:141
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:301
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition Address.cpp:1034
@ DumpStyleFileAddress
Display as the file address (if any).
Definition Address.h:87
@ DumpStyleSectionNameOffset
Display as the section name + offset.
Definition Address.h:74
@ DumpStyleDetailedSymbolContext
Detailed symbol context information for an address for all symbol context members.
Definition Address.h:112
@ DumpStyleInvalid
Invalid dump style.
Definition Address.h:68
@ DumpStyleModuleWithFileAddress
Display as the file address with the module name prepended (if any).
Definition Address.h:93
@ DumpStyleResolvedDescription
Display the details about what an address resolves to.
Definition Address.h:104
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
Definition Address.cpp:396
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:273
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:281
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:690
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:370
void DumpTriple(llvm::raw_ostream &s) const
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition ArchSpec.cpp:557
A command line argument class.
Definition Args.h:33
void Shift()
Shifts the first argument C string value of the array off the argument array.
Definition Args.cpp:295
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
bool Confirm(llvm::StringRef message, bool default_answer)
ExecutionContext GetExecutionContext() const
CommandObjectMultiwordTarget(CommandInterpreter &interpreter)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
std::vector< CommandArgumentData > CommandArgumentEntry
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
std::vector< CommandArgumentEntry > m_arguments
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
virtual void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector)
The default version handles argument definitions that have only one argument type,...
void AppendMessage(llvm::StringRef in_string)
void AppendError(llvm::StringRef in_string)
const ValueObjectList & GetValueObjectList() const
void AppendWarningWithFormatv(const char *format, Args &&...args)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void void AppendMessageWithFormatv(const char *format, Args &&...args)
void AppendWarning(llvm::StringRef in_string)
void AppendErrorWithFormatv(const char *format, Args &&...args)
A class that describes a compilation unit.
Definition CompileUnit.h:43
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
"lldb/Utility/ArgCompletionRequest.h"
void TryCompleteCurrentArg(llvm::StringRef completion, llvm::StringRef description="")
Adds a possible completion string if the completion would complete the current argument.
A uniqued constant string class.
Definition ConstString.h:40
void Dump(Stream *s, const char *value_if_empty=nullptr) const
Dump the object description to a stream.
bool IsEmpty() const
Test for empty string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
A class to manage flag bits.
Definition Debugger.h:100
TargetList & GetTargetList()
Get accessor for the target list.
Definition Debugger.h:224
bool GetUseColor() const
Definition Debugger.cpp:525
llvm::StringRef GetRegexMatchAnsiSuffix() const
Definition Debugger.cpp:630
Target & GetDummyTarget()
Definition Debugger.h:536
llvm::StringRef GetRegexMatchAnsiPrefix() const
Definition Debugger.cpp:624
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
DumpValueObjectOptions & SetRootValueObjectName(const char *name=nullptr)
DumpValueObjectOptions & SetFormat(lldb::Format format=lldb::eFormatDefault)
A class that measures elapsed time in an exception safe way.
Definition Statistics.h:76
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
Target * GetTargetPtr() const
Returns a pointer to the target object.
A file collection class.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
size_t GetSize() const
Get the number of files in the file list.
A file utility class.
Definition FileSpec.h:57
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
void SetDirectory(ConstString directory)
Directory string set accessor.
Definition FileSpec.cpp:342
const ConstString & GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:250
const ConstString & GetDirectory() const
Directory string const get accessor.
Definition FileSpec.h:234
ConstString GetFileNameStrippingExtension() const
Return the filename without the extension part.
Definition FileSpec.cpp:414
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
void Dump(llvm::raw_ostream &s) const
Dump this object to a Stream.
Definition FileSpec.cpp:325
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Definition FileSpec.cpp:410
void SetFilename(ConstString filename)
Filename string set accessor.
Definition FileSpec.cpp:352
bool ResolveExecutableLocation(FileSpec &file_spec)
Call into the Host to see if it can help find the file.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
@ eOpenOptionReadOnly
Definition File.h:51
IOHandlerDelegateMultiline(llvm::StringRef end_line, Completion completion=Completion::None)
Definition IOHandler.h:289
A delegate class for use with IOHandler subclasses.
Definition IOHandler.h:184
lldb::LockableStreamFileSP GetErrorStreamFileSP()
Definition IOHandler.cpp:95
lldb::LockableStreamFileSP GetOutputStreamFileSP()
Definition IOHandler.cpp:93
void SetIsDone(bool b)
Definition IOHandler.h:81
A line table class.
Definition LineTable.h:25
void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level)
A collection class for Module objects.
Definition ModuleList.h:125
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const
ModuleIterableNoLocking ModulesNoLocking() const
Definition ModuleList.h:576
static bool ModuleIsInCache(const Module *module_ptr)
void FindGlobalVariables(ConstString name, size_t max_matches, VariableList &variable_list) const
Find global and static variables by name.
std::recursive_mutex & GetMutex() const
Definition ModuleList.h:252
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Finds the first module whose file specification matches module_spec.
lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const
Get the module shared pointer for the module at index idx without acquiring the ModuleList mutex.
void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const
Find compile units by partial or full path.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
Module * GetModulePointerAtIndex(size_t idx) const
Get the module pointer for the module at index idx.
void FindModules(const ModuleSpec &module_spec, ModuleList &matching_module_list) const
Finds modules whose file specification matches module_spec.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
static size_t RemoveOrphanSharedModules(bool mandatory)
static void FindSharedModules(const ModuleSpec &module_spec, ModuleList &matching_module_list)
bool LoadScriptingResourcesInTarget(Target *target, std::list< Status > &errors, bool continue_on_error=true)
ModuleIterable Modules() const
Definition ModuleList.h:570
size_t GetSize() const
Gets the size of the module list.
bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const
Definition ModuleSpec.h:356
bool FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
Definition ModuleSpec.h:366
FileSpec & GetPlatformFileSpec()
Definition ModuleSpec.h:69
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
FileSpec * GetFileSpecPtr()
Definition ModuleSpec.h:51
FileSpec & GetSymbolFileSpec()
Definition ModuleSpec.h:81
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:90
const lldb_private::UUID & GetUUID()
Get a reference to the UUID value contained in this object.
Definition Module.cpp:344
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
Definition Module.cpp:984
static Module * GetAllocatedModuleAtIndex(size_t idx)
Definition Module.cpp:123
static std::recursive_mutex & GetAllocationModuleCollectionMutex()
Definition Module.cpp:105
bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr)
Definition Module.cpp:431
Symtab * GetSymtab(bool can_create=true)
Get the module's symbol table.
Definition Module.cpp:1011
bool MatchesModuleSpec(const ModuleSpec &module_ref)
Definition Module.cpp:1442
static size_t GetNumberAllocatedModules()
Definition Module.cpp:117
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
Definition Module.cpp:1026
std::string GetSpecificationDescription() const
Get the module path and object name.
Definition Module.cpp:1028
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition Module.h:446
const llvm::sys::TimePoint & GetModificationTime() const
Definition Module.h:482
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
virtual void Dump(Stream *s)=0
Dump a description of this object to a Stream.
virtual std::vector< LoadableData > GetLoadableData(Target &target)
Loads this objfile to memory.
virtual lldb_private::Address GetEntryPointAddress()
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
Definition ObjectFile.h:452
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:280
static ModuleSpecList GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataExtractorSP=lldb::DataExtractorSP())
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
Definition ObjectFile.h:462
static const uint32_t OPTION_GROUP_GDB_FMT
static const uint32_t OPTION_GROUP_FORMAT
A command line option parsing protocol class.
Definition Options.h:58
std::vector< Option > m_getopt_table
Definition Options.h:198
void Insert(llvm::StringRef path, llvm::StringRef replacement, uint32_t insert_idx, bool notify)
void Append(llvm::StringRef path, llvm::StringRef replacement, bool notify)
bool RemapPath(ConstString path, ConstString &new_path) const
bool GetPathsAtIndex(uint32_t idx, ConstString &path, ConstString &new_path) const
void Dump(Stream *s, int pair_index=-1)
static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup=true, bool copy_executable=true)
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
A plug-in interface definition class for debugging a process.
Definition Process.h:356
ThreadList & GetThreadList()
Definition Process.h:2347
void Flush()
Flush all data in the process.
Definition Process.cpp:6290
lldb::StateType GetState()
Get accessor for the current process state.
Definition Process.cpp:1278
const lldb::ABISP & GetABI()
Definition Process.cpp:1482
bool IsValid() const
Test if this object contains a valid regular expression.
virtual lldb::ScriptedFrameProviderInterfaceSP CreateScriptedFrameProviderInterface()
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
Definition Section.cpp:556
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
Definition Section.cpp:642
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:405
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t PutChar(char ch)
Definition Stream.cpp:131
void SetIndentLevel(unsigned level)
Set the current indentation level.
Definition Stream.cpp:196
void PutCStringColorHighlighted(llvm::StringRef text, std::optional< HighlightSettings > settings=std::nullopt)
Output a C string to the stream with color highlighting.
Definition Stream.cpp:73
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition Stream.cpp:204
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition Stream.cpp:201
unsigned GetIndentLevel() const
Get the current indentation level.
Definition Stream.cpp:193
void AddItem(const ObjectSP &item)
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
void SortTypeList(TypeMap &type_map, TypeList &type_list) const
Sorts the types in TypeMap according to SymbolContext to TypeList.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
Symbol * symbol
The Symbol for a given query.
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
virtual ObjectFile * GetObjectFile()=0
bool ValueIsAddress() const
Definition Symbol.cpp:165
bool GetByteSizeIsValid() const
Definition Symbol.h:209
Address & GetAddressRef()
Definition Symbol.h:73
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:431
ConstString GetDisplayName() const
Definition Symbol.cpp:169
uint64_t GetRawValue() const
Get the raw value of the symbol from the symbol table.
Definition Symbol.h:110
Symbol * SymbolAtIndex(size_t idx)
Definition Symtab.cpp:225
uint32_t AppendSymbolIndexesWithName(ConstString symbol_name, std::vector< uint32_t > &matches)
Definition Symtab.cpp:679
uint32_t AppendSymbolIndexesMatchingRegExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, std::vector< uint32_t > &indexes, Mangled::NamePreference name_preference=Mangled::ePreferDemangled)
Definition Symtab.cpp:746
lldb::TargetSP GetTargetAtIndex(uint32_t index) const
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
void SetSelectedTarget(uint32_t index)
bool DeleteTarget(lldb::TargetSP &target_sp)
Delete a Target object from the list.
lldb::TargetSP GetSelectedTarget()
size_t GetNumTargets() const
bool GetUserSpecifiedTrapHandlerNames(Args &args) const
Definition Target.cpp:5704
Environment GetEnvironment() const
Definition Target.cpp:5352
void SetActionFromStrings(const std::vector< std::string > &strings)
Populate the command list from a vector of individual command strings.
Definition Target.cpp:4517
void SetActionFromString(const std::string &strings)
Definition Target.cpp:4239
void SetActionFromStrings(const std::vector< std::string > &strings)
Definition Target.cpp:4243
Status SetScriptCallback(std::string class_name, StructuredData::ObjectSP extra_args_sp)
Definition Target.cpp:4284
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
Definition Target.cpp:1910
llvm::Expected< uint32_t > AddScriptedFrameProviderDescriptor(const ScriptedFrameProviderDescriptor &descriptor)
Add or update a scripted frame provider descriptor for this target.
Definition Target.cpp:3849
Module * GetExecutableModulePointer()
Definition Target.cpp:1610
bool RemoveHookByID(lldb::user_id_t uid)
Definition Target.cpp:4742
PathMappingList & GetImageSearchPathList()
Definition Target.cpp:2660
size_t GetNumHooks() const
Definition Target.h:1932
std::shared_ptr< StopHook > StopHookSP
Definition Target.h:1741
void SymbolsDidLoad(ModuleList &module_list)
Definition Target.cpp:1938
const std::vector< StopHookSP > GetStopHooks(bool internal=false) const
Definition Target.cpp:3187
const llvm::MapVector< uint32_t, ScriptedFrameProviderDescriptor > & GetScriptedFrameProviderDescriptors() const
Get all scripted frame provider descriptors for this target.
Definition Target.cpp:3910
bool RemoveScriptedFrameProviderDescriptor(uint32_t id)
Remove a scripted frame provider descriptor by id.
Definition Target.cpp:3885
HookSP CreateHook(Hook::HookKind kind)
Definition Target.cpp:4720
void DumpSectionLoadList(Stream &s)
Definition Target.cpp:5984
bool SetHookEnabledStateByID(lldb::user_id_t uid, bool enabled)
Definition Target.cpp:4764
const lldb::ProcessSP & GetProcessSP() const
Definition Target.cpp:327
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition Target.cpp:2410
void UndoCreateStopHook(lldb::user_id_t uid)
If you tried to create a stop hook, and that failed, call this to remove the stop hook,...
Definition Target.cpp:3139
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
Definition Target.cpp:3449
HookSP GetHookByID(lldb::user_id_t uid)
Definition Target.cpp:4749
bool SetStopHookActiveStateByID(lldb::user_id_t uid, bool active_state)
Definition Target.cpp:3163
void SetAllStopHooksActiveState(bool active_state)
Definition Target.cpp:3174
StopHookSP CreateStopHook(StopHook::StopHookKind kind, bool internal=false)
Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to the new hook.
Definition Target.cpp:3117
void SetAllHooksEnabledState(bool enabled)
Definition Target.cpp:4772
void UndoCreateHook(lldb::user_id_t uid)
Removes the most recently created hook.
Definition Target.cpp:4735
HookSP GetHookAtIndex(size_t index)
Definition Target.cpp:4756
lldb::PlatformSP GetPlatform()
Definition Target.h:1972
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1240
const ArchSpec & GetArchitecture() const
Definition Target.h:1282
const std::string & GetLabel() const
Definition Target.h:683
void ClearScriptedFrameProviderDescriptors()
Clear all scripted frame provider descriptors for this target.
Definition Target.cpp:3898
std::shared_ptr< Hook > HookSP
Definition Target.h:1913
lldb::ProcessSP CalculateProcess() override
Definition Target.cpp:2649
bool SetSectionLoadAddress(const lldb::SectionSP &section, lldb::addr_t load_addr, bool warn_multiple=false)
Definition Target.cpp:3460
bool RemoveStopHookByID(lldb::user_id_t uid)
Definition Target.cpp:3146
lldb::ThreadSP GetSelectedThread()
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
void SetIndex(uint32_t index)
Definition ThreadSpec.h:47
void SetName(llvm::StringRef name)
Definition ThreadSpec.h:51
void SetTID(lldb::tid_t tid)
Definition ThreadSpec.h:49
void SetQueueName(llvm::StringRef queue_name)
Definition ThreadSpec.h:53
uint32_t GetSize() const
Definition TypeList.cpp:36
bool Empty() const
Definition TypeList.h:35
TypeIterable Types()
Definition TypeList.h:42
lldb::TypeSP GetTypeAtIndex(uint32_t idx)
Definition TypeList.cpp:42
A class that contains all state required for type lookups.
Definition Type.h:104
This class tracks the state and results of a TypeQuery.
Definition Type.h:344
TypeMap & GetTypeMap()
Definition Type.h:386
void Dump(Stream &s) const
Definition UUID.cpp:68
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
bool IsValid() const
Definition UUID.h:69
lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress(const Address &addr, const SymbolContext &sc)
lldb::FuncUnwindersSP GetUncachedFuncUnwindersContainingAddress(const Address &addr, const SymbolContext &sc)
A collection of ValueObject values that.
void Append(const lldb::ValueObjectSP &val_obj_sp)
lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
lldb::VariableSP GetVariableAtIndex(size_t idx) const
static Status GetValuesForVariableExpressionPath(llvm::StringRef variable_expr_path, ExecutionContextScope *scope, GetVariableCallback callback, void *baton, VariableList &variable_list, ValueObjectList &valobj_list)
Definition Variable.cpp:335
#define LLDB_OPT_SET_1
#define LLDB_OPT_SET_FROM_TO(A, B)
#define LLDB_OPT_SET_2
#define LLDB_INVALID_LINE_NUMBER
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_INDEX32
#define LLDB_OPT_SET_ALL
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:327
std::vector< OptionArgElement > OptionElementVector
Definition Options.h:43
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
Definition State.cpp:89
void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size, const char *prefix=nullptr, const char *suffix=nullptr)
Output an address value to this stream.
Definition Stream.cpp:108
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
std::string toString(FormatterBytecode::OpCodes op)
@ eSourceFileCompletion
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
@ eDescriptionLevelBrief
@ eDescriptionLevelFull
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ScriptedMetadata > ScriptedMetadataSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Format
Display format definitions.
std::shared_ptr< lldb_private::Platform > PlatformSP
StateType
Process and Thread States.
std::shared_ptr< lldb_private::FuncUnwinders > FuncUnwindersSP
std::shared_ptr< lldb_private::Type > TypeSP
std::shared_ptr< lldb_private::Process > ProcessSP
@ eReturnStatusFailed
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
uint64_t pid_t
Definition lldb-types.h:83
@ eArgTypeOldPathPrefix
@ eArgTypeNewPathPrefix
@ eArgTypeUnsignedInteger
@ eArgTypeDirectoryName
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
uint64_t tid_t
Definition lldb-types.h:84
std::shared_ptr< lldb_private::Module > ModuleSP
Used to build individual command argument lists.
Options used by Module::FindFunctions.
Definition Module.h:66
bool include_inlines
Include inlined functions.
Definition Module.h:70
bool include_symbols
Include the symbol table.
Definition Module.h:68
static int64_t ToOptionEnum(llvm::StringRef s, const OptionEnumValues &enum_values, int32_t fail_value, Status &error)
static lldb::addr_t ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error_ptr)
Try to parse an address.
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)
This struct contains the metadata needed to instantiate a frame provider and optional filters to cont...
void Dump(Stream *s) const
Dump a description of this descriptor to the given stream.
lldb::ScriptedFrameProviderInterfaceSP interface_sp
Interface for calling static methods on the provider class.
Struct to store information for color highlighting in the stream.
Definition Stream.h:37
#define PATH_MAX