1 //===-- CommandObjectTarget.cpp -------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectTarget.h"
11 #include "lldb/Core/Address.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/IOHandler.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/DataFormatters/ValueObjectPrinter.h"
19 #include "lldb/Host/OptionParser.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
22 #include "lldb/Interpreter/CommandReturnObject.h"
23 #include "lldb/Interpreter/OptionArgParser.h"
24 #include "lldb/Interpreter/OptionGroupArchitecture.h"
25 #include "lldb/Interpreter/OptionGroupBoolean.h"
26 #include "lldb/Interpreter/OptionGroupFile.h"
27 #include "lldb/Interpreter/OptionGroupFormat.h"
28 #include "lldb/Interpreter/OptionGroupPlatform.h"
29 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
30 #include "lldb/Interpreter/OptionGroupString.h"
31 #include "lldb/Interpreter/OptionGroupUInt64.h"
32 #include "lldb/Interpreter/OptionGroupUUID.h"
33 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
34 #include "lldb/Interpreter/OptionGroupVariable.h"
35 #include "lldb/Interpreter/Options.h"
36 #include "lldb/Symbol/CompileUnit.h"
37 #include "lldb/Symbol/FuncUnwinders.h"
38 #include "lldb/Symbol/LineTable.h"
39 #include "lldb/Symbol/ObjectFile.h"
40 #include "lldb/Symbol/SymbolFile.h"
41 #include "lldb/Symbol/UnwindPlan.h"
42 #include "lldb/Symbol/VariableList.h"
43 #include "lldb/Target/ABI.h"
44 #include "lldb/Target/Process.h"
45 #include "lldb/Target/RegisterContext.h"
46 #include "lldb/Target/SectionLoadList.h"
47 #include "lldb/Target/StackFrame.h"
48 #include "lldb/Target/Thread.h"
49 #include "lldb/Target/ThreadSpec.h"
50 #include "lldb/Utility/Args.h"
51 #include "lldb/Utility/ConstString.h"
52 #include "lldb/Utility/FileSpec.h"
53 #include "lldb/Utility/LLDBLog.h"
54 #include "lldb/Utility/State.h"
55 #include "lldb/Utility/Stream.h"
56 #include "lldb/Utility/StructuredData.h"
57 #include "lldb/Utility/Timer.h"
58 #include "lldb/ValueObject/ValueObjectVariable.h"
59 #include "lldb/lldb-enumerations.h"
60 #include "lldb/lldb-private-enumerations.h"
62 #include "clang/Frontend/CompilerInstance.h"
63 #include "clang/Frontend/CompilerInvocation.h"
64 #include "clang/Frontend/FrontendActions.h"
65 #include "clang/Serialization/ObjectFilePCHContainerReader.h"
66 #include "llvm/ADT/ScopeExit.h"
67 #include "llvm/ADT/StringRef.h"
68 #include "llvm/Support/FileSystem.h"
69 #include "llvm/Support/FormatAdapters.h"
73 using namespace lldb_private
;
75 static void DumpTargetInfo(uint32_t target_idx
, Target
*target
,
76 const char *prefix_cstr
,
77 bool show_stopped_process_status
, Stream
&strm
) {
78 const ArchSpec
&target_arch
= target
->GetArchitecture();
80 Module
*exe_module
= target
->GetExecutableModulePointer();
81 char exe_path
[PATH_MAX
];
82 bool exe_valid
= false;
84 exe_valid
= exe_module
->GetFileSpec().GetPath(exe_path
, sizeof(exe_path
));
87 ::strcpy(exe_path
, "<none>");
89 std::string formatted_label
= "";
90 const std::string
&label
= target
->GetLabel();
92 formatted_label
= " (" + label
+ ")";
95 strm
.Printf("%starget #%u%s: %s", prefix_cstr
? prefix_cstr
: "", target_idx
,
96 formatted_label
.data(), exe_path
);
98 uint32_t properties
= 0;
99 if (target_arch
.IsValid()) {
100 strm
.Printf(" ( arch=");
101 target_arch
.DumpTriple(strm
.AsRawOstream());
104 PlatformSP
platform_sp(target
->GetPlatform());
106 strm
.Format("{0}platform={1}", properties
++ > 0 ? ", " : " ( ",
107 platform_sp
->GetName());
109 ProcessSP
process_sp(target
->GetProcessSP());
110 bool show_process_status
= false;
112 lldb::pid_t pid
= process_sp
->GetID();
113 StateType state
= process_sp
->GetState();
114 if (show_stopped_process_status
)
115 show_process_status
= StateIsStoppedState(state
, true);
116 const char *state_cstr
= StateAsCString(state
);
117 if (pid
!= LLDB_INVALID_PROCESS_ID
)
118 strm
.Printf("%spid=%" PRIu64
, properties
++ > 0 ? ", " : " ( ", pid
);
119 strm
.Printf("%sstate=%s", properties
++ > 0 ? ", " : " ( ", state_cstr
);
122 strm
.PutCString(" )\n");
125 if (show_process_status
) {
126 const bool only_threads_with_stop_reason
= true;
127 const uint32_t start_frame
= 0;
128 const uint32_t num_frames
= 1;
129 const uint32_t num_frames_with_source
= 1;
130 const bool stop_format
= false;
131 process_sp
->GetStatus(strm
);
132 process_sp
->GetThreadStatus(strm
, only_threads_with_stop_reason
,
133 start_frame
, num_frames
, num_frames_with_source
,
138 static uint32_t DumpTargetList(TargetList
&target_list
,
139 bool show_stopped_process_status
, Stream
&strm
) {
140 const uint32_t num_targets
= target_list
.GetNumTargets();
142 TargetSP
selected_target_sp(target_list
.GetSelectedTarget());
143 strm
.PutCString("Current targets:\n");
144 for (uint32_t i
= 0; i
< num_targets
; ++i
) {
145 TargetSP
target_sp(target_list
.GetTargetAtIndex(i
));
147 bool is_selected
= target_sp
.get() == selected_target_sp
.get();
148 DumpTargetInfo(i
, target_sp
.get(), is_selected
? "* " : " ",
149 show_stopped_process_status
, strm
);
156 #define LLDB_OPTIONS_target_dependents
157 #include "CommandOptions.inc"
159 class OptionGroupDependents
: public OptionGroup
{
161 OptionGroupDependents() = default;
163 ~OptionGroupDependents() override
= default;
165 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
166 return llvm::ArrayRef(g_target_dependents_options
);
169 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_value
,
170 ExecutionContext
*execution_context
) override
{
173 // For compatibility no value means don't load dependents.
174 if (option_value
.empty()) {
175 m_load_dependent_files
= eLoadDependentsNo
;
179 const char short_option
=
180 g_target_dependents_options
[option_idx
].short_option
;
181 if (short_option
== 'd') {
182 LoadDependentFiles tmp_load_dependents
;
183 tmp_load_dependents
= (LoadDependentFiles
)OptionArgParser::ToOptionEnum(
184 option_value
, g_target_dependents_options
[option_idx
].enum_values
, 0,
187 m_load_dependent_files
= tmp_load_dependents
;
189 error
= Status::FromErrorStringWithFormat(
190 "unrecognized short option '%c'", short_option
);
196 Status
SetOptionValue(uint32_t, const char *, ExecutionContext
*) = delete;
198 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
199 m_load_dependent_files
= eLoadDependentsDefault
;
202 LoadDependentFiles m_load_dependent_files
;
205 OptionGroupDependents(const OptionGroupDependents
&) = delete;
206 const OptionGroupDependents
&
207 operator=(const OptionGroupDependents
&) = delete;
210 #pragma mark CommandObjectTargetCreate
212 class CommandObjectTargetCreate
: public CommandObjectParsed
{
214 CommandObjectTargetCreate(CommandInterpreter
&interpreter
)
215 : CommandObjectParsed(
216 interpreter
, "target create",
217 "Create a target using the argument as the main executable.",
219 m_platform_options(true), // Include the --platform option.
220 m_core_file(LLDB_OPT_SET_1
, false, "core", 'c', 0, eArgTypeFilename
,
221 "Fullpath to a core file to use for this target."),
222 m_label(LLDB_OPT_SET_1
, false, "label", 'l', 0, eArgTypeName
,
223 "Optional name for this target.", nullptr),
224 m_symbol_file(LLDB_OPT_SET_1
, false, "symfile", 's', 0,
226 "Fullpath to a stand alone debug "
227 "symbols file for when debug symbols "
228 "are not in the executable."),
230 LLDB_OPT_SET_1
, false, "remote-file", 'r', 0, eArgTypeFilename
,
231 "Fullpath to the file on the remote host if debugging remotely.") {
233 AddSimpleArgumentList(eArgTypeFilename
);
235 m_option_group
.Append(&m_arch_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
236 m_option_group
.Append(&m_platform_options
, LLDB_OPT_SET_ALL
, 1);
237 m_option_group
.Append(&m_core_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
238 m_option_group
.Append(&m_label
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
239 m_option_group
.Append(&m_symbol_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
240 m_option_group
.Append(&m_remote_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
241 m_option_group
.Append(&m_add_dependents
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
242 m_option_group
.Finalize();
245 ~CommandObjectTargetCreate() override
= default;
247 Options
*GetOptions() override
{ return &m_option_group
; }
250 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
251 const size_t argc
= command
.GetArgumentCount();
252 FileSpec
core_file(m_core_file
.GetOptionValue().GetCurrentValue());
253 FileSpec
remote_file(m_remote_file
.GetOptionValue().GetCurrentValue());
256 auto file
= FileSystem::Instance().Open(
257 core_file
, lldb_private::File::eOpenOptionReadOnly
);
260 result
.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
262 llvm::toString(file
.takeError()));
267 if (argc
== 1 || core_file
|| remote_file
) {
268 FileSpec
symfile(m_symbol_file
.GetOptionValue().GetCurrentValue());
270 auto file
= FileSystem::Instance().Open(
271 symfile
, lldb_private::File::eOpenOptionReadOnly
);
274 result
.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
276 llvm::toString(file
.takeError()));
281 const char *file_path
= command
.GetArgumentAtIndex(0);
282 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path
);
284 bool must_set_platform_path
= false;
286 Debugger
&debugger
= GetDebugger();
289 llvm::StringRef arch_cstr
= m_arch_option
.GetArchitectureName();
290 Status
error(debugger
.GetTargetList().CreateTarget(
291 debugger
, file_path
, arch_cstr
,
292 m_add_dependents
.m_load_dependent_files
, &m_platform_options
,
296 result
.AppendError(error
.AsCString());
300 const llvm::StringRef label
=
301 m_label
.GetOptionValue().GetCurrentValueAsRef();
302 if (!label
.empty()) {
303 if (auto E
= target_sp
->SetLabel(label
))
304 result
.SetError(std::move(E
));
308 auto on_error
= llvm::make_scope_exit(
309 [&target_list
= debugger
.GetTargetList(), &target_sp
]() {
310 target_list
.DeleteTarget(target_sp
);
313 // Only get the platform after we create the target because we might
314 // have switched platforms depending on what the arguments were to
315 // CreateTarget() we can't rely on the selected platform.
317 PlatformSP platform_sp
= target_sp
->GetPlatform();
321 file_spec
.SetFile(file_path
, FileSpec::Style::native
);
322 FileSystem::Instance().Resolve(file_spec
);
324 // Try to resolve the exe based on PATH and/or platform-specific
325 // suffixes, but only if using the host platform.
326 if (platform_sp
&& platform_sp
->IsHost() &&
327 !FileSystem::Instance().Exists(file_spec
))
328 FileSystem::Instance().ResolveExecutableLocation(file_spec
);
333 // I have a remote file.. two possible cases
334 if (file_spec
&& FileSystem::Instance().Exists(file_spec
)) {
335 // if the remote file does not exist, push it there
336 if (!platform_sp
->GetFileExists(remote_file
)) {
337 Status err
= platform_sp
->PutFile(file_spec
, remote_file
);
339 result
.AppendError(err
.AsCString());
344 // there is no local file and we need one
345 // in order to make the remote ---> local transfer we need a
347 // TODO: if the user has passed in a --platform argument, use it
348 // to fetch the right platform
350 // copy the remote file to the local file
351 Status err
= platform_sp
->GetFile(remote_file
, file_spec
);
353 result
.AppendError(err
.AsCString());
357 // If the remote file exists, we can debug reading that out of
358 // memory. If the platform is already connected to an lldb-server
359 // then we can at least check the file exists remotely. Otherwise
360 // we'll just have to trust that it will be there when we do
362 // I don't do this for the host platform because it seems odd to
363 // support supplying a remote file but no local file for a local
365 if (platform_sp
->IsHost()) {
366 result
.AppendError("Supply a local file, not a remote file, "
367 "when debugging on the host.");
370 if (platform_sp
->IsConnected() && !platform_sp
->GetFileExists(remote_file
)) {
371 result
.AppendError("remote --> local transfer without local "
372 "path is not implemented yet");
375 // Since there's only a remote file, we need to set the executable
376 // file spec to the remote one.
377 ProcessLaunchInfo launch_info
= target_sp
->GetProcessLaunchInfo();
378 launch_info
.SetExecutableFile(FileSpec(remote_file
), true);
379 target_sp
->SetProcessLaunchInfo(launch_info
);
383 result
.AppendError("no platform found for target");
388 if (symfile
|| remote_file
) {
389 ModuleSP
module_sp(target_sp
->GetExecutableModule());
392 module_sp
->SetSymbolFileFileSpec(symfile
);
394 std::string remote_path
= remote_file
.GetPath();
395 target_sp
->SetArg0(remote_path
.c_str());
396 module_sp
->SetPlatformFileSpec(remote_file
);
401 if (must_set_platform_path
) {
402 ModuleSpec
main_module_spec(file_spec
);
404 target_sp
->GetOrCreateModule(main_module_spec
, true /* notify */);
406 module_sp
->SetPlatformFileSpec(remote_file
);
410 FileSpec core_file_dir
;
411 core_file_dir
.SetDirectory(core_file
.GetDirectory());
412 target_sp
->AppendExecutableSearchPaths(core_file_dir
);
414 ProcessSP
process_sp(target_sp
->CreateProcess(
415 GetDebugger().GetListener(), llvm::StringRef(), &core_file
, false));
418 // Seems weird that we Launch a core file, but that is what we
420 error
= process_sp
->LoadCore();
423 result
.AppendError(error
.AsCString("unknown core file format"));
426 result
.AppendMessageWithFormatv(
427 "Core file '{0}' ({1}) was loaded.\n", core_file
.GetPath(),
428 target_sp
->GetArchitecture().GetArchitectureName());
429 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
433 result
.AppendErrorWithFormatv("Unknown core file format '{0}'\n",
434 core_file
.GetPath());
437 result
.AppendMessageWithFormat(
438 "Current executable set to '%s' (%s).\n",
439 file_spec
.GetPath().c_str(),
440 target_sp
->GetArchitecture().GetArchitectureName());
441 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
445 result
.AppendErrorWithFormat("'%s' takes exactly one executable path "
446 "argument, or use the --core option.\n",
452 OptionGroupOptions m_option_group
;
453 OptionGroupArchitecture m_arch_option
;
454 OptionGroupPlatform m_platform_options
;
455 OptionGroupFile m_core_file
;
456 OptionGroupString m_label
;
457 OptionGroupFile m_symbol_file
;
458 OptionGroupFile m_remote_file
;
459 OptionGroupDependents m_add_dependents
;
462 #pragma mark CommandObjectTargetList
464 class CommandObjectTargetList
: public CommandObjectParsed
{
466 CommandObjectTargetList(CommandInterpreter
&interpreter
)
467 : CommandObjectParsed(
468 interpreter
, "target list",
469 "List all current targets in the current debug session.", nullptr) {
472 ~CommandObjectTargetList() override
= default;
475 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
476 Stream
&strm
= result
.GetOutputStream();
478 bool show_stopped_process_status
= false;
479 if (DumpTargetList(GetDebugger().GetTargetList(),
480 show_stopped_process_status
, strm
) == 0) {
481 strm
.PutCString("No targets.\n");
483 result
.SetStatus(eReturnStatusSuccessFinishResult
);
487 #pragma mark CommandObjectTargetSelect
489 class CommandObjectTargetSelect
: public CommandObjectParsed
{
491 CommandObjectTargetSelect(CommandInterpreter
&interpreter
)
492 : CommandObjectParsed(
493 interpreter
, "target select",
494 "Select a target as the current target by target index.", nullptr) {
495 AddSimpleArgumentList(eArgTypeTargetID
);
498 ~CommandObjectTargetSelect() override
= default;
501 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
502 if (args
.GetArgumentCount() == 1) {
503 const char *target_identifier
= args
.GetArgumentAtIndex(0);
504 uint32_t target_idx
= LLDB_INVALID_INDEX32
;
505 TargetList
&target_list
= GetDebugger().GetTargetList();
506 const uint32_t num_targets
= target_list
.GetNumTargets();
507 if (llvm::to_integer(target_identifier
, target_idx
)) {
508 if (target_idx
< num_targets
) {
509 target_list
.SetSelectedTarget(target_idx
);
510 Stream
&strm
= result
.GetOutputStream();
511 bool show_stopped_process_status
= false;
512 DumpTargetList(target_list
, show_stopped_process_status
, strm
);
513 result
.SetStatus(eReturnStatusSuccessFinishResult
);
515 if (num_targets
> 0) {
516 result
.AppendErrorWithFormat(
517 "index %u is out of range, valid target indexes are 0 - %u\n",
518 target_idx
, num_targets
- 1);
520 result
.AppendErrorWithFormat(
521 "index %u is out of range since there are no active targets\n",
526 for (size_t i
= 0; i
< num_targets
; i
++) {
527 if (TargetSP target_sp
= target_list
.GetTargetAtIndex(i
)) {
528 const std::string
&label
= target_sp
->GetLabel();
529 if (!label
.empty() && label
== target_identifier
) {
536 if (target_idx
!= LLDB_INVALID_INDEX32
) {
537 target_list
.SetSelectedTarget(target_idx
);
538 Stream
&strm
= result
.GetOutputStream();
539 bool show_stopped_process_status
= false;
540 DumpTargetList(target_list
, show_stopped_process_status
, strm
);
541 result
.SetStatus(eReturnStatusSuccessFinishResult
);
543 result
.AppendErrorWithFormat("invalid index string value '%s'\n",
549 "'target select' takes a single argument: a target index\n");
554 #pragma mark CommandObjectTargetDelete
556 class CommandObjectTargetDelete
: public CommandObjectParsed
{
558 CommandObjectTargetDelete(CommandInterpreter
&interpreter
)
559 : CommandObjectParsed(interpreter
, "target delete",
560 "Delete one or more targets by target index.",
562 m_all_option(LLDB_OPT_SET_1
, false, "all", 'a', "Delete all targets.",
565 LLDB_OPT_SET_1
, false, "clean", 'c',
566 "Perform extra cleanup to minimize memory consumption after "
567 "deleting the target. "
568 "By default, LLDB will keep in memory any modules previously "
569 "loaded by the target as well "
570 "as all of its debug info. Specifying --clean will unload all of "
571 "these shared modules and "
572 "cause them to be reparsed again the next time the target is run",
574 m_option_group
.Append(&m_all_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
575 m_option_group
.Append(&m_cleanup_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
576 m_option_group
.Finalize();
577 AddSimpleArgumentList(eArgTypeTargetID
, eArgRepeatStar
);
580 ~CommandObjectTargetDelete() override
= default;
582 Options
*GetOptions() override
{ return &m_option_group
; }
585 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
586 const size_t argc
= args
.GetArgumentCount();
587 std::vector
<TargetSP
> delete_target_list
;
588 TargetList
&target_list
= GetDebugger().GetTargetList();
591 if (m_all_option
.GetOptionValue()) {
592 for (size_t i
= 0; i
< target_list
.GetNumTargets(); ++i
)
593 delete_target_list
.push_back(target_list
.GetTargetAtIndex(i
));
594 } else if (argc
> 0) {
595 const uint32_t num_targets
= target_list
.GetNumTargets();
596 // Bail out if don't have any targets.
597 if (num_targets
== 0) {
598 result
.AppendError("no targets to delete");
602 for (auto &entry
: args
.entries()) {
604 if (entry
.ref().getAsInteger(0, target_idx
)) {
605 result
.AppendErrorWithFormat("invalid target index '%s'\n",
609 if (target_idx
< num_targets
) {
610 target_sp
= target_list
.GetTargetAtIndex(target_idx
);
612 delete_target_list
.push_back(target_sp
);
617 result
.AppendErrorWithFormat("target index %u is out of range, valid "
618 "target indexes are 0 - %u\n",
619 target_idx
, num_targets
- 1);
621 result
.AppendErrorWithFormat(
622 "target index %u is out of range, the only valid index is 0\n",
628 target_sp
= target_list
.GetSelectedTarget();
630 result
.AppendErrorWithFormat("no target is currently selected\n");
633 delete_target_list
.push_back(target_sp
);
636 const size_t num_targets_to_delete
= delete_target_list
.size();
637 for (size_t idx
= 0; idx
< num_targets_to_delete
; ++idx
) {
638 target_sp
= delete_target_list
[idx
];
639 target_list
.DeleteTarget(target_sp
);
640 target_sp
->Destroy();
642 // If "--clean" was specified, prune any orphaned shared modules from the
643 // global shared module list
644 if (m_cleanup_option
.GetOptionValue()) {
645 const bool mandatory
= true;
646 ModuleList::RemoveOrphanSharedModules(mandatory
);
648 result
.GetOutputStream().Printf("%u targets deleted.\n",
649 (uint32_t)num_targets_to_delete
);
650 result
.SetStatus(eReturnStatusSuccessFinishResult
);
655 OptionGroupOptions m_option_group
;
656 OptionGroupBoolean m_all_option
;
657 OptionGroupBoolean m_cleanup_option
;
660 class CommandObjectTargetShowLaunchEnvironment
: public CommandObjectParsed
{
662 CommandObjectTargetShowLaunchEnvironment(CommandInterpreter
&interpreter
)
663 : CommandObjectParsed(
664 interpreter
, "target show-launch-environment",
665 "Shows the environment being passed to the process when launched, "
666 "taking info account 3 settings: target.env-vars, "
667 "target.inherit-env and target.unset-env-vars.",
668 nullptr, eCommandRequiresTarget
) {}
670 ~CommandObjectTargetShowLaunchEnvironment() override
= default;
673 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
674 Target
*target
= m_exe_ctx
.GetTargetPtr();
675 Environment env
= target
->GetEnvironment();
677 std::vector
<Environment::value_type
*> env_vector
;
678 env_vector
.reserve(env
.size());
680 env_vector
.push_back(&KV
);
681 std::sort(env_vector
.begin(), env_vector
.end(),
682 [](Environment::value_type
*a
, Environment::value_type
*b
) {
683 return a
->first() < b
->first();
686 auto &strm
= result
.GetOutputStream();
687 for (auto &KV
: env_vector
)
688 strm
.Format("{0}={1}\n", KV
->first(), KV
->second
);
690 result
.SetStatus(eReturnStatusSuccessFinishResult
);
694 #pragma mark CommandObjectTargetVariable
696 class CommandObjectTargetVariable
: public CommandObjectParsed
{
697 static const uint32_t SHORT_OPTION_FILE
= 0x66696c65; // 'file'
698 static const uint32_t SHORT_OPTION_SHLB
= 0x73686c62; // 'shlb'
701 CommandObjectTargetVariable(CommandInterpreter
&interpreter
)
702 : CommandObjectParsed(interpreter
, "target variable",
703 "Read global variables for the current target, "
704 "before or while running a process.",
705 nullptr, eCommandRequiresTarget
),
706 m_option_variable(false), // Don't include frame options
707 m_option_format(eFormatDefault
),
708 m_option_compile_units(LLDB_OPT_SET_1
, false, "file", SHORT_OPTION_FILE
,
710 "A basename or fullpath to a file that contains "
711 "global variables. This option can be "
712 "specified multiple times."),
713 m_option_shared_libraries(
714 LLDB_OPT_SET_1
, false, "shlib", SHORT_OPTION_SHLB
, 0,
716 "A basename or fullpath to a shared library to use in the search "
718 "variables. This option can be specified multiple times.") {
719 AddSimpleArgumentList(eArgTypeVarName
, eArgRepeatPlus
);
721 m_option_group
.Append(&m_varobj_options
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
722 m_option_group
.Append(&m_option_variable
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
723 m_option_group
.Append(&m_option_format
,
724 OptionGroupFormat::OPTION_GROUP_FORMAT
|
725 OptionGroupFormat::OPTION_GROUP_GDB_FMT
,
727 m_option_group
.Append(&m_option_compile_units
, LLDB_OPT_SET_ALL
,
729 m_option_group
.Append(&m_option_shared_libraries
, LLDB_OPT_SET_ALL
,
731 m_option_group
.Finalize();
734 ~CommandObjectTargetVariable() override
= default;
736 void DumpValueObject(Stream
&s
, VariableSP
&var_sp
, ValueObjectSP
&valobj_sp
,
737 const char *root_name
) {
738 DumpValueObjectOptions
options(m_varobj_options
.GetAsDumpOptions());
740 if (!valobj_sp
->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
741 valobj_sp
->IsRuntimeSupportValue())
744 switch (var_sp
->GetScope()) {
745 case eValueTypeVariableGlobal
:
746 if (m_option_variable
.show_scope
)
747 s
.PutCString("GLOBAL: ");
750 case eValueTypeVariableStatic
:
751 if (m_option_variable
.show_scope
)
752 s
.PutCString("STATIC: ");
755 case eValueTypeVariableArgument
:
756 if (m_option_variable
.show_scope
)
757 s
.PutCString(" ARG: ");
760 case eValueTypeVariableLocal
:
761 if (m_option_variable
.show_scope
)
762 s
.PutCString(" LOCAL: ");
765 case eValueTypeVariableThreadLocal
:
766 if (m_option_variable
.show_scope
)
767 s
.PutCString("THREAD: ");
774 if (m_option_variable
.show_decl
) {
775 bool show_fullpaths
= false;
776 bool show_module
= true;
777 if (var_sp
->DumpDeclaration(&s
, show_fullpaths
, show_module
))
781 const Format format
= m_option_format
.GetFormat();
782 if (format
!= eFormatDefault
)
783 options
.SetFormat(format
);
785 options
.SetRootValueObjectName(root_name
);
787 if (llvm::Error error
= valobj_sp
->Dump(s
, options
))
788 s
<< "error: " << toString(std::move(error
));
791 static size_t GetVariableCallback(void *baton
, const char *name
,
792 VariableList
&variable_list
) {
793 size_t old_size
= variable_list
.GetSize();
794 Target
*target
= static_cast<Target
*>(baton
);
796 target
->GetImages().FindGlobalVariables(ConstString(name
), UINT32_MAX
,
798 return variable_list
.GetSize() - old_size
;
801 Options
*GetOptions() override
{ return &m_option_group
; }
804 void DumpGlobalVariableList(const ExecutionContext
&exe_ctx
,
805 const SymbolContext
&sc
,
806 const VariableList
&variable_list
, Stream
&s
) {
807 if (variable_list
.Empty())
811 s
.Format("Global variables for {0} in {1}:\n",
812 sc
.comp_unit
->GetPrimaryFile(), sc
.module_sp
->GetFileSpec());
814 s
.Printf("Global variables for %s\n",
815 sc
.module_sp
->GetFileSpec().GetPath().c_str());
817 } else if (sc
.comp_unit
) {
818 s
.Format("Global variables for {0}\n", sc
.comp_unit
->GetPrimaryFile());
821 for (VariableSP var_sp
: variable_list
) {
824 ValueObjectSP
valobj_sp(ValueObjectVariable::Create(
825 exe_ctx
.GetBestExecutionContextScope(), var_sp
));
828 DumpValueObject(s
, var_sp
, valobj_sp
, var_sp
->GetName().GetCString());
832 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
833 Target
*target
= m_exe_ctx
.GetTargetPtr();
834 const size_t argc
= args
.GetArgumentCount();
835 Stream
&s
= result
.GetOutputStream();
838 for (const Args::ArgEntry
&arg
: args
) {
839 VariableList variable_list
;
840 ValueObjectList valobj_list
;
843 bool use_var_name
= false;
844 if (m_option_variable
.use_regex
) {
845 RegularExpression
regex(arg
.ref());
846 if (!regex
.IsValid()) {
847 result
.GetErrorStream().Printf(
848 "error: invalid regular expression: '%s'\n", arg
.c_str());
852 target
->GetImages().FindGlobalVariables(regex
, UINT32_MAX
,
854 matches
= variable_list
.GetSize();
856 Status
error(Variable::GetValuesForVariableExpressionPath(
857 arg
.c_str(), m_exe_ctx
.GetBestExecutionContextScope(),
858 GetVariableCallback
, target
, variable_list
, valobj_list
));
859 matches
= variable_list
.GetSize();
863 result
.AppendErrorWithFormat("can't find global variable '%s'",
867 for (uint32_t global_idx
= 0; global_idx
< matches
; ++global_idx
) {
868 VariableSP
var_sp(variable_list
.GetVariableAtIndex(global_idx
));
870 ValueObjectSP
valobj_sp(
871 valobj_list
.GetValueObjectAtIndex(global_idx
));
873 valobj_sp
= ValueObjectVariable::Create(
874 m_exe_ctx
.GetBestExecutionContextScope(), var_sp
);
877 DumpValueObject(s
, var_sp
, valobj_sp
,
878 use_var_name
? var_sp
->GetName().GetCString()
885 const FileSpecList
&compile_units
=
886 m_option_compile_units
.GetOptionValue().GetCurrentValue();
887 const FileSpecList
&shlibs
=
888 m_option_shared_libraries
.GetOptionValue().GetCurrentValue();
889 SymbolContextList sc_list
;
890 const size_t num_compile_units
= compile_units
.GetSize();
891 const size_t num_shlibs
= shlibs
.GetSize();
892 if (num_compile_units
== 0 && num_shlibs
== 0) {
893 bool success
= false;
894 StackFrame
*frame
= m_exe_ctx
.GetFramePtr();
895 CompileUnit
*comp_unit
= nullptr;
897 SymbolContext sc
= frame
->GetSymbolContext(eSymbolContextCompUnit
);
898 comp_unit
= sc
.comp_unit
;
900 const bool can_create
= true;
901 VariableListSP
comp_unit_varlist_sp(
902 sc
.comp_unit
->GetVariableList(can_create
));
903 if (comp_unit_varlist_sp
) {
904 size_t count
= comp_unit_varlist_sp
->GetSize();
906 DumpGlobalVariableList(m_exe_ctx
, sc
, *comp_unit_varlist_sp
, s
);
915 result
.AppendErrorWithFormatv(
916 "no global variables in current compile unit: {0}\n",
917 comp_unit
->GetPrimaryFile());
919 result
.AppendErrorWithFormat(
920 "no debug information for frame %u\n",
921 frame
->GetFrameIndex());
923 result
.AppendError("'target variable' takes one or more global "
924 "variable names as arguments\n");
927 SymbolContextList sc_list
;
928 // We have one or more compile unit or shlib
929 if (num_shlibs
> 0) {
930 for (size_t shlib_idx
= 0; shlib_idx
< num_shlibs
; ++shlib_idx
) {
931 const FileSpec
module_file(shlibs
.GetFileSpecAtIndex(shlib_idx
));
932 ModuleSpec
module_spec(module_file
);
935 target
->GetImages().FindFirstModule(module_spec
));
937 if (num_compile_units
> 0) {
938 for (size_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
)
939 module_sp
->FindCompileUnits(
940 compile_units
.GetFileSpecAtIndex(cu_idx
), sc_list
);
943 sc
.module_sp
= module_sp
;
947 // Didn't find matching shlib/module in target...
948 result
.AppendErrorWithFormat(
949 "target doesn't contain the specified shared library: %s\n",
950 module_file
.GetPath().c_str());
954 // No shared libraries, we just want to find globals for the compile
955 // units files that were specified
956 for (size_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
)
957 target
->GetImages().FindCompileUnits(
958 compile_units
.GetFileSpecAtIndex(cu_idx
), sc_list
);
961 for (const SymbolContext
&sc
: sc_list
) {
963 const bool can_create
= true;
964 VariableListSP
comp_unit_varlist_sp(
965 sc
.comp_unit
->GetVariableList(can_create
));
966 if (comp_unit_varlist_sp
)
967 DumpGlobalVariableList(m_exe_ctx
, sc
, *comp_unit_varlist_sp
, s
);
968 } else if (sc
.module_sp
) {
969 // Get all global variables for this module
970 lldb_private::RegularExpression
all_globals_regex(
971 llvm::StringRef(".")); // Any global with at least one character
972 VariableList variable_list
;
973 sc
.module_sp
->FindGlobalVariables(all_globals_regex
, UINT32_MAX
,
975 DumpGlobalVariableList(m_exe_ctx
, sc
, variable_list
, s
);
981 m_interpreter
.PrintWarningsIfNecessary(result
.GetOutputStream(),
985 OptionGroupOptions m_option_group
;
986 OptionGroupVariable m_option_variable
;
987 OptionGroupFormat m_option_format
;
988 OptionGroupFileList m_option_compile_units
;
989 OptionGroupFileList m_option_shared_libraries
;
990 OptionGroupValueObjectDisplay m_varobj_options
;
993 #pragma mark CommandObjectTargetModulesSearchPathsAdd
995 class CommandObjectTargetModulesSearchPathsAdd
: public CommandObjectParsed
{
997 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter
&interpreter
)
998 : CommandObjectParsed(interpreter
, "target modules search-paths add",
999 "Add new image search paths substitution pairs to "
1000 "the current target.",
1001 nullptr, eCommandRequiresTarget
) {
1002 CommandArgumentEntry arg
;
1003 CommandArgumentData old_prefix_arg
;
1004 CommandArgumentData new_prefix_arg
;
1006 // Define the first variant of this arg pair.
1007 old_prefix_arg
.arg_type
= eArgTypeOldPathPrefix
;
1008 old_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1010 // Define the first variant of this arg pair.
1011 new_prefix_arg
.arg_type
= eArgTypeNewPathPrefix
;
1012 new_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1014 // There are two required arguments that must always occur together, i.e.
1015 // an argument "pair". Because they must always occur together, they are
1016 // treated as two variants of one argument rather than two independent
1017 // arguments. Push them both into the first argument position for
1020 arg
.push_back(old_prefix_arg
);
1021 arg
.push_back(new_prefix_arg
);
1023 m_arguments
.push_back(arg
);
1026 ~CommandObjectTargetModulesSearchPathsAdd() override
= default;
1029 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1030 Target
&target
= GetTarget();
1031 const size_t argc
= command
.GetArgumentCount();
1033 result
.AppendError("add requires an even number of arguments\n");
1035 for (size_t i
= 0; i
< argc
; i
+= 2) {
1036 const char *from
= command
.GetArgumentAtIndex(i
);
1037 const char *to
= command
.GetArgumentAtIndex(i
+ 1);
1039 if (from
[0] && to
[0]) {
1040 Log
*log
= GetLog(LLDBLog::Host
);
1043 "target modules search path adding ImageSearchPath "
1044 "pair: '%s' -> '%s'",
1047 bool last_pair
= ((argc
- i
) == 2);
1048 target
.GetImageSearchPathList().Append(
1049 from
, to
, last_pair
); // Notify if this is the last pair
1050 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1053 result
.AppendError("<path-prefix> can't be empty\n");
1055 result
.AppendError("<new-path-prefix> can't be empty\n");
1062 #pragma mark CommandObjectTargetModulesSearchPathsClear
1064 class CommandObjectTargetModulesSearchPathsClear
: public CommandObjectParsed
{
1066 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter
&interpreter
)
1067 : CommandObjectParsed(interpreter
, "target modules search-paths clear",
1068 "Clear all current image search path substitution "
1069 "pairs from the current target.",
1070 "target modules search-paths clear",
1071 eCommandRequiresTarget
) {}
1073 ~CommandObjectTargetModulesSearchPathsClear() override
= default;
1076 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1077 Target
&target
= GetTarget();
1079 target
.GetImageSearchPathList().Clear(notify
);
1080 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1084 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1086 class CommandObjectTargetModulesSearchPathsInsert
: public CommandObjectParsed
{
1088 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter
&interpreter
)
1089 : CommandObjectParsed(interpreter
, "target modules search-paths insert",
1090 "Insert a new image search path substitution pair "
1091 "into the current target at the specified index.",
1092 nullptr, eCommandRequiresTarget
) {
1093 CommandArgumentEntry arg1
;
1094 CommandArgumentEntry arg2
;
1095 CommandArgumentData index_arg
;
1096 CommandArgumentData old_prefix_arg
;
1097 CommandArgumentData new_prefix_arg
;
1099 // Define the first and only variant of this arg.
1100 index_arg
.arg_type
= eArgTypeIndex
;
1101 index_arg
.arg_repetition
= eArgRepeatPlain
;
1103 // Put the one and only variant into the first arg for m_arguments:
1104 arg1
.push_back(index_arg
);
1106 // Define the first variant of this arg pair.
1107 old_prefix_arg
.arg_type
= eArgTypeOldPathPrefix
;
1108 old_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1110 // Define the first variant of this arg pair.
1111 new_prefix_arg
.arg_type
= eArgTypeNewPathPrefix
;
1112 new_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1114 // There are two required arguments that must always occur together, i.e.
1115 // an argument "pair". Because they must always occur together, they are
1116 // treated as two variants of one argument rather than two independent
1117 // arguments. Push them both into the same argument position for
1120 arg2
.push_back(old_prefix_arg
);
1121 arg2
.push_back(new_prefix_arg
);
1123 // Add arguments to m_arguments.
1124 m_arguments
.push_back(arg1
);
1125 m_arguments
.push_back(arg2
);
1128 ~CommandObjectTargetModulesSearchPathsInsert() override
= default;
1131 HandleArgumentCompletion(CompletionRequest
&request
,
1132 OptionElementVector
&opt_element_vector
) override
{
1133 if (!m_exe_ctx
.HasTargetScope() || request
.GetCursorIndex() != 0)
1136 Target
*target
= m_exe_ctx
.GetTargetPtr();
1137 const PathMappingList
&list
= target
->GetImageSearchPathList();
1138 const size_t num
= list
.GetSize();
1139 ConstString old_path
, new_path
;
1140 for (size_t i
= 0; i
< num
; ++i
) {
1141 if (!list
.GetPathsAtIndex(i
, old_path
, new_path
))
1144 strm
<< old_path
<< " -> " << new_path
;
1145 request
.TryCompleteCurrentArg(std::to_string(i
), strm
.GetString());
1150 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1151 Target
&target
= GetTarget();
1152 size_t argc
= command
.GetArgumentCount();
1153 // check for at least 3 arguments and an odd number of parameters
1154 if (argc
>= 3 && argc
& 1) {
1155 uint32_t insert_idx
;
1157 if (!llvm::to_integer(command
.GetArgumentAtIndex(0), insert_idx
)) {
1158 result
.AppendErrorWithFormat(
1159 "<index> parameter is not an integer: '%s'.\n",
1160 command
.GetArgumentAtIndex(0));
1164 // shift off the index
1166 argc
= command
.GetArgumentCount();
1168 for (uint32_t i
= 0; i
< argc
; i
+= 2, ++insert_idx
) {
1169 const char *from
= command
.GetArgumentAtIndex(i
);
1170 const char *to
= command
.GetArgumentAtIndex(i
+ 1);
1172 if (from
[0] && to
[0]) {
1173 bool last_pair
= ((argc
- i
) == 2);
1174 target
.GetImageSearchPathList().Insert(from
, to
, insert_idx
,
1176 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1179 result
.AppendError("<path-prefix> can't be empty\n");
1181 result
.AppendError("<new-path-prefix> can't be empty\n");
1186 result
.AppendError("insert requires at least three arguments\n");
1191 #pragma mark CommandObjectTargetModulesSearchPathsList
1193 class CommandObjectTargetModulesSearchPathsList
: public CommandObjectParsed
{
1195 CommandObjectTargetModulesSearchPathsList(CommandInterpreter
&interpreter
)
1196 : CommandObjectParsed(interpreter
, "target modules search-paths list",
1197 "List all current image search path substitution "
1198 "pairs in the current target.",
1199 "target modules search-paths list",
1200 eCommandRequiresTarget
) {}
1202 ~CommandObjectTargetModulesSearchPathsList() override
= default;
1205 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1206 Target
&target
= GetTarget();
1207 target
.GetImageSearchPathList().Dump(&result
.GetOutputStream());
1208 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1212 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1214 class CommandObjectTargetModulesSearchPathsQuery
: public CommandObjectParsed
{
1216 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter
&interpreter
)
1217 : CommandObjectParsed(
1218 interpreter
, "target modules search-paths query",
1219 "Transform a path using the first applicable image search path.",
1220 nullptr, eCommandRequiresTarget
) {
1221 AddSimpleArgumentList(eArgTypeDirectoryName
);
1224 ~CommandObjectTargetModulesSearchPathsQuery() override
= default;
1227 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1228 Target
&target
= GetTarget();
1229 if (command
.GetArgumentCount() != 1) {
1230 result
.AppendError("query requires one argument\n");
1234 ConstString
orig(command
.GetArgumentAtIndex(0));
1235 ConstString transformed
;
1236 if (target
.GetImageSearchPathList().RemapPath(orig
, transformed
))
1237 result
.GetOutputStream().Printf("%s\n", transformed
.GetCString());
1239 result
.GetOutputStream().Printf("%s\n", orig
.GetCString());
1241 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1245 // Static Helper functions
1246 static void DumpModuleArchitecture(Stream
&strm
, Module
*module
,
1247 bool full_triple
, uint32_t width
) {
1249 StreamString arch_strm
;
1252 module
->GetArchitecture().DumpTriple(arch_strm
.AsRawOstream());
1254 arch_strm
.PutCString(module
->GetArchitecture().GetArchitectureName());
1255 std::string arch_str
= std::string(arch_strm
.GetString());
1258 strm
.Printf("%-*s", width
, arch_str
.c_str());
1260 strm
.PutCString(arch_str
);
1264 static void DumpModuleUUID(Stream
&strm
, Module
*module
) {
1265 if (module
&& module
->GetUUID().IsValid())
1266 module
->GetUUID().Dump(strm
);
1268 strm
.PutCString(" ");
1271 static uint32_t DumpCompileUnitLineTable(CommandInterpreter
&interpreter
,
1272 Stream
&strm
, Module
*module
,
1273 const FileSpec
&file_spec
,
1274 lldb::DescriptionLevel desc_level
) {
1275 uint32_t num_matches
= 0;
1277 SymbolContextList sc_list
;
1278 num_matches
= module
->ResolveSymbolContextsForFileSpec(
1279 file_spec
, 0, false, eSymbolContextCompUnit
, sc_list
);
1281 bool first_module
= true;
1282 for (const SymbolContext
&sc
: sc_list
) {
1286 strm
<< "Line table for " << sc
.comp_unit
->GetPrimaryFile() << " in `"
1287 << module
->GetFileSpec().GetFilename() << "\n";
1288 LineTable
*line_table
= sc
.comp_unit
->GetLineTable();
1290 line_table
->GetDescription(
1291 &strm
, interpreter
.GetExecutionContext().GetTargetPtr(),
1294 strm
<< "No line table";
1296 first_module
= false;
1302 static void DumpFullpath(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1304 if (file_spec_ptr
) {
1306 std::string fullpath
= file_spec_ptr
->GetPath();
1307 strm
.Printf("%-*s", width
, fullpath
.c_str());
1310 file_spec_ptr
->Dump(strm
.AsRawOstream());
1314 // Keep the width spacing correct if things go wrong...
1316 strm
.Printf("%-*s", width
, "");
1319 static void DumpDirectory(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1321 if (file_spec_ptr
) {
1323 strm
.Printf("%-*s", width
, file_spec_ptr
->GetDirectory().AsCString(""));
1325 file_spec_ptr
->GetDirectory().Dump(&strm
);
1328 // Keep the width spacing correct if things go wrong...
1330 strm
.Printf("%-*s", width
, "");
1333 static void DumpBasename(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1335 if (file_spec_ptr
) {
1337 strm
.Printf("%-*s", width
, file_spec_ptr
->GetFilename().AsCString(""));
1339 file_spec_ptr
->GetFilename().Dump(&strm
);
1342 // Keep the width spacing correct if things go wrong...
1344 strm
.Printf("%-*s", width
, "");
1347 static size_t DumpModuleObjfileHeaders(Stream
&strm
, ModuleList
&module_list
) {
1348 std::lock_guard
<std::recursive_mutex
> guard(module_list
.GetMutex());
1349 const size_t num_modules
= module_list
.GetSize();
1350 if (num_modules
== 0)
1353 size_t num_dumped
= 0;
1354 strm
.Format("Dumping headers for {0} module(s).\n", num_modules
);
1356 for (ModuleSP module_sp
: module_list
.ModulesNoLocking()) {
1358 if (num_dumped
++ > 0) {
1362 ObjectFile
*objfile
= module_sp
->GetObjectFile();
1364 objfile
->Dump(&strm
);
1366 strm
.Format("No object file for module: {0:F}\n",
1367 module_sp
->GetFileSpec());
1375 static void DumpModuleSymtab(CommandInterpreter
&interpreter
, Stream
&strm
,
1376 Module
*module
, SortOrder sort_order
,
1377 Mangled::NamePreference name_preference
) {
1380 if (Symtab
*symtab
= module
->GetSymtab())
1381 symtab
->Dump(&strm
, interpreter
.GetExecutionContext().GetTargetPtr(),
1382 sort_order
, name_preference
);
1385 static void DumpModuleSections(CommandInterpreter
&interpreter
, Stream
&strm
,
1388 SectionList
*section_list
= module
->GetSectionList();
1390 strm
.Printf("Sections for '%s' (%s):\n",
1391 module
->GetSpecificationDescription().c_str(),
1392 module
->GetArchitecture().GetArchitectureName());
1393 section_list
->Dump(strm
.AsRawOstream(), strm
.GetIndentLevel() + 2,
1394 interpreter
.GetExecutionContext().GetTargetPtr(), true,
1400 static bool DumpModuleSymbolFile(Stream
&strm
, Module
*module
) {
1402 if (SymbolFile
*symbol_file
= module
->GetSymbolFile(true)) {
1403 symbol_file
->Dump(strm
);
1410 static bool GetSeparateDebugInfoList(StructuredData::Array
&list
,
1411 Module
*module
, bool errors_only
) {
1413 if (SymbolFile
*symbol_file
= module
->GetSymbolFile(/*can_create=*/true)) {
1414 StructuredData::Dictionary d
;
1415 if (symbol_file
->GetSeparateDebugInfo(d
, errors_only
)) {
1417 std::make_shared
<StructuredData::Dictionary
>(std::move(d
)));
1425 static void DumpDwoFilesTable(Stream
&strm
,
1426 StructuredData::Array
&dwo_listings
) {
1427 strm
.PutCString("Dwo ID Err Dwo Path");
1430 "------------------ --- -----------------------------------------");
1432 dwo_listings
.ForEach([&strm
](StructuredData::Object
*dwo
) {
1433 StructuredData::Dictionary
*dict
= dwo
->GetAsDictionary();
1438 if (dict
->GetValueForKeyAsInteger("dwo_id", dwo_id
))
1439 strm
.Printf("0x%16.16" PRIx64
" ", dwo_id
);
1441 strm
.Printf("0x???????????????? ");
1443 llvm::StringRef error
;
1444 if (dict
->GetValueForKeyAsString("error", error
))
1445 strm
<< "E " << error
;
1447 llvm::StringRef resolved_dwo_path
;
1448 if (dict
->GetValueForKeyAsString("resolved_dwo_path",
1449 resolved_dwo_path
)) {
1450 strm
<< " " << resolved_dwo_path
;
1451 if (resolved_dwo_path
.ends_with(".dwp")) {
1452 llvm::StringRef dwo_name
;
1453 if (dict
->GetValueForKeyAsString("dwo_name", dwo_name
))
1454 strm
<< "(" << dwo_name
<< ")";
1463 static void DumpOsoFilesTable(Stream
&strm
,
1464 StructuredData::Array
&oso_listings
) {
1465 strm
.PutCString("Mod Time Err Oso Path");
1467 strm
.PutCString("------------------ --- ---------------------");
1469 oso_listings
.ForEach([&strm
](StructuredData::Object
*oso
) {
1470 StructuredData::Dictionary
*dict
= oso
->GetAsDictionary();
1474 uint32_t oso_mod_time
;
1475 if (dict
->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time
))
1476 strm
.Printf("0x%16.16" PRIx32
" ", oso_mod_time
);
1478 llvm::StringRef error
;
1479 if (dict
->GetValueForKeyAsString("error", error
))
1480 strm
<< "E " << error
;
1482 llvm::StringRef oso_path
;
1483 if (dict
->GetValueForKeyAsString("oso_path", oso_path
))
1484 strm
<< " " << oso_path
;
1492 DumpAddress(ExecutionContextScope
*exe_scope
, const Address
&so_addr
,
1493 bool verbose
, bool all_ranges
, Stream
&strm
,
1494 std::optional
<Stream::HighlightSettings
> settings
= std::nullopt
) {
1496 strm
.Indent(" Address: ");
1497 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleModuleWithFileAddress
);
1498 strm
.PutCString(" (");
1499 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleSectionNameOffset
);
1500 strm
.PutCString(")\n");
1501 strm
.Indent(" Summary: ");
1502 const uint32_t save_indent
= strm
.GetIndentLevel();
1503 strm
.SetIndentLevel(save_indent
+ 13);
1504 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleResolvedDescription
,
1505 Address::DumpStyleInvalid
, UINT32_MAX
, false, settings
);
1506 strm
.SetIndentLevel(save_indent
);
1507 // Print out detailed address information when verbose is enabled
1510 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleDetailedSymbolContext
,
1511 Address::DumpStyleInvalid
, UINT32_MAX
, all_ranges
, settings
);
1516 static bool LookupAddressInModule(CommandInterpreter
&interpreter
, Stream
&strm
,
1517 Module
*module
, uint32_t resolve_mask
,
1518 lldb::addr_t raw_addr
, lldb::addr_t offset
,
1519 bool verbose
, bool all_ranges
) {
1521 lldb::addr_t addr
= raw_addr
- offset
;
1524 Target
*target
= interpreter
.GetExecutionContext().GetTargetPtr();
1525 if (target
&& !target
->GetSectionLoadList().IsEmpty()) {
1526 if (!target
->GetSectionLoadList().ResolveLoadAddress(addr
, so_addr
))
1528 else if (so_addr
.GetModule().get() != module
)
1531 if (!module
->ResolveFileAddress(addr
, so_addr
))
1535 ExecutionContextScope
*exe_scope
=
1536 interpreter
.GetExecutionContext().GetBestExecutionContextScope();
1537 DumpAddress(exe_scope
, so_addr
, verbose
, all_ranges
, strm
);
1544 static uint32_t LookupSymbolInModule(CommandInterpreter
&interpreter
,
1545 Stream
&strm
, Module
*module
,
1546 const char *name
, bool name_is_regex
,
1547 bool verbose
, bool all_ranges
) {
1551 Symtab
*symtab
= module
->GetSymtab();
1556 const bool use_color
= interpreter
.GetDebugger().GetUseColor();
1557 std::vector
<uint32_t> match_indexes
;
1558 ConstString
symbol_name(name
);
1559 uint32_t num_matches
= 0;
1560 if (name_is_regex
) {
1561 RegularExpression
name_regexp(symbol_name
.GetStringRef());
1562 num_matches
= symtab
->AppendSymbolIndexesMatchingRegExAndType(
1563 name_regexp
, eSymbolTypeAny
, match_indexes
);
1566 symtab
->AppendSymbolIndexesWithName(symbol_name
, match_indexes
);
1569 if (num_matches
> 0) {
1571 strm
.Printf("%u symbols match %s'%s' in ", num_matches
,
1572 name_is_regex
? "the regular expression " : "", name
);
1573 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1574 strm
.PutCString(":\n");
1576 Stream::HighlightSettings
settings(
1577 name
, interpreter
.GetDebugger().GetRegexMatchAnsiPrefix(),
1578 interpreter
.GetDebugger().GetRegexMatchAnsiSuffix());
1579 for (uint32_t i
= 0; i
< num_matches
; ++i
) {
1580 Symbol
*symbol
= symtab
->SymbolAtIndex(match_indexes
[i
]);
1582 if (symbol
->ValueIsAddress()) {
1584 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1585 symbol
->GetAddressRef(), verbose
, all_ranges
, strm
,
1586 use_color
&& name_is_regex
1587 ? std::optional
<Stream::HighlightSettings
>{settings
}
1592 strm
.Indent(" Name: ");
1593 strm
.PutCStringColorHighlighted(
1594 symbol
->GetDisplayName().GetStringRef(),
1595 use_color
&& name_is_regex
1596 ? std::optional
<Stream::HighlightSettings
>{settings
}
1599 strm
.Indent(" Value: ");
1600 strm
.Printf("0x%16.16" PRIx64
"\n", symbol
->GetRawValue());
1601 if (symbol
->GetByteSizeIsValid()) {
1602 strm
.Indent(" Size: ");
1603 strm
.Printf("0x%16.16" PRIx64
"\n", symbol
->GetByteSize());
1614 static void DumpSymbolContextList(
1615 ExecutionContextScope
*exe_scope
, Stream
&strm
,
1616 const SymbolContextList
&sc_list
, bool verbose
, bool all_ranges
,
1617 std::optional
<Stream::HighlightSettings
> settings
= std::nullopt
) {
1619 bool first_module
= true;
1620 for (const SymbolContext
&sc
: sc_list
) {
1626 sc
.GetAddressRange(eSymbolContextEverything
, 0, true, range
);
1628 DumpAddress(exe_scope
, range
.GetBaseAddress(), verbose
, all_ranges
, strm
,
1630 first_module
= false;
1635 static size_t LookupFunctionInModule(CommandInterpreter
&interpreter
,
1636 Stream
&strm
, Module
*module
,
1637 const char *name
, bool name_is_regex
,
1638 const ModuleFunctionSearchOptions
&options
,
1639 bool verbose
, bool all_ranges
) {
1640 if (module
&& name
&& name
[0]) {
1641 SymbolContextList sc_list
;
1642 size_t num_matches
= 0;
1643 if (name_is_regex
) {
1644 RegularExpression
function_name_regex((llvm::StringRef(name
)));
1645 module
->FindFunctions(function_name_regex
, options
, sc_list
);
1647 ConstString
function_name(name
);
1648 module
->FindFunctions(function_name
, CompilerDeclContext(),
1649 eFunctionNameTypeAuto
, options
, sc_list
);
1651 num_matches
= sc_list
.GetSize();
1654 strm
.Printf("%" PRIu64
" match%s found in ", (uint64_t)num_matches
,
1655 num_matches
> 1 ? "es" : "");
1656 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1657 strm
.PutCString(":\n");
1658 DumpSymbolContextList(
1659 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1660 strm
, sc_list
, verbose
, all_ranges
);
1667 static size_t LookupTypeInModule(Target
*target
,
1668 CommandInterpreter
&interpreter
, Stream
&strm
,
1669 Module
*module
, const char *name_cstr
,
1670 bool name_is_regex
) {
1671 if (module
&& name_cstr
&& name_cstr
[0]) {
1672 TypeQuery
query(name_cstr
);
1673 TypeResults results
;
1674 module
->FindTypes(query
, results
);
1679 sc
.module_sp
= module
->shared_from_this();
1680 // Sort the type results and put the results that matched in \a module
1681 // first if \a module was specified.
1682 sc
.SortTypeList(results
.GetTypeMap(), type_list
);
1683 if (type_list
.Empty())
1686 const uint64_t num_matches
= type_list
.GetSize();
1689 strm
.Printf("%" PRIu64
" match%s found in ", num_matches
,
1690 num_matches
> 1 ? "es" : "");
1691 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1692 strm
.PutCString(":\n");
1693 for (TypeSP type_sp
: type_list
.Types()) {
1696 // Resolve the clang type so that any forward references to types
1697 // that haven't yet been parsed will get parsed.
1698 type_sp
->GetFullCompilerType();
1699 type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true, target
);
1700 // Print all typedef chains
1701 TypeSP
typedef_type_sp(type_sp
);
1702 TypeSP
typedefed_type_sp(typedef_type_sp
->GetTypedefType());
1703 while (typedefed_type_sp
) {
1705 strm
.Printf(" typedef '%s': ",
1706 typedef_type_sp
->GetName().GetCString());
1707 typedefed_type_sp
->GetFullCompilerType();
1708 typedefed_type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true,
1710 typedef_type_sp
= typedefed_type_sp
;
1711 typedefed_type_sp
= typedef_type_sp
->GetTypedefType();
1715 return type_list
.GetSize();
1720 static size_t LookupTypeHere(Target
*target
, CommandInterpreter
&interpreter
,
1721 Stream
&strm
, Module
&module
,
1722 const char *name_cstr
, bool name_is_regex
) {
1723 TypeQuery
query(name_cstr
);
1724 TypeResults results
;
1725 module
.FindTypes(query
, results
);
1728 sc
.module_sp
= module
.shared_from_this();
1729 sc
.SortTypeList(results
.GetTypeMap(), type_list
);
1730 if (type_list
.Empty())
1734 strm
.PutCString("Best match found in ");
1735 DumpFullpath(strm
, &module
.GetFileSpec(), 0);
1736 strm
.PutCString(":\n");
1738 TypeSP
type_sp(type_list
.GetTypeAtIndex(0));
1740 // Resolve the clang type so that any forward references to types that
1741 // haven't yet been parsed will get parsed.
1742 type_sp
->GetFullCompilerType();
1743 type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true, target
);
1744 // Print all typedef chains.
1745 TypeSP
typedef_type_sp(type_sp
);
1746 TypeSP
typedefed_type_sp(typedef_type_sp
->GetTypedefType());
1747 while (typedefed_type_sp
) {
1749 strm
.Printf(" typedef '%s': ",
1750 typedef_type_sp
->GetName().GetCString());
1751 typedefed_type_sp
->GetFullCompilerType();
1752 typedefed_type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true,
1754 typedef_type_sp
= typedefed_type_sp
;
1755 typedefed_type_sp
= typedef_type_sp
->GetTypedefType();
1759 return type_list
.GetSize();
1762 static uint32_t LookupFileAndLineInModule(CommandInterpreter
&interpreter
,
1763 Stream
&strm
, Module
*module
,
1764 const FileSpec
&file_spec
,
1765 uint32_t line
, bool check_inlines
,
1766 bool verbose
, bool all_ranges
) {
1767 if (module
&& file_spec
) {
1768 SymbolContextList sc_list
;
1769 const uint32_t num_matches
= module
->ResolveSymbolContextsForFileSpec(
1770 file_spec
, line
, check_inlines
, eSymbolContextEverything
, sc_list
);
1771 if (num_matches
> 0) {
1773 strm
.Printf("%u match%s found in ", num_matches
,
1774 num_matches
> 1 ? "es" : "");
1777 strm
.Printf(":%u", line
);
1779 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1780 strm
.PutCString(":\n");
1781 DumpSymbolContextList(
1782 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1783 strm
, sc_list
, verbose
, all_ranges
);
1790 static size_t FindModulesByName(Target
*target
, const char *module_name
,
1791 ModuleList
&module_list
,
1792 bool check_global_list
) {
1793 FileSpec
module_file_spec(module_name
);
1794 ModuleSpec
module_spec(module_file_spec
);
1796 const size_t initial_size
= module_list
.GetSize();
1798 if (check_global_list
) {
1799 // Check the global list
1800 std::lock_guard
<std::recursive_mutex
> guard(
1801 Module::GetAllocationModuleCollectionMutex());
1802 const size_t num_modules
= Module::GetNumberAllocatedModules();
1804 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
1805 Module
*module
= Module::GetAllocatedModuleAtIndex(image_idx
);
1808 if (module
->MatchesModuleSpec(module_spec
)) {
1809 module_sp
= module
->shared_from_this();
1810 module_list
.AppendIfNeeded(module_sp
);
1816 target
->GetImages().FindModules(module_spec
, module_list
);
1817 const size_t num_matches
= module_list
.GetSize();
1819 // Not found in our module list for our target, check the main shared
1820 // module list in case it is a extra file used somewhere else
1821 if (num_matches
== 0) {
1822 module_spec
.GetArchitecture() = target
->GetArchitecture();
1823 ModuleList::FindSharedModules(module_spec
, module_list
);
1826 ModuleList::FindSharedModules(module_spec
, module_list
);
1830 return module_list
.GetSize() - initial_size
;
1833 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1835 // A base command object class that can auto complete with module file
1838 class CommandObjectTargetModulesModuleAutoComplete
1839 : public CommandObjectParsed
{
1841 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter
&interpreter
,
1846 : CommandObjectParsed(interpreter
, name
, help
, syntax
, flags
) {
1847 AddSimpleArgumentList(eArgTypeFilename
, eArgRepeatStar
);
1850 ~CommandObjectTargetModulesModuleAutoComplete() override
= default;
1853 HandleArgumentCompletion(CompletionRequest
&request
,
1854 OptionElementVector
&opt_element_vector
) override
{
1855 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1856 GetCommandInterpreter(), lldb::eModuleCompletion
, request
, nullptr);
1860 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1862 // A base command object class that can auto complete with module source
1865 class CommandObjectTargetModulesSourceFileAutoComplete
1866 : public CommandObjectParsed
{
1868 CommandObjectTargetModulesSourceFileAutoComplete(
1869 CommandInterpreter
&interpreter
, const char *name
, const char *help
,
1870 const char *syntax
, uint32_t flags
)
1871 : CommandObjectParsed(interpreter
, name
, help
, syntax
, flags
) {
1872 AddSimpleArgumentList(eArgTypeSourceFile
, eArgRepeatPlus
);
1875 ~CommandObjectTargetModulesSourceFileAutoComplete() override
= default;
1878 HandleArgumentCompletion(CompletionRequest
&request
,
1879 OptionElementVector
&opt_element_vector
) override
{
1880 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1881 GetCommandInterpreter(), lldb::eSourceFileCompletion
, request
, nullptr);
1885 #pragma mark CommandObjectTargetModulesDumpObjfile
1887 class CommandObjectTargetModulesDumpObjfile
1888 : public CommandObjectTargetModulesModuleAutoComplete
{
1890 CommandObjectTargetModulesDumpObjfile(CommandInterpreter
&interpreter
)
1891 : CommandObjectTargetModulesModuleAutoComplete(
1892 interpreter
, "target modules dump objfile",
1893 "Dump the object file headers from one or more target modules.",
1894 nullptr, eCommandRequiresTarget
) {}
1896 ~CommandObjectTargetModulesDumpObjfile() override
= default;
1899 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1900 Target
&target
= GetTarget();
1902 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
1903 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
1904 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
1906 size_t num_dumped
= 0;
1907 if (command
.GetArgumentCount() == 0) {
1908 // Dump all headers for all modules images
1909 num_dumped
= DumpModuleObjfileHeaders(result
.GetOutputStream(),
1910 target
.GetImages());
1911 if (num_dumped
== 0) {
1912 result
.AppendError("the target has no associated executable images");
1915 // Find the modules that match the basename or full path.
1916 ModuleList module_list
;
1917 const char *arg_cstr
;
1918 for (int arg_idx
= 0;
1919 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
1921 size_t num_matched
=
1922 FindModulesByName(&target
, arg_cstr
, module_list
, true);
1923 if (num_matched
== 0) {
1924 result
.AppendWarningWithFormat(
1925 "Unable to find an image that matches '%s'.\n", arg_cstr
);
1928 // Dump all the modules we found.
1930 DumpModuleObjfileHeaders(result
.GetOutputStream(), module_list
);
1933 if (num_dumped
> 0) {
1934 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1936 result
.AppendError("no matching executable images found");
1941 #define LLDB_OPTIONS_target_modules_dump_symtab
1942 #include "CommandOptions.inc"
1944 class CommandObjectTargetModulesDumpSymtab
1945 : public CommandObjectTargetModulesModuleAutoComplete
{
1947 CommandObjectTargetModulesDumpSymtab(CommandInterpreter
&interpreter
)
1948 : CommandObjectTargetModulesModuleAutoComplete(
1949 interpreter
, "target modules dump symtab",
1950 "Dump the symbol table from one or more target modules.", nullptr,
1951 eCommandRequiresTarget
) {}
1953 ~CommandObjectTargetModulesDumpSymtab() override
= default;
1955 Options
*GetOptions() override
{ return &m_options
; }
1957 class CommandOptions
: public Options
{
1959 CommandOptions() = default;
1961 ~CommandOptions() override
= default;
1963 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1964 ExecutionContext
*execution_context
) override
{
1966 const int short_option
= m_getopt_table
[option_idx
].val
;
1968 switch (short_option
) {
1970 m_prefer_mangled
.SetCurrentValue(true);
1971 m_prefer_mangled
.SetOptionWasSet();
1975 m_sort_order
= (SortOrder
)OptionArgParser::ToOptionEnum(
1976 option_arg
, GetDefinitions()[option_idx
].enum_values
,
1977 eSortOrderNone
, error
);
1981 llvm_unreachable("Unimplemented option");
1986 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1987 m_sort_order
= eSortOrderNone
;
1988 m_prefer_mangled
.Clear();
1991 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1992 return llvm::ArrayRef(g_target_modules_dump_symtab_options
);
1995 SortOrder m_sort_order
= eSortOrderNone
;
1996 OptionValueBoolean m_prefer_mangled
= {false, false};
2000 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2001 Target
&target
= GetTarget();
2002 uint32_t num_dumped
= 0;
2003 Mangled::NamePreference name_preference
=
2004 (m_options
.m_prefer_mangled
? Mangled::ePreferMangled
2005 : Mangled::ePreferDemangled
);
2007 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
2008 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2009 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2011 if (command
.GetArgumentCount() == 0) {
2012 // Dump all sections for all modules images
2013 const ModuleList
&module_list
= target
.GetImages();
2014 std::lock_guard
<std::recursive_mutex
> guard(module_list
.GetMutex());
2015 const size_t num_modules
= module_list
.GetSize();
2016 if (num_modules
> 0) {
2017 result
.GetOutputStream().Format(
2018 "Dumping symbol table for {0} modules.\n", num_modules
);
2019 for (ModuleSP module_sp
: module_list
.ModulesNoLocking()) {
2020 if (num_dumped
> 0) {
2021 result
.GetOutputStream().EOL();
2022 result
.GetOutputStream().EOL();
2024 if (INTERRUPT_REQUESTED(GetDebugger(),
2025 "Interrupted in dump all symtabs with {0} "
2026 "of {1} dumped.", num_dumped
, num_modules
))
2030 DumpModuleSymtab(m_interpreter
, result
.GetOutputStream(),
2031 module_sp
.get(), m_options
.m_sort_order
,
2035 result
.AppendError("the target has no associated executable images");
2039 // Dump specified images (by basename or fullpath)
2040 const char *arg_cstr
;
2041 for (int arg_idx
= 0;
2042 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2044 ModuleList module_list
;
2045 const size_t num_matches
=
2046 FindModulesByName(&target
, arg_cstr
, module_list
, true);
2047 if (num_matches
> 0) {
2048 for (ModuleSP module_sp
: module_list
.Modules()) {
2050 if (num_dumped
> 0) {
2051 result
.GetOutputStream().EOL();
2052 result
.GetOutputStream().EOL();
2054 if (INTERRUPT_REQUESTED(GetDebugger(),
2055 "Interrupted in dump symtab list with {0} of {1} dumped.",
2056 num_dumped
, num_matches
))
2060 DumpModuleSymtab(m_interpreter
, result
.GetOutputStream(),
2061 module_sp
.get(), m_options
.m_sort_order
,
2066 result
.AppendWarningWithFormat(
2067 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2072 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2074 result
.AppendError("no matching executable images found");
2078 CommandOptions m_options
;
2081 #pragma mark CommandObjectTargetModulesDumpSections
2083 // Image section dumping command
2085 class CommandObjectTargetModulesDumpSections
2086 : public CommandObjectTargetModulesModuleAutoComplete
{
2088 CommandObjectTargetModulesDumpSections(CommandInterpreter
&interpreter
)
2089 : CommandObjectTargetModulesModuleAutoComplete(
2090 interpreter
, "target modules dump sections",
2091 "Dump the sections from one or more target modules.",
2092 //"target modules dump sections [<file1> ...]")
2093 nullptr, eCommandRequiresTarget
) {}
2095 ~CommandObjectTargetModulesDumpSections() override
= default;
2098 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2099 Target
&target
= GetTarget();
2100 uint32_t num_dumped
= 0;
2102 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
2103 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2104 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2106 if (command
.GetArgumentCount() == 0) {
2107 // Dump all sections for all modules images
2108 const size_t num_modules
= target
.GetImages().GetSize();
2109 if (num_modules
== 0) {
2110 result
.AppendError("the target has no associated executable images");
2114 result
.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2116 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
2117 if (INTERRUPT_REQUESTED(GetDebugger(),
2118 "Interrupted in dump all sections with {0} of {1} dumped",
2119 image_idx
, num_modules
))
2124 m_interpreter
, result
.GetOutputStream(),
2125 target
.GetImages().GetModulePointerAtIndex(image_idx
));
2128 // Dump specified images (by basename or fullpath)
2129 const char *arg_cstr
;
2130 for (int arg_idx
= 0;
2131 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2133 ModuleList module_list
;
2134 const size_t num_matches
=
2135 FindModulesByName(&target
, arg_cstr
, module_list
, true);
2136 if (num_matches
> 0) {
2137 for (size_t i
= 0; i
< num_matches
; ++i
) {
2138 if (INTERRUPT_REQUESTED(GetDebugger(),
2139 "Interrupted in dump section list with {0} of {1} dumped.",
2143 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2146 DumpModuleSections(m_interpreter
, result
.GetOutputStream(),
2151 // Check the global list
2152 std::lock_guard
<std::recursive_mutex
> guard(
2153 Module::GetAllocationModuleCollectionMutex());
2155 result
.AppendWarningWithFormat(
2156 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2162 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2164 result
.AppendError("no matching executable images found");
2169 class CommandObjectTargetModulesDumpClangPCMInfo
: public CommandObjectParsed
{
2171 CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter
&interpreter
)
2172 : CommandObjectParsed(
2173 interpreter
, "target modules dump pcm-info",
2174 "Dump information about the given clang module (pcm).") {
2175 // Take a single file argument.
2176 AddSimpleArgumentList(eArgTypeFilename
);
2179 ~CommandObjectTargetModulesDumpClangPCMInfo() override
= default;
2182 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2183 if (command
.GetArgumentCount() != 1) {
2184 result
.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",
2185 m_cmd_name
.c_str());
2189 const char *pcm_path
= command
.GetArgumentAtIndex(0);
2190 const FileSpec pcm_file
{pcm_path
};
2192 if (pcm_file
.GetFileNameExtension() != ".pcm") {
2193 result
.AppendError("file must have a .pcm extension");
2197 if (!FileSystem::Instance().Exists(pcm_file
)) {
2198 result
.AppendError("pcm file does not exist");
2202 clang::CompilerInstance compiler
;
2203 compiler
.createDiagnostics();
2205 const char *clang_args
[] = {"clang", pcm_path
};
2206 compiler
.setInvocation(clang::createInvocation(clang_args
));
2208 // Pass empty deleter to not attempt to free memory that was allocated
2209 // outside of the current scope, possibly statically.
2210 std::shared_ptr
<llvm::raw_ostream
> Out(
2211 &result
.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream
*) {});
2212 clang::DumpModuleInfoAction
dump_module_info(Out
);
2213 // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2214 compiler
.getPCHContainerOperations()->registerReader(
2215 std::make_unique
<clang::ObjectFilePCHContainerReader
>());
2217 if (compiler
.ExecuteAction(dump_module_info
))
2218 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2222 #pragma mark CommandObjectTargetModulesDumpClangAST
2224 // Clang AST dumping command
2226 class CommandObjectTargetModulesDumpClangAST
2227 : public CommandObjectTargetModulesModuleAutoComplete
{
2229 CommandObjectTargetModulesDumpClangAST(CommandInterpreter
&interpreter
)
2230 : CommandObjectTargetModulesModuleAutoComplete(
2231 interpreter
, "target modules dump ast",
2232 "Dump the clang ast for a given module's symbol file.",
2233 //"target modules dump ast [<file1> ...]")
2234 nullptr, eCommandRequiresTarget
) {}
2236 ~CommandObjectTargetModulesDumpClangAST() override
= default;
2239 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2240 Target
&target
= GetTarget();
2242 const ModuleList
&module_list
= target
.GetImages();
2243 const size_t num_modules
= module_list
.GetSize();
2244 if (num_modules
== 0) {
2245 result
.AppendError("the target has no associated executable images");
2249 if (command
.GetArgumentCount() == 0) {
2250 // Dump all ASTs for all modules images
2251 result
.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2253 for (ModuleSP module_sp
: module_list
.ModulesNoLocking()) {
2254 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
2256 if (SymbolFile
*sf
= module_sp
->GetSymbolFile())
2257 sf
->DumpClangAST(result
.GetOutputStream());
2259 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2263 // Dump specified ASTs (by basename or fullpath)
2264 for (const Args::ArgEntry
&arg
: command
.entries()) {
2265 ModuleList module_list
;
2266 const size_t num_matches
=
2267 FindModulesByName(&target
, arg
.c_str(), module_list
, true);
2268 if (num_matches
== 0) {
2269 // Check the global list
2270 std::lock_guard
<std::recursive_mutex
> guard(
2271 Module::GetAllocationModuleCollectionMutex());
2273 result
.AppendWarningWithFormat(
2274 "Unable to find an image that matches '%s'.\n", arg
.c_str());
2278 for (size_t i
= 0; i
< num_matches
; ++i
) {
2279 if (INTERRUPT_REQUESTED(GetDebugger(),
2280 "Interrupted in dump clang ast list with {0} of {1} dumped.",
2284 Module
*m
= module_list
.GetModulePointerAtIndex(i
);
2285 if (SymbolFile
*sf
= m
->GetSymbolFile())
2286 sf
->DumpClangAST(result
.GetOutputStream());
2289 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2293 #pragma mark CommandObjectTargetModulesDumpSymfile
2295 // Image debug symbol dumping command
2297 class CommandObjectTargetModulesDumpSymfile
2298 : public CommandObjectTargetModulesModuleAutoComplete
{
2300 CommandObjectTargetModulesDumpSymfile(CommandInterpreter
&interpreter
)
2301 : CommandObjectTargetModulesModuleAutoComplete(
2302 interpreter
, "target modules dump symfile",
2303 "Dump the debug symbol file for one or more target modules.",
2304 //"target modules dump symfile [<file1> ...]")
2305 nullptr, eCommandRequiresTarget
) {}
2307 ~CommandObjectTargetModulesDumpSymfile() override
= default;
2310 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2311 Target
&target
= GetTarget();
2312 uint32_t num_dumped
= 0;
2314 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
2315 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2316 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2318 if (command
.GetArgumentCount() == 0) {
2319 // Dump all sections for all modules images
2320 const ModuleList
&target_modules
= target
.GetImages();
2321 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2322 const size_t num_modules
= target_modules
.GetSize();
2323 if (num_modules
== 0) {
2324 result
.AppendError("the target has no associated executable images");
2327 result
.GetOutputStream().Format(
2328 "Dumping debug symbols for {0} modules.\n", num_modules
);
2329 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
2330 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2331 "debug symbols with {0} of {1} modules dumped",
2332 num_dumped
, num_modules
))
2335 if (DumpModuleSymbolFile(result
.GetOutputStream(), module_sp
.get()))
2339 // Dump specified images (by basename or fullpath)
2340 const char *arg_cstr
;
2341 for (int arg_idx
= 0;
2342 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2344 ModuleList module_list
;
2345 const size_t num_matches
=
2346 FindModulesByName(&target
, arg_cstr
, module_list
, true);
2347 if (num_matches
> 0) {
2348 for (size_t i
= 0; i
< num_matches
; ++i
) {
2349 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2350 "of {1} requested modules",
2353 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2355 if (DumpModuleSymbolFile(result
.GetOutputStream(), module
))
2360 result
.AppendWarningWithFormat(
2361 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2366 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2368 result
.AppendError("no matching executable images found");
2373 #pragma mark CommandObjectTargetModulesDumpLineTable
2374 #define LLDB_OPTIONS_target_modules_dump
2375 #include "CommandOptions.inc"
2377 // Image debug line table dumping command
2379 class CommandObjectTargetModulesDumpLineTable
2380 : public CommandObjectTargetModulesSourceFileAutoComplete
{
2382 CommandObjectTargetModulesDumpLineTable(CommandInterpreter
&interpreter
)
2383 : CommandObjectTargetModulesSourceFileAutoComplete(
2384 interpreter
, "target modules dump line-table",
2385 "Dump the line table for one or more compilation units.", nullptr,
2386 eCommandRequiresTarget
) {}
2388 ~CommandObjectTargetModulesDumpLineTable() override
= default;
2390 Options
*GetOptions() override
{ return &m_options
; }
2393 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2394 Target
*target
= m_exe_ctx
.GetTargetPtr();
2395 uint32_t total_num_dumped
= 0;
2397 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2398 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2399 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2401 if (command
.GetArgumentCount() == 0) {
2402 result
.AppendError("file option must be specified.");
2405 // Dump specified images (by basename or fullpath)
2406 const char *arg_cstr
;
2407 for (int arg_idx
= 0;
2408 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2410 FileSpec
file_spec(arg_cstr
);
2412 const ModuleList
&target_modules
= target
->GetImages();
2413 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2414 size_t num_modules
= target_modules
.GetSize();
2415 if (num_modules
> 0) {
2416 uint32_t num_dumped
= 0;
2417 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
2418 if (INTERRUPT_REQUESTED(GetDebugger(),
2419 "Interrupted in dump all line tables with "
2420 "{0} of {1} dumped", num_dumped
,
2424 if (DumpCompileUnitLineTable(
2425 m_interpreter
, result
.GetOutputStream(), module_sp
.get(),
2427 m_options
.m_verbose
? eDescriptionLevelFull
2428 : eDescriptionLevelBrief
))
2431 if (num_dumped
== 0)
2432 result
.AppendWarningWithFormat(
2433 "No source filenames matched '%s'.\n", arg_cstr
);
2435 total_num_dumped
+= num_dumped
;
2440 if (total_num_dumped
> 0)
2441 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2443 result
.AppendError("no source filenames matched any command arguments");
2447 class CommandOptions
: public Options
{
2449 CommandOptions() { OptionParsingStarting(nullptr); }
2451 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2452 ExecutionContext
*execution_context
) override
{
2453 assert(option_idx
== 0 && "We only have one option.");
2459 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2463 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2464 return llvm::ArrayRef(g_target_modules_dump_options
);
2470 CommandOptions m_options
;
2473 #pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2474 #define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2475 #include "CommandOptions.inc"
2477 // Image debug separate debug info dumping command
2479 class CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2480 : public CommandObjectTargetModulesModuleAutoComplete
{
2482 CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2483 CommandInterpreter
&interpreter
)
2484 : CommandObjectTargetModulesModuleAutoComplete(
2485 interpreter
, "target modules dump separate-debug-info",
2486 "List the separate debug info symbol files for one or more target "
2488 nullptr, eCommandRequiresTarget
) {}
2490 ~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override
= default;
2492 Options
*GetOptions() override
{ return &m_options
; }
2494 class CommandOptions
: public Options
{
2496 CommandOptions() = default;
2498 ~CommandOptions() override
= default;
2500 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2501 ExecutionContext
*execution_context
) override
{
2503 const int short_option
= m_getopt_table
[option_idx
].val
;
2505 switch (short_option
) {
2507 m_json
.SetCurrentValue(true);
2508 m_json
.SetOptionWasSet();
2511 m_errors_only
.SetCurrentValue(true);
2512 m_errors_only
.SetOptionWasSet();
2515 llvm_unreachable("Unimplemented option");
2520 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2522 m_errors_only
.Clear();
2525 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2526 return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options
);
2529 OptionValueBoolean m_json
= false;
2530 OptionValueBoolean m_errors_only
= false;
2534 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2535 Target
&target
= GetTarget();
2536 uint32_t num_dumped
= 0;
2538 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
2539 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2540 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2542 StructuredData::Array separate_debug_info_lists_by_module
;
2543 if (command
.GetArgumentCount() == 0) {
2544 // Dump all sections for all modules images
2545 const ModuleList
&target_modules
= target
.GetImages();
2546 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2547 const size_t num_modules
= target_modules
.GetSize();
2548 if (num_modules
== 0) {
2549 result
.AppendError("the target has no associated executable images");
2552 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
2553 if (INTERRUPT_REQUESTED(
2555 "Interrupted in dumping all "
2556 "separate debug info with {0} of {1} modules dumped",
2557 num_dumped
, num_modules
))
2560 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module
,
2562 bool(m_options
.m_errors_only
)))
2566 // Dump specified images (by basename or fullpath)
2567 const char *arg_cstr
;
2568 for (int arg_idx
= 0;
2569 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2571 ModuleList module_list
;
2572 const size_t num_matches
=
2573 FindModulesByName(&target
, arg_cstr
, module_list
, true);
2574 if (num_matches
> 0) {
2575 for (size_t i
= 0; i
< num_matches
; ++i
) {
2576 if (INTERRUPT_REQUESTED(GetDebugger(),
2577 "Interrupted dumping {0} "
2578 "of {1} requested modules",
2581 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2582 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module
,
2583 module
, bool(m_options
.m_errors_only
)))
2587 result
.AppendWarningWithFormat(
2588 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2592 if (num_dumped
> 0) {
2593 Stream
&strm
= result
.GetOutputStream();
2594 // Display the debug info files in some format.
2595 if (m_options
.m_json
) {
2597 separate_debug_info_lists_by_module
.Dump(strm
,
2598 /*pretty_print=*/true);
2600 // Human-readable table format
2601 separate_debug_info_lists_by_module
.ForEach(
2602 [&result
, &strm
](StructuredData::Object
*obj
) {
2607 // Each item in `separate_debug_info_lists_by_module` should be a
2608 // valid structured data dictionary.
2609 StructuredData::Dictionary
*separate_debug_info_list
=
2610 obj
->GetAsDictionary();
2611 if (!separate_debug_info_list
) {
2615 llvm::StringRef type
;
2616 llvm::StringRef symfile
;
2617 StructuredData::Array
*files
;
2618 if (!(separate_debug_info_list
->GetValueForKeyAsString("type",
2620 separate_debug_info_list
->GetValueForKeyAsString("symfile",
2622 separate_debug_info_list
->GetValueForKeyAsArray(
2623 "separate-debug-info-files", files
))) {
2627 strm
<< "Symbol file: " << symfile
;
2629 strm
<< "Type: \"" << type
<< "\"";
2631 if (type
== "dwo") {
2632 DumpDwoFilesTable(strm
, *files
);
2633 } else if (type
== "oso") {
2634 DumpOsoFilesTable(strm
, *files
);
2636 result
.AppendWarningWithFormat(
2637 "Found unsupported debug info type '%s'.\n",
2638 type
.str().c_str());
2643 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2645 result
.AppendError("no matching executable images found");
2649 CommandOptions m_options
;
2652 #pragma mark CommandObjectTargetModulesDump
2654 // Dump multi-word command for target modules
2656 class CommandObjectTargetModulesDump
: public CommandObjectMultiword
{
2658 // Constructors and Destructors
2659 CommandObjectTargetModulesDump(CommandInterpreter
&interpreter
)
2660 : CommandObjectMultiword(
2661 interpreter
, "target modules dump",
2662 "Commands for dumping information about one or more target "
2664 "target modules dump "
2665 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2667 "[<file1> <file2> ...]") {
2668 LoadSubCommand("objfile",
2670 new CommandObjectTargetModulesDumpObjfile(interpreter
)));
2673 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter
)));
2674 LoadSubCommand("sections",
2675 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2677 LoadSubCommand("symfile",
2679 new CommandObjectTargetModulesDumpSymfile(interpreter
)));
2681 "ast", CommandObjectSP(
2682 new CommandObjectTargetModulesDumpClangAST(interpreter
)));
2683 LoadSubCommand("line-table",
2684 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2689 new CommandObjectTargetModulesDumpClangPCMInfo(interpreter
)));
2690 LoadSubCommand("separate-debug-info",
2692 new CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2696 ~CommandObjectTargetModulesDump() override
= default;
2699 class CommandObjectTargetModulesAdd
: public CommandObjectParsed
{
2701 CommandObjectTargetModulesAdd(CommandInterpreter
&interpreter
)
2702 : CommandObjectParsed(interpreter
, "target modules add",
2703 "Add a new module to the current target's modules.",
2704 "target modules add [<module>]",
2705 eCommandRequiresTarget
),
2706 m_symbol_file(LLDB_OPT_SET_1
, false, "symfile", 's', 0,
2708 "Fullpath to a stand alone debug "
2709 "symbols file for when debug symbols "
2710 "are not in the executable.") {
2711 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
2713 m_option_group
.Append(&m_symbol_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2714 m_option_group
.Finalize();
2715 AddSimpleArgumentList(eArgTypePath
, eArgRepeatStar
);
2718 ~CommandObjectTargetModulesAdd() override
= default;
2720 Options
*GetOptions() override
{ return &m_option_group
; }
2723 OptionGroupOptions m_option_group
;
2724 OptionGroupUUID m_uuid_option_group
;
2725 OptionGroupFile m_symbol_file
;
2727 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
2728 Target
&target
= GetTarget();
2731 const size_t argc
= args
.GetArgumentCount();
2733 if (m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2734 // We are given a UUID only, go locate the file
2735 ModuleSpec module_spec
;
2736 module_spec
.GetUUID() =
2737 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2738 if (m_symbol_file
.GetOptionValue().OptionWasSet())
2739 module_spec
.GetSymbolFileSpec() =
2740 m_symbol_file
.GetOptionValue().GetCurrentValue();
2742 if (PluginManager::DownloadObjectAndSymbolFile(module_spec
, error
)) {
2744 target
.GetOrCreateModule(module_spec
, true /* notify */));
2746 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2750 module_spec
.GetUUID().Dump(strm
);
2751 if (module_spec
.GetFileSpec()) {
2752 if (module_spec
.GetSymbolFileSpec()) {
2753 result
.AppendErrorWithFormat(
2754 "Unable to create the executable or symbol file with "
2755 "UUID %s with path %s and symbol file %s",
2756 strm
.GetData(), module_spec
.GetFileSpec().GetPath().c_str(),
2757 module_spec
.GetSymbolFileSpec().GetPath().c_str());
2759 result
.AppendErrorWithFormat(
2760 "Unable to create the executable or symbol file with "
2761 "UUID %s with path %s",
2763 module_spec
.GetFileSpec().GetPath().c_str());
2766 result
.AppendErrorWithFormat("Unable to create the executable "
2767 "or symbol file with UUID %s",
2774 module_spec
.GetUUID().Dump(strm
);
2775 result
.AppendErrorWithFormat(
2776 "Unable to locate the executable or symbol file with UUID %s",
2778 result
.SetError(std::move(error
));
2783 "one or more executable image paths must be specified");
2787 for (auto &entry
: args
.entries()) {
2788 if (entry
.ref().empty())
2791 FileSpec
file_spec(entry
.ref());
2792 if (FileSystem::Instance().Exists(file_spec
)) {
2793 ModuleSpec
module_spec(file_spec
);
2794 if (m_uuid_option_group
.GetOptionValue().OptionWasSet())
2795 module_spec
.GetUUID() =
2796 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2797 if (m_symbol_file
.GetOptionValue().OptionWasSet())
2798 module_spec
.GetSymbolFileSpec() =
2799 m_symbol_file
.GetOptionValue().GetCurrentValue();
2800 if (!module_spec
.GetArchitecture().IsValid())
2801 module_spec
.GetArchitecture() = target
.GetArchitecture();
2804 target
.GetOrCreateModule(module_spec
, true /* notify */, &error
));
2806 const char *error_cstr
= error
.AsCString();
2808 result
.AppendError(error_cstr
);
2810 result
.AppendErrorWithFormat("unsupported module: %s",
2816 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2818 std::string resolved_path
= file_spec
.GetPath();
2819 if (resolved_path
!= entry
.ref()) {
2820 result
.AppendErrorWithFormat(
2821 "invalid module path '%s' with resolved path '%s'\n",
2822 entry
.ref().str().c_str(), resolved_path
.c_str());
2825 result
.AppendErrorWithFormat("invalid module path '%s'\n",
2833 ProcessSP process
= target
.GetProcessSP();
2840 class CommandObjectTargetModulesLoad
2841 : public CommandObjectTargetModulesModuleAutoComplete
{
2843 CommandObjectTargetModulesLoad(CommandInterpreter
&interpreter
)
2844 : CommandObjectTargetModulesModuleAutoComplete(
2845 interpreter
, "target modules load",
2846 "Set the load addresses for one or more sections in a target "
2848 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2849 "<address> [<sect-name> <address> ....]",
2850 eCommandRequiresTarget
),
2851 m_file_option(LLDB_OPT_SET_1
, false, "file", 'f', 0, eArgTypeName
,
2852 "Fullpath or basename for module to load.", ""),
2853 m_load_option(LLDB_OPT_SET_1
, false, "load", 'l',
2854 "Write file contents to the memory.", false, true),
2855 m_pc_option(LLDB_OPT_SET_1
, false, "set-pc-to-entry", 'p',
2856 "Set PC to the entry point."
2857 " Only applicable with '--load' option.",
2859 m_slide_option(LLDB_OPT_SET_1
, false, "slide", 's', 0, eArgTypeOffset
,
2860 "Set the load address for all sections to be the "
2861 "virtual address in the file plus the offset.",
2863 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
2865 m_option_group
.Append(&m_file_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2866 m_option_group
.Append(&m_load_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2867 m_option_group
.Append(&m_pc_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2868 m_option_group
.Append(&m_slide_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2869 m_option_group
.Finalize();
2872 ~CommandObjectTargetModulesLoad() override
= default;
2874 Options
*GetOptions() override
{ return &m_option_group
; }
2877 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
2878 Target
&target
= GetTarget();
2879 const bool load
= m_load_option
.GetOptionValue().GetCurrentValue();
2880 const bool set_pc
= m_pc_option
.GetOptionValue().GetCurrentValue();
2882 const size_t argc
= args
.GetArgumentCount();
2883 ModuleSpec module_spec
;
2884 bool search_using_module_spec
= false;
2886 // Allow "load" option to work without --file or --uuid option.
2888 if (!m_file_option
.GetOptionValue().OptionWasSet() &&
2889 !m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2890 ModuleList
&module_list
= target
.GetImages();
2891 if (module_list
.GetSize() == 1) {
2892 search_using_module_spec
= true;
2893 module_spec
.GetFileSpec() =
2894 module_list
.GetModuleAtIndex(0)->GetFileSpec();
2899 if (m_file_option
.GetOptionValue().OptionWasSet()) {
2900 search_using_module_spec
= true;
2901 const char *arg_cstr
= m_file_option
.GetOptionValue().GetCurrentValue();
2902 const bool use_global_module_list
= true;
2903 ModuleList module_list
;
2904 const size_t num_matches
= FindModulesByName(
2905 &target
, arg_cstr
, module_list
, use_global_module_list
);
2906 if (num_matches
== 1) {
2907 module_spec
.GetFileSpec() =
2908 module_list
.GetModuleAtIndex(0)->GetFileSpec();
2909 } else if (num_matches
> 1) {
2910 search_using_module_spec
= false;
2911 result
.AppendErrorWithFormat(
2912 "more than 1 module matched by name '%s'\n", arg_cstr
);
2914 search_using_module_spec
= false;
2915 result
.AppendErrorWithFormat("no object file for module '%s'\n",
2920 if (m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2921 search_using_module_spec
= true;
2922 module_spec
.GetUUID() =
2923 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2926 if (search_using_module_spec
) {
2927 ModuleList matching_modules
;
2928 target
.GetImages().FindModules(module_spec
, matching_modules
);
2929 const size_t num_matches
= matching_modules
.GetSize();
2931 char path
[PATH_MAX
];
2932 if (num_matches
== 1) {
2933 Module
*module
= matching_modules
.GetModulePointerAtIndex(0);
2935 ObjectFile
*objfile
= module
->GetObjectFile();
2937 SectionList
*section_list
= module
->GetSectionList();
2939 bool changed
= false;
2941 if (m_slide_option
.GetOptionValue().OptionWasSet()) {
2942 const addr_t slide
=
2943 m_slide_option
.GetOptionValue().GetCurrentValue();
2944 const bool slide_is_offset
= true;
2945 module
->SetLoadAddress(target
, slide
, slide_is_offset
,
2948 result
.AppendError("one or more section name + load "
2949 "address pair must be specified");
2953 if (m_slide_option
.GetOptionValue().OptionWasSet()) {
2954 result
.AppendError("The \"--slide <offset>\" option can't "
2955 "be used in conjunction with setting "
2956 "section load addresses.\n");
2960 for (size_t i
= 0; i
< argc
; i
+= 2) {
2961 const char *sect_name
= args
.GetArgumentAtIndex(i
);
2962 const char *load_addr_cstr
= args
.GetArgumentAtIndex(i
+ 1);
2963 if (sect_name
&& load_addr_cstr
) {
2964 ConstString
const_sect_name(sect_name
);
2966 if (llvm::to_integer(load_addr_cstr
, load_addr
)) {
2967 SectionSP
section_sp(
2968 section_list
->FindSectionByName(const_sect_name
));
2970 if (section_sp
->IsThreadSpecific()) {
2971 result
.AppendErrorWithFormat(
2972 "thread specific sections are not yet "
2973 "supported (section '%s')\n",
2977 if (target
.GetSectionLoadList().SetSectionLoadAddress(
2978 section_sp
, load_addr
))
2980 result
.AppendMessageWithFormat(
2981 "section '%s' loaded at 0x%" PRIx64
"\n",
2982 sect_name
, load_addr
);
2985 result
.AppendErrorWithFormat("no section found that "
2986 "matches the section "
2992 result
.AppendErrorWithFormat(
2993 "invalid load address string '%s'\n", load_addr_cstr
);
2998 result
.AppendError("section names must be followed by "
2999 "a load address.\n");
3001 result
.AppendError("one or more section name + load "
3002 "address pair must be specified.\n");
3009 target
.ModulesDidLoad(matching_modules
);
3010 Process
*process
= m_exe_ctx
.GetProcessPtr();
3015 ProcessSP process
= target
.CalculateProcess();
3016 Address file_entry
= objfile
->GetEntryPointAddress();
3018 result
.AppendError("No process");
3021 if (set_pc
&& !file_entry
.IsValid()) {
3022 result
.AppendError("No entry address in object file");
3025 std::vector
<ObjectFile::LoadableData
> loadables(
3026 objfile
->GetLoadableData(target
));
3027 if (loadables
.size() == 0) {
3028 result
.AppendError("No loadable sections");
3031 Status error
= process
->WriteObjectFile(std::move(loadables
));
3033 result
.AppendError(error
.AsCString());
3037 ThreadList
&thread_list
= process
->GetThreadList();
3038 RegisterContextSP
reg_context(
3039 thread_list
.GetSelectedThread()->GetRegisterContext());
3040 addr_t file_entry_addr
= file_entry
.GetLoadAddress(&target
);
3041 if (!reg_context
->SetPC(file_entry_addr
)) {
3042 result
.AppendErrorWithFormat("failed to set PC value to "
3049 module
->GetFileSpec().GetPath(path
, sizeof(path
));
3050 result
.AppendErrorWithFormat("no sections in object file '%s'\n",
3054 module
->GetFileSpec().GetPath(path
, sizeof(path
));
3055 result
.AppendErrorWithFormat("no object file for module '%s'\n",
3059 FileSpec
*module_spec_file
= module_spec
.GetFileSpecPtr();
3060 if (module_spec_file
) {
3061 module_spec_file
->GetPath(path
, sizeof(path
));
3062 result
.AppendErrorWithFormat("invalid module '%s'.\n", path
);
3064 result
.AppendError("no module spec");
3067 std::string uuid_str
;
3069 if (module_spec
.GetFileSpec())
3070 module_spec
.GetFileSpec().GetPath(path
, sizeof(path
));
3074 if (module_spec
.GetUUIDPtr())
3075 uuid_str
= module_spec
.GetUUID().GetAsString();
3076 if (num_matches
> 1) {
3077 result
.AppendErrorWithFormat(
3078 "multiple modules match%s%s%s%s:\n", path
[0] ? " file=" : "",
3079 path
, !uuid_str
.empty() ? " uuid=" : "", uuid_str
.c_str());
3080 for (size_t i
= 0; i
< num_matches
; ++i
) {
3081 if (matching_modules
.GetModulePointerAtIndex(i
)
3083 .GetPath(path
, sizeof(path
)))
3084 result
.AppendMessageWithFormat("%s\n", path
);
3087 result
.AppendErrorWithFormat(
3088 "no modules were found that match%s%s%s%s.\n",
3089 path
[0] ? " file=" : "", path
, !uuid_str
.empty() ? " uuid=" : "",
3094 result
.AppendError("either the \"--file <module>\" or the \"--uuid "
3095 "<uuid>\" option must be specified.\n");
3099 OptionGroupOptions m_option_group
;
3100 OptionGroupUUID m_uuid_option_group
;
3101 OptionGroupString m_file_option
;
3102 OptionGroupBoolean m_load_option
;
3103 OptionGroupBoolean m_pc_option
;
3104 OptionGroupUInt64 m_slide_option
;
3107 #pragma mark CommandObjectTargetModulesList
3108 // List images with associated information
3109 #define LLDB_OPTIONS_target_modules_list
3110 #include "CommandOptions.inc"
3112 class CommandObjectTargetModulesList
: public CommandObjectParsed
{
3114 class CommandOptions
: public Options
{
3116 CommandOptions() = default;
3118 ~CommandOptions() override
= default;
3120 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3121 ExecutionContext
*execution_context
) override
{
3124 const int short_option
= m_getopt_table
[option_idx
].val
;
3125 if (short_option
== 'g') {
3126 m_use_global_module_list
= true;
3127 } else if (short_option
== 'a') {
3128 m_module_addr
= OptionArgParser::ToAddress(
3129 execution_context
, option_arg
, LLDB_INVALID_ADDRESS
, &error
);
3131 unsigned long width
= 0;
3132 option_arg
.getAsInteger(0, width
);
3133 m_format_array
.push_back(std::make_pair(short_option
, width
));
3138 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3139 m_format_array
.clear();
3140 m_use_global_module_list
= false;
3141 m_module_addr
= LLDB_INVALID_ADDRESS
;
3144 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3145 return llvm::ArrayRef(g_target_modules_list_options
);
3148 // Instance variables to hold the values for command options.
3149 typedef std::vector
<std::pair
<char, uint32_t>> FormatWidthCollection
;
3150 FormatWidthCollection m_format_array
;
3151 bool m_use_global_module_list
= false;
3152 lldb::addr_t m_module_addr
= LLDB_INVALID_ADDRESS
;
3155 CommandObjectTargetModulesList(CommandInterpreter
&interpreter
)
3156 : CommandObjectParsed(
3157 interpreter
, "target modules list",
3158 "List current executable and dependent shared library images.") {
3159 AddSimpleArgumentList(eArgTypeModule
, eArgRepeatStar
);
3162 ~CommandObjectTargetModulesList() override
= default;
3164 Options
*GetOptions() override
{ return &m_options
; }
3167 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
3168 Target
&target
= GetTarget();
3169 const bool use_global_module_list
= m_options
.m_use_global_module_list
;
3170 // Define a local module list here to ensure it lives longer than any
3171 // "locker" object which might lock its contents below (through the
3172 // "module_list_ptr" variable).
3173 ModuleList module_list
;
3174 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
3175 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
3176 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
3177 // Dump all sections for all modules images
3178 Stream
&strm
= result
.GetOutputStream();
3180 if (m_options
.m_module_addr
!= LLDB_INVALID_ADDRESS
) {
3181 Address module_address
;
3182 if (module_address
.SetLoadAddress(m_options
.m_module_addr
, &target
)) {
3183 ModuleSP
module_sp(module_address
.GetModule());
3185 PrintModule(target
, module_sp
.get(), 0, strm
);
3186 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3188 result
.AppendErrorWithFormat(
3189 "Couldn't find module matching address: 0x%" PRIx64
".",
3190 m_options
.m_module_addr
);
3193 result
.AppendErrorWithFormat(
3194 "Couldn't find module containing address: 0x%" PRIx64
".",
3195 m_options
.m_module_addr
);
3200 size_t num_modules
= 0;
3202 // This locker will be locked on the mutex in module_list_ptr if it is
3203 // non-nullptr. Otherwise it will lock the
3204 // AllocationModuleCollectionMutex when accessing the global module list
3206 std::unique_lock
<std::recursive_mutex
> guard(
3207 Module::GetAllocationModuleCollectionMutex(), std::defer_lock
);
3209 const ModuleList
*module_list_ptr
= nullptr;
3210 const size_t argc
= command
.GetArgumentCount();
3212 if (use_global_module_list
) {
3214 num_modules
= Module::GetNumberAllocatedModules();
3216 module_list_ptr
= &target
.GetImages();
3219 for (const Args::ArgEntry
&arg
: command
) {
3220 // Dump specified images (by basename or fullpath)
3221 const size_t num_matches
= FindModulesByName(
3222 &target
, arg
.c_str(), module_list
, use_global_module_list
);
3223 if (num_matches
== 0) {
3225 result
.AppendErrorWithFormat("no modules found that match '%s'",
3232 module_list_ptr
= &module_list
;
3235 std::unique_lock
<std::recursive_mutex
> lock
;
3236 if (module_list_ptr
!= nullptr) {
3238 std::unique_lock
<std::recursive_mutex
>(module_list_ptr
->GetMutex());
3240 num_modules
= module_list_ptr
->GetSize();
3243 if (num_modules
> 0) {
3244 for (uint32_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
3247 if (module_list_ptr
) {
3248 module_sp
= module_list_ptr
->GetModuleAtIndexUnlocked(image_idx
);
3249 module
= module_sp
.get();
3251 module
= Module::GetAllocatedModuleAtIndex(image_idx
);
3252 module_sp
= module
->shared_from_this();
3255 const size_t indent
= strm
.Printf("[%3u] ", image_idx
);
3256 PrintModule(target
, module
, indent
, strm
);
3258 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3261 if (use_global_module_list
)
3263 "the global module list has no matching modules");
3265 result
.AppendError("the target has no matching modules");
3267 if (use_global_module_list
)
3268 result
.AppendError("the global module list is empty");
3271 "the target has no associated executable images");
3277 void PrintModule(Target
&target
, Module
*module
, int indent
, Stream
&strm
) {
3278 if (module
== nullptr) {
3279 strm
.PutCString("Null module");
3283 bool dump_object_name
= false;
3284 if (m_options
.m_format_array
.empty()) {
3285 m_options
.m_format_array
.push_back(std::make_pair('u', 0));
3286 m_options
.m_format_array
.push_back(std::make_pair('h', 0));
3287 m_options
.m_format_array
.push_back(std::make_pair('f', 0));
3288 m_options
.m_format_array
.push_back(std::make_pair('S', 0));
3290 const size_t num_entries
= m_options
.m_format_array
.size();
3291 bool print_space
= false;
3292 for (size_t i
= 0; i
< num_entries
; ++i
) {
3296 const char format_char
= m_options
.m_format_array
[i
].first
;
3297 uint32_t width
= m_options
.m_format_array
[i
].second
;
3298 switch (format_char
) {
3300 DumpModuleArchitecture(strm
, module
, false, width
);
3304 DumpModuleArchitecture(strm
, module
, true, width
);
3308 DumpFullpath(strm
, &module
->GetFileSpec(), width
);
3309 dump_object_name
= true;
3313 DumpDirectory(strm
, &module
->GetFileSpec(), width
);
3317 DumpBasename(strm
, &module
->GetFileSpec(), width
);
3318 dump_object_name
= true;
3323 // Image header address
3325 uint32_t addr_nibble_width
=
3326 target
.GetArchitecture().GetAddressByteSize() * 2;
3328 ObjectFile
*objfile
= module
->GetObjectFile();
3330 Address
base_addr(objfile
->GetBaseAddress());
3331 if (base_addr
.IsValid()) {
3332 if (!target
.GetSectionLoadList().IsEmpty()) {
3333 lldb::addr_t load_addr
= base_addr
.GetLoadAddress(&target
);
3334 if (load_addr
== LLDB_INVALID_ADDRESS
) {
3335 base_addr
.Dump(&strm
, &target
,
3336 Address::DumpStyleModuleWithFileAddress
,
3337 Address::DumpStyleFileAddress
);
3339 if (format_char
== 'o') {
3340 // Show the offset of slide for the image
3341 strm
.Printf("0x%*.*" PRIx64
, addr_nibble_width
,
3343 load_addr
- base_addr
.GetFileAddress());
3345 // Show the load address of the image
3346 strm
.Printf("0x%*.*" PRIx64
, addr_nibble_width
,
3347 addr_nibble_width
, load_addr
);
3352 // The address was valid, but the image isn't loaded, output the
3353 // address in an appropriate format
3354 base_addr
.Dump(&strm
, &target
, Address::DumpStyleFileAddress
);
3358 strm
.Printf("%*s", addr_nibble_width
+ 2, "");
3363 size_t ref_count
= 0;
3364 char in_shared_cache
= 'Y';
3366 ModuleSP
module_sp(module
->shared_from_this());
3367 if (!ModuleList::ModuleIsInCache(module
))
3368 in_shared_cache
= 'N';
3370 // Take one away to make sure we don't count our local "module_sp"
3371 ref_count
= module_sp
.use_count() - 1;
3374 strm
.Printf("{%c %*" PRIu64
"}", in_shared_cache
, width
, (uint64_t)ref_count
);
3376 strm
.Printf("{%c %" PRIu64
"}", in_shared_cache
, (uint64_t)ref_count
);
3381 if (const SymbolFile
*symbol_file
= module
->GetSymbolFile()) {
3382 const FileSpec symfile_spec
=
3383 symbol_file
->GetObjectFile()->GetFileSpec();
3384 if (format_char
== 'S') {
3385 // Dump symbol file only if different from module file
3386 if (!symfile_spec
|| symfile_spec
== module
->GetFileSpec()) {
3387 print_space
= false;
3390 // Add a newline and indent past the index
3391 strm
.Printf("\n%*s", indent
, "");
3393 DumpFullpath(strm
, &symfile_spec
, width
);
3394 dump_object_name
= true;
3397 strm
.Printf("%.*s", width
, "<NONE>");
3401 strm
.Format("{0:%c}", llvm::fmt_align(module
->GetModificationTime(),
3402 llvm::AlignStyle::Left
, width
));
3406 strm
.Printf("%p", static_cast<void *>(module
));
3410 DumpModuleUUID(strm
, module
);
3417 if (dump_object_name
) {
3418 const char *object_name
= module
->GetObjectName().GetCString();
3420 strm
.Printf("(%s)", object_name
);
3425 CommandOptions m_options
;
3428 #pragma mark CommandObjectTargetModulesShowUnwind
3430 // Lookup unwind information in images
3431 #define LLDB_OPTIONS_target_modules_show_unwind
3432 #include "CommandOptions.inc"
3434 class CommandObjectTargetModulesShowUnwind
: public CommandObjectParsed
{
3437 eLookupTypeInvalid
= -1,
3438 eLookupTypeAddress
= 0,
3440 eLookupTypeFunction
,
3441 eLookupTypeFunctionOrSymbol
,
3445 class CommandOptions
: public Options
{
3447 CommandOptions() = default;
3449 ~CommandOptions() override
= default;
3451 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3452 ExecutionContext
*execution_context
) override
{
3455 const int short_option
= m_getopt_table
[option_idx
].val
;
3457 switch (short_option
) {
3459 m_str
= std::string(option_arg
);
3460 m_type
= eLookupTypeAddress
;
3461 m_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
3462 LLDB_INVALID_ADDRESS
, &error
);
3463 if (m_addr
== LLDB_INVALID_ADDRESS
)
3464 error
= Status::FromErrorStringWithFormat(
3465 "invalid address string '%s'", option_arg
.str().c_str());
3470 m_str
= std::string(option_arg
);
3471 m_type
= eLookupTypeFunctionOrSymbol
;
3475 llvm_unreachable("Unimplemented option");
3481 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3482 m_type
= eLookupTypeInvalid
;
3484 m_addr
= LLDB_INVALID_ADDRESS
;
3487 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3488 return llvm::ArrayRef(g_target_modules_show_unwind_options
);
3491 // Instance variables to hold the values for command options.
3493 int m_type
= eLookupTypeInvalid
; // Should be a eLookupTypeXXX enum after
3495 std::string m_str
; // Holds name lookup
3496 lldb::addr_t m_addr
= LLDB_INVALID_ADDRESS
; // Holds the address to lookup
3499 CommandObjectTargetModulesShowUnwind(CommandInterpreter
&interpreter
)
3500 : CommandObjectParsed(
3501 interpreter
, "target modules show-unwind",
3502 "Show synthesized unwind instructions for a function.", nullptr,
3503 eCommandRequiresTarget
| eCommandRequiresProcess
|
3504 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
) {}
3506 ~CommandObjectTargetModulesShowUnwind() override
= default;
3508 Options
*GetOptions() override
{ return &m_options
; }
3511 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
3512 Target
*target
= m_exe_ctx
.GetTargetPtr();
3513 Process
*process
= m_exe_ctx
.GetProcessPtr();
3516 abi
= process
->GetABI().get();
3518 if (process
== nullptr) {
3520 "You must have a process running to use this command.");
3524 ThreadList
threads(process
->GetThreadList());
3525 if (threads
.GetSize() == 0) {
3526 result
.AppendError("The process must be paused to use this command.");
3530 ThreadSP
thread(threads
.GetThreadAtIndex(0));
3532 result
.AppendError("The process must be paused to use this command.");
3536 SymbolContextList sc_list
;
3538 if (m_options
.m_type
== eLookupTypeFunctionOrSymbol
) {
3539 ConstString
function_name(m_options
.m_str
.c_str());
3540 ModuleFunctionSearchOptions function_options
;
3541 function_options
.include_symbols
= true;
3542 function_options
.include_inlines
= false;
3543 target
->GetImages().FindFunctions(function_name
, eFunctionNameTypeAuto
,
3544 function_options
, sc_list
);
3545 } else if (m_options
.m_type
== eLookupTypeAddress
&& target
) {
3547 if (target
->GetSectionLoadList().ResolveLoadAddress(m_options
.m_addr
,
3550 ModuleSP
module_sp(addr
.GetModule());
3551 module_sp
->ResolveSymbolContextForAddress(addr
,
3552 eSymbolContextEverything
, sc
);
3553 if (sc
.function
|| sc
.symbol
) {
3559 "address-expression or function name option must be specified.");
3563 if (sc_list
.GetSize() == 0) {
3564 result
.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3565 m_options
.m_str
.c_str());
3569 for (const SymbolContext
&sc
: sc_list
) {
3570 if (sc
.symbol
== nullptr && sc
.function
== nullptr)
3572 if (!sc
.module_sp
|| sc
.module_sp
->GetObjectFile() == nullptr)
3575 if (!sc
.GetAddressRange(eSymbolContextFunction
| eSymbolContextSymbol
, 0,
3578 if (!range
.GetBaseAddress().IsValid())
3580 ConstString
funcname(sc
.GetFunctionName());
3581 if (funcname
.IsEmpty())
3583 addr_t start_addr
= range
.GetBaseAddress().GetLoadAddress(target
);
3585 start_addr
= abi
->FixCodeAddress(start_addr
);
3587 FuncUnwindersSP
func_unwinders_sp(
3588 sc
.module_sp
->GetUnwindTable()
3589 .GetUncachedFuncUnwindersContainingAddress(start_addr
, sc
));
3590 if (!func_unwinders_sp
)
3593 result
.GetOutputStream().Printf(
3594 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64
")\n",
3595 sc
.module_sp
->GetPlatformFileSpec().GetFilename().AsCString(),
3596 funcname
.AsCString(), start_addr
);
3599 target
->GetUserSpecifiedTrapHandlerNames(args
);
3600 size_t count
= args
.GetArgumentCount();
3601 for (size_t i
= 0; i
< count
; i
++) {
3602 const char *trap_func_name
= args
.GetArgumentAtIndex(i
);
3603 if (strcmp(funcname
.GetCString(), trap_func_name
) == 0)
3604 result
.GetOutputStream().Printf(
3606 "treated as a trap handler function via user setting.\n");
3608 PlatformSP
platform_sp(target
->GetPlatform());
3610 const std::vector
<ConstString
> trap_handler_names(
3611 platform_sp
->GetTrapHandlerSymbolNames());
3612 for (ConstString trap_name
: trap_handler_names
) {
3613 if (trap_name
== funcname
) {
3614 result
.GetOutputStream().Printf(
3616 "name is listed by the platform as a trap handler.\n");
3621 result
.GetOutputStream().Printf("\n");
3623 UnwindPlanSP non_callsite_unwind_plan
=
3624 func_unwinders_sp
->GetUnwindPlanAtNonCallSite(*target
, *thread
);
3625 if (non_callsite_unwind_plan
) {
3626 result
.GetOutputStream().Printf(
3627 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3628 non_callsite_unwind_plan
->GetSourceName().AsCString());
3630 UnwindPlanSP callsite_unwind_plan
=
3631 func_unwinders_sp
->GetUnwindPlanAtCallSite(*target
, *thread
);
3632 if (callsite_unwind_plan
) {
3633 result
.GetOutputStream().Printf(
3634 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3635 callsite_unwind_plan
->GetSourceName().AsCString());
3637 UnwindPlanSP fast_unwind_plan
=
3638 func_unwinders_sp
->GetUnwindPlanFastUnwind(*target
, *thread
);
3639 if (fast_unwind_plan
) {
3640 result
.GetOutputStream().Printf(
3641 "Fast UnwindPlan is '%s'\n",
3642 fast_unwind_plan
->GetSourceName().AsCString());
3645 result
.GetOutputStream().Printf("\n");
3647 UnwindPlanSP assembly_sp
=
3648 func_unwinders_sp
->GetAssemblyUnwindPlan(*target
, *thread
);
3650 result
.GetOutputStream().Printf(
3651 "Assembly language inspection UnwindPlan:\n");
3652 assembly_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3653 LLDB_INVALID_ADDRESS
);
3654 result
.GetOutputStream().Printf("\n");
3657 UnwindPlanSP of_unwind_sp
=
3658 func_unwinders_sp
->GetObjectFileUnwindPlan(*target
);
3660 result
.GetOutputStream().Printf("object file UnwindPlan:\n");
3661 of_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3662 LLDB_INVALID_ADDRESS
);
3663 result
.GetOutputStream().Printf("\n");
3666 UnwindPlanSP of_unwind_augmented_sp
=
3667 func_unwinders_sp
->GetObjectFileAugmentedUnwindPlan(*target
, *thread
);
3668 if (of_unwind_augmented_sp
) {
3669 result
.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3670 of_unwind_augmented_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3671 LLDB_INVALID_ADDRESS
);
3672 result
.GetOutputStream().Printf("\n");
3675 UnwindPlanSP ehframe_sp
=
3676 func_unwinders_sp
->GetEHFrameUnwindPlan(*target
);
3678 result
.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3679 ehframe_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3680 LLDB_INVALID_ADDRESS
);
3681 result
.GetOutputStream().Printf("\n");
3684 UnwindPlanSP ehframe_augmented_sp
=
3685 func_unwinders_sp
->GetEHFrameAugmentedUnwindPlan(*target
, *thread
);
3686 if (ehframe_augmented_sp
) {
3687 result
.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3688 ehframe_augmented_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3689 LLDB_INVALID_ADDRESS
);
3690 result
.GetOutputStream().Printf("\n");
3693 if (UnwindPlanSP plan_sp
=
3694 func_unwinders_sp
->GetDebugFrameUnwindPlan(*target
)) {
3695 result
.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3696 plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3697 LLDB_INVALID_ADDRESS
);
3698 result
.GetOutputStream().Printf("\n");
3701 if (UnwindPlanSP plan_sp
=
3702 func_unwinders_sp
->GetDebugFrameAugmentedUnwindPlan(*target
,
3704 result
.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3705 plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3706 LLDB_INVALID_ADDRESS
);
3707 result
.GetOutputStream().Printf("\n");
3710 UnwindPlanSP arm_unwind_sp
=
3711 func_unwinders_sp
->GetArmUnwindUnwindPlan(*target
);
3712 if (arm_unwind_sp
) {
3713 result
.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3714 arm_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3715 LLDB_INVALID_ADDRESS
);
3716 result
.GetOutputStream().Printf("\n");
3719 if (UnwindPlanSP symfile_plan_sp
=
3720 func_unwinders_sp
->GetSymbolFileUnwindPlan(*thread
)) {
3721 result
.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3722 symfile_plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3723 LLDB_INVALID_ADDRESS
);
3724 result
.GetOutputStream().Printf("\n");
3727 UnwindPlanSP compact_unwind_sp
=
3728 func_unwinders_sp
->GetCompactUnwindUnwindPlan(*target
);
3729 if (compact_unwind_sp
) {
3730 result
.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3731 compact_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3732 LLDB_INVALID_ADDRESS
);
3733 result
.GetOutputStream().Printf("\n");
3736 if (fast_unwind_plan
) {
3737 result
.GetOutputStream().Printf("Fast UnwindPlan:\n");
3738 fast_unwind_plan
->Dump(result
.GetOutputStream(), thread
.get(),
3739 LLDB_INVALID_ADDRESS
);
3740 result
.GetOutputStream().Printf("\n");
3743 ABISP abi_sp
= process
->GetABI();
3745 UnwindPlan
arch_default(lldb::eRegisterKindGeneric
);
3746 if (abi_sp
->CreateDefaultUnwindPlan(arch_default
)) {
3747 result
.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3748 arch_default
.Dump(result
.GetOutputStream(), thread
.get(),
3749 LLDB_INVALID_ADDRESS
);
3750 result
.GetOutputStream().Printf("\n");
3753 UnwindPlan
arch_entry(lldb::eRegisterKindGeneric
);
3754 if (abi_sp
->CreateFunctionEntryUnwindPlan(arch_entry
)) {
3755 result
.GetOutputStream().Printf(
3756 "Arch default at entry point UnwindPlan:\n");
3757 arch_entry
.Dump(result
.GetOutputStream(), thread
.get(),
3758 LLDB_INVALID_ADDRESS
);
3759 result
.GetOutputStream().Printf("\n");
3763 result
.GetOutputStream().Printf("\n");
3767 CommandOptions m_options
;
3770 // Lookup information in images
3771 #define LLDB_OPTIONS_target_modules_lookup
3772 #include "CommandOptions.inc"
3774 class CommandObjectTargetModulesLookup
: public CommandObjectParsed
{
3777 eLookupTypeInvalid
= -1,
3778 eLookupTypeAddress
= 0,
3780 eLookupTypeFileLine
, // Line is optional
3781 eLookupTypeFunction
,
3782 eLookupTypeFunctionOrSymbol
,
3787 class CommandOptions
: public Options
{
3789 CommandOptions() { OptionParsingStarting(nullptr); }
3791 ~CommandOptions() override
= default;
3793 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3794 ExecutionContext
*execution_context
) override
{
3797 const int short_option
= m_getopt_table
[option_idx
].val
;
3799 switch (short_option
) {
3801 m_type
= eLookupTypeAddress
;
3802 m_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
3803 LLDB_INVALID_ADDRESS
, &error
);
3807 if (option_arg
.getAsInteger(0, m_offset
))
3808 error
= Status::FromErrorStringWithFormat(
3809 "invalid offset string '%s'", option_arg
.str().c_str());
3813 m_str
= std::string(option_arg
);
3814 m_type
= eLookupTypeSymbol
;
3818 m_file
.SetFile(option_arg
, FileSpec::Style::native
);
3819 m_type
= eLookupTypeFileLine
;
3823 m_include_inlines
= false;
3827 if (option_arg
.getAsInteger(0, m_line_number
))
3828 error
= Status::FromErrorStringWithFormat(
3829 "invalid line number string '%s'", option_arg
.str().c_str());
3830 else if (m_line_number
== 0)
3831 error
= Status::FromErrorString("zero is an invalid line number");
3832 m_type
= eLookupTypeFileLine
;
3836 m_str
= std::string(option_arg
);
3837 m_type
= eLookupTypeFunction
;
3841 m_str
= std::string(option_arg
);
3842 m_type
= eLookupTypeFunctionOrSymbol
;
3846 m_str
= std::string(option_arg
);
3847 m_type
= eLookupTypeType
;
3863 m_all_ranges
= true;
3866 llvm_unreachable("Unimplemented option");
3872 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3873 m_type
= eLookupTypeInvalid
;
3876 m_addr
= LLDB_INVALID_ADDRESS
;
3879 m_use_regex
= false;
3880 m_include_inlines
= true;
3881 m_all_ranges
= false;
3883 m_print_all
= false;
3886 Status
OptionParsingFinished(ExecutionContext
*execution_context
) override
{
3888 if (m_all_ranges
&& !m_verbose
) {
3890 Status::FromErrorString("--show-variable-ranges must be used in "
3891 "conjunction with --verbose.");
3896 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3897 return llvm::ArrayRef(g_target_modules_lookup_options
);
3900 int m_type
; // Should be a eLookupTypeXXX enum after parsing options
3901 std::string m_str
; // Holds name lookup
3902 FileSpec m_file
; // Files for file lookups
3903 lldb::addr_t m_addr
; // Holds the address to lookup
3905 m_offset
; // Subtract this offset from m_addr before doing lookups.
3906 uint32_t m_line_number
; // Line number for file+line lookups
3907 bool m_use_regex
; // Name lookups in m_str are regular expressions.
3908 bool m_include_inlines
; // Check for inline entries when looking up by
3910 bool m_all_ranges
; // Print all ranges or single range.
3911 bool m_verbose
; // Enable verbose lookup info
3912 bool m_print_all
; // Print all matches, even in cases where there's a best
3916 CommandObjectTargetModulesLookup(CommandInterpreter
&interpreter
)
3917 : CommandObjectParsed(interpreter
, "target modules lookup",
3918 "Look up information within executable and "
3919 "dependent shared library images.",
3920 nullptr, eCommandRequiresTarget
) {
3921 AddSimpleArgumentList(eArgTypeFilename
, eArgRepeatStar
);
3924 ~CommandObjectTargetModulesLookup() override
= default;
3926 Options
*GetOptions() override
{ return &m_options
; }
3928 bool LookupHere(CommandInterpreter
&interpreter
, CommandReturnObject
&result
,
3929 bool &syntax_error
) {
3930 switch (m_options
.m_type
) {
3931 case eLookupTypeAddress
:
3932 case eLookupTypeFileLine
:
3933 case eLookupTypeFunction
:
3934 case eLookupTypeFunctionOrSymbol
:
3935 case eLookupTypeSymbol
:
3938 case eLookupTypeType
:
3942 StackFrameSP frame
= m_exe_ctx
.GetFrameSP();
3947 const SymbolContext
&sym_ctx(frame
->GetSymbolContext(eSymbolContextModule
));
3949 if (!sym_ctx
.module_sp
)
3952 switch (m_options
.m_type
) {
3955 case eLookupTypeType
:
3956 if (!m_options
.m_str
.empty()) {
3957 if (LookupTypeHere(&GetTarget(), m_interpreter
,
3958 result
.GetOutputStream(), *sym_ctx
.module_sp
,
3959 m_options
.m_str
.c_str(), m_options
.m_use_regex
)) {
3960 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3970 bool LookupInModule(CommandInterpreter
&interpreter
, Module
*module
,
3971 CommandReturnObject
&result
, bool &syntax_error
) {
3972 switch (m_options
.m_type
) {
3973 case eLookupTypeAddress
:
3974 if (m_options
.m_addr
!= LLDB_INVALID_ADDRESS
) {
3975 if (LookupAddressInModule(
3976 m_interpreter
, result
.GetOutputStream(), module
,
3977 eSymbolContextEverything
|
3978 (m_options
.m_verbose
3979 ? static_cast<int>(eSymbolContextVariable
)
3981 m_options
.m_addr
, m_options
.m_offset
, m_options
.m_verbose
,
3982 m_options
.m_all_ranges
)) {
3983 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3989 case eLookupTypeSymbol
:
3990 if (!m_options
.m_str
.empty()) {
3991 if (LookupSymbolInModule(m_interpreter
, result
.GetOutputStream(),
3992 module
, m_options
.m_str
.c_str(),
3993 m_options
.m_use_regex
, m_options
.m_verbose
,
3994 m_options
.m_all_ranges
)) {
3995 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4001 case eLookupTypeFileLine
:
4002 if (m_options
.m_file
) {
4003 if (LookupFileAndLineInModule(
4004 m_interpreter
, result
.GetOutputStream(), module
,
4005 m_options
.m_file
, m_options
.m_line_number
,
4006 m_options
.m_include_inlines
, m_options
.m_verbose
,
4007 m_options
.m_all_ranges
)) {
4008 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4014 case eLookupTypeFunctionOrSymbol
:
4015 case eLookupTypeFunction
:
4016 if (!m_options
.m_str
.empty()) {
4017 ModuleFunctionSearchOptions function_options
;
4018 function_options
.include_symbols
=
4019 m_options
.m_type
== eLookupTypeFunctionOrSymbol
;
4020 function_options
.include_inlines
= m_options
.m_include_inlines
;
4022 if (LookupFunctionInModule(m_interpreter
, result
.GetOutputStream(),
4023 module
, m_options
.m_str
.c_str(),
4024 m_options
.m_use_regex
, function_options
,
4025 m_options
.m_verbose
,
4026 m_options
.m_all_ranges
)) {
4027 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4033 case eLookupTypeType
:
4034 if (!m_options
.m_str
.empty()) {
4035 if (LookupTypeInModule(
4036 &GetTarget(), m_interpreter
, result
.GetOutputStream(), module
,
4037 m_options
.m_str
.c_str(), m_options
.m_use_regex
)) {
4038 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4045 m_options
.GenerateOptionUsage(
4046 result
.GetErrorStream(), *this,
4047 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
4048 syntax_error
= true;
4052 result
.SetStatus(eReturnStatusFailed
);
4057 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
4058 Target
&target
= GetTarget();
4059 bool syntax_error
= false;
4061 uint32_t num_successful_lookups
= 0;
4062 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
4063 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
4064 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
4065 // Dump all sections for all modules images
4067 if (command
.GetArgumentCount() == 0) {
4068 ModuleSP current_module
;
4070 // Where it is possible to look in the current symbol context first,
4071 // try that. If this search was successful and --all was not passed,
4072 // don't print anything else.
4073 if (LookupHere(m_interpreter
, result
, syntax_error
)) {
4074 result
.GetOutputStream().EOL();
4075 num_successful_lookups
++;
4076 if (!m_options
.m_print_all
) {
4077 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4082 // Dump all sections for all other modules
4084 const ModuleList
&target_modules
= target
.GetImages();
4085 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
4086 if (target_modules
.GetSize() == 0) {
4087 result
.AppendError("the target has no associated executable images");
4091 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
4092 if (module_sp
!= current_module
&&
4093 LookupInModule(m_interpreter
, module_sp
.get(), result
,
4095 result
.GetOutputStream().EOL();
4096 num_successful_lookups
++;
4100 // Dump specified images (by basename or fullpath)
4101 const char *arg_cstr
;
4102 for (i
= 0; (arg_cstr
= command
.GetArgumentAtIndex(i
)) != nullptr &&
4105 ModuleList module_list
;
4106 const size_t num_matches
=
4107 FindModulesByName(&target
, arg_cstr
, module_list
, false);
4108 if (num_matches
> 0) {
4109 for (size_t j
= 0; j
< num_matches
; ++j
) {
4110 Module
*module
= module_list
.GetModulePointerAtIndex(j
);
4112 if (LookupInModule(m_interpreter
, module
, result
, syntax_error
)) {
4113 result
.GetOutputStream().EOL();
4114 num_successful_lookups
++;
4119 result
.AppendWarningWithFormat(
4120 "Unable to find an image that matches '%s'.\n", arg_cstr
);
4124 if (num_successful_lookups
> 0)
4125 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4127 result
.SetStatus(eReturnStatusFailed
);
4130 CommandOptions m_options
;
4133 #pragma mark CommandObjectMultiwordImageSearchPaths
4135 // CommandObjectMultiwordImageSearchPaths
4137 class CommandObjectTargetModulesImageSearchPaths
4138 : public CommandObjectMultiword
{
4140 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter
&interpreter
)
4141 : CommandObjectMultiword(
4142 interpreter
, "target modules search-paths",
4143 "Commands for managing module search paths for a target.",
4144 "target modules search-paths <subcommand> [<subcommand-options>]") {
4146 "add", CommandObjectSP(
4147 new CommandObjectTargetModulesSearchPathsAdd(interpreter
)));
4149 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
4154 new CommandObjectTargetModulesSearchPathsInsert(interpreter
)));
4156 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
4159 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
4163 ~CommandObjectTargetModulesImageSearchPaths() override
= default;
4166 #pragma mark CommandObjectTargetModules
4168 // CommandObjectTargetModules
4170 class CommandObjectTargetModules
: public CommandObjectMultiword
{
4172 // Constructors and Destructors
4173 CommandObjectTargetModules(CommandInterpreter
&interpreter
)
4174 : CommandObjectMultiword(interpreter
, "target modules",
4175 "Commands for accessing information for one or "
4176 "more target modules.",
4177 "target modules <sub-command> ...") {
4179 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter
)));
4180 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
4182 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
4184 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
4188 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter
)));
4192 new CommandObjectTargetModulesImageSearchPaths(interpreter
)));
4195 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter
)));
4198 ~CommandObjectTargetModules() override
= default;
4201 // For CommandObjectTargetModules only
4202 CommandObjectTargetModules(const CommandObjectTargetModules
&) = delete;
4203 const CommandObjectTargetModules
&
4204 operator=(const CommandObjectTargetModules
&) = delete;
4207 class CommandObjectTargetSymbolsAdd
: public CommandObjectParsed
{
4209 CommandObjectTargetSymbolsAdd(CommandInterpreter
&interpreter
)
4210 : CommandObjectParsed(
4211 interpreter
, "target symbols add",
4212 "Add a debug symbol file to one of the target's current modules by "
4213 "specifying a path to a debug symbols file or by using the options "
4214 "to specify a module.",
4215 "target symbols add <cmd-options> [<symfile>]",
4216 eCommandRequiresTarget
),
4218 LLDB_OPT_SET_1
, false, "shlib", 's', lldb::eModuleCompletion
,
4220 "Locate the debug symbols for the shared library specified by "
4222 m_current_frame_option(
4223 LLDB_OPT_SET_2
, false, "frame", 'F',
4224 "Locate the debug symbols for the currently selected frame.", false,
4226 m_current_stack_option(LLDB_OPT_SET_2
, false, "stack", 'S',
4227 "Locate the debug symbols for every frame in "
4228 "the current call stack.",
4232 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
4234 m_option_group
.Append(&m_file_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
4235 m_option_group
.Append(&m_current_frame_option
, LLDB_OPT_SET_2
,
4237 m_option_group
.Append(&m_current_stack_option
, LLDB_OPT_SET_2
,
4239 m_option_group
.Finalize();
4240 AddSimpleArgumentList(eArgTypeFilename
);
4243 ~CommandObjectTargetSymbolsAdd() override
= default;
4245 Options
*GetOptions() override
{ return &m_option_group
; }
4248 bool AddModuleSymbols(Target
*target
, ModuleSpec
&module_spec
, bool &flush
,
4249 CommandReturnObject
&result
) {
4250 const FileSpec
&symbol_fspec
= module_spec
.GetSymbolFileSpec();
4251 if (!symbol_fspec
) {
4253 "one or more executable image paths must be specified");
4257 char symfile_path
[PATH_MAX
];
4258 symbol_fspec
.GetPath(symfile_path
, sizeof(symfile_path
));
4260 if (!module_spec
.GetUUID().IsValid()) {
4261 if (!module_spec
.GetFileSpec() && !module_spec
.GetPlatformFileSpec())
4262 module_spec
.GetFileSpec().SetFilename(symbol_fspec
.GetFilename());
4265 // Now module_spec represents a symbol file for a module that might exist
4266 // in the current target. Let's find possible matches.
4267 ModuleList matching_modules
;
4269 // First extract all module specs from the symbol file
4270 lldb_private::ModuleSpecList symfile_module_specs
;
4271 if (ObjectFile::GetModuleSpecifications(module_spec
.GetSymbolFileSpec(),
4272 0, 0, symfile_module_specs
)) {
4273 // Now extract the module spec that matches the target architecture
4274 ModuleSpec target_arch_module_spec
;
4275 ModuleSpec symfile_module_spec
;
4276 target_arch_module_spec
.GetArchitecture() = target
->GetArchitecture();
4277 if (symfile_module_specs
.FindMatchingModuleSpec(target_arch_module_spec
,
4278 symfile_module_spec
)) {
4279 if (symfile_module_spec
.GetUUID().IsValid()) {
4280 // It has a UUID, look for this UUID in the target modules
4281 ModuleSpec symfile_uuid_module_spec
;
4282 symfile_uuid_module_spec
.GetUUID() = symfile_module_spec
.GetUUID();
4283 target
->GetImages().FindModules(symfile_uuid_module_spec
,
4288 if (matching_modules
.IsEmpty()) {
4289 // No matches yet. Iterate through the module specs to find a UUID
4290 // value that we can match up to an image in our target.
4291 const size_t num_symfile_module_specs
= symfile_module_specs
.GetSize();
4293 i
< num_symfile_module_specs
&& matching_modules
.IsEmpty(); ++i
) {
4294 if (symfile_module_specs
.GetModuleSpecAtIndex(
4295 i
, symfile_module_spec
)) {
4296 if (symfile_module_spec
.GetUUID().IsValid()) {
4297 // It has a UUID. Look for this UUID in the target modules.
4298 ModuleSpec symfile_uuid_module_spec
;
4299 symfile_uuid_module_spec
.GetUUID() =
4300 symfile_module_spec
.GetUUID();
4301 target
->GetImages().FindModules(symfile_uuid_module_spec
,
4309 // Just try to match up the file by basename if we have no matches at
4310 // this point. For example, module foo might have symbols in foo.debug.
4311 if (matching_modules
.IsEmpty())
4312 target
->GetImages().FindModules(module_spec
, matching_modules
);
4314 while (matching_modules
.IsEmpty()) {
4315 ConstString
filename_no_extension(
4316 module_spec
.GetFileSpec().GetFileNameStrippingExtension());
4317 // Empty string returned, let's bail
4318 if (!filename_no_extension
)
4321 // Check if there was no extension to strip and the basename is the same
4322 if (filename_no_extension
== module_spec
.GetFileSpec().GetFilename())
4325 // Replace basename with one fewer extension
4326 module_spec
.GetFileSpec().SetFilename(filename_no_extension
);
4327 target
->GetImages().FindModules(module_spec
, matching_modules
);
4330 if (matching_modules
.GetSize() > 1) {
4331 result
.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4332 "use the --uuid option to resolve the "
4338 if (matching_modules
.GetSize() == 1) {
4339 ModuleSP
module_sp(matching_modules
.GetModuleAtIndex(0));
4341 // The module has not yet created its symbol vendor, we can just give
4342 // the existing target module the symfile path to use for when it
4343 // decides to create it!
4344 module_sp
->SetSymbolFileFileSpec(symbol_fspec
);
4346 SymbolFile
*symbol_file
=
4347 module_sp
->GetSymbolFile(true, &result
.GetErrorStream());
4349 ObjectFile
*object_file
= symbol_file
->GetObjectFile();
4350 if (object_file
&& object_file
->GetFileSpec() == symbol_fspec
) {
4351 // Provide feedback that the symfile has been successfully added.
4352 const FileSpec
&module_fs
= module_sp
->GetFileSpec();
4353 result
.AppendMessageWithFormat(
4354 "symbol file '%s' has been added to '%s'\n", symfile_path
,
4355 module_fs
.GetPath().c_str());
4357 // Let clients know something changed in the module if it is
4359 ModuleList module_list
;
4360 module_list
.Append(module_sp
);
4361 target
->SymbolsDidLoad(module_list
);
4363 // Make sure we load any scripting resources that may be embedded
4364 // in the debug info files in case the platform supports that.
4366 StreamString feedback_stream
;
4367 module_sp
->LoadScriptingResourceInTarget(target
, error
,
4369 if (error
.Fail() && error
.AsCString())
4370 result
.AppendWarningWithFormat(
4371 "unable to load scripting data for module %s - error "
4373 module_sp
->GetFileSpec()
4374 .GetFileNameStrippingExtension()
4377 else if (feedback_stream
.GetSize())
4378 result
.AppendWarning(feedback_stream
.GetData());
4381 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4385 // Clear the symbol file spec if anything went wrong
4386 module_sp
->SetSymbolFileFileSpec(FileSpec());
4389 StreamString ss_symfile_uuid
;
4390 if (module_spec
.GetUUID().IsValid()) {
4391 ss_symfile_uuid
<< " (";
4392 module_spec
.GetUUID().Dump(ss_symfile_uuid
);
4393 ss_symfile_uuid
<< ')';
4395 result
.AppendErrorWithFormat(
4396 "symbol file '%s'%s does not match any existing module%s\n",
4397 symfile_path
, ss_symfile_uuid
.GetData(),
4398 !llvm::sys::fs::is_regular_file(symbol_fspec
.GetPath())
4399 ? "\n please specify the full path to the symbol file"
4404 bool DownloadObjectAndSymbolFile(ModuleSpec
&module_spec
,
4405 CommandReturnObject
&result
, bool &flush
) {
4407 if (PluginManager::DownloadObjectAndSymbolFile(module_spec
, error
)) {
4408 if (module_spec
.GetSymbolFileSpec())
4409 return AddModuleSymbols(m_exe_ctx
.GetTargetPtr(), module_spec
, flush
,
4412 result
.SetError(std::move(error
));
4417 bool AddSymbolsForUUID(CommandReturnObject
&result
, bool &flush
) {
4418 assert(m_uuid_option_group
.GetOptionValue().OptionWasSet());
4420 ModuleSpec module_spec
;
4421 module_spec
.GetUUID() =
4422 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
4424 if (!DownloadObjectAndSymbolFile(module_spec
, result
, flush
)) {
4425 StreamString error_strm
;
4426 error_strm
.PutCString("unable to find debug symbols for UUID ");
4427 module_spec
.GetUUID().Dump(error_strm
);
4428 result
.AppendError(error_strm
.GetString());
4435 bool AddSymbolsForFile(CommandReturnObject
&result
, bool &flush
) {
4436 assert(m_file_option
.GetOptionValue().OptionWasSet());
4438 ModuleSpec module_spec
;
4439 module_spec
.GetFileSpec() =
4440 m_file_option
.GetOptionValue().GetCurrentValue();
4442 Target
*target
= m_exe_ctx
.GetTargetPtr();
4443 ModuleSP
module_sp(target
->GetImages().FindFirstModule(module_spec
));
4445 module_spec
.GetFileSpec() = module_sp
->GetFileSpec();
4446 module_spec
.GetPlatformFileSpec() = module_sp
->GetPlatformFileSpec();
4447 module_spec
.GetUUID() = module_sp
->GetUUID();
4448 module_spec
.GetArchitecture() = module_sp
->GetArchitecture();
4450 module_spec
.GetArchitecture() = target
->GetArchitecture();
4453 if (!DownloadObjectAndSymbolFile(module_spec
, result
, flush
)) {
4454 StreamString error_strm
;
4455 error_strm
.PutCString(
4456 "unable to find debug symbols for the executable file ");
4457 error_strm
<< module_spec
.GetFileSpec();
4458 result
.AppendError(error_strm
.GetString());
4465 bool AddSymbolsForFrame(CommandReturnObject
&result
, bool &flush
) {
4466 assert(m_current_frame_option
.GetOptionValue().OptionWasSet());
4468 Process
*process
= m_exe_ctx
.GetProcessPtr();
4471 "a process must exist in order to use the --frame option");
4475 const StateType process_state
= process
->GetState();
4476 if (!StateIsStoppedState(process_state
, true)) {
4477 result
.AppendErrorWithFormat("process is not stopped: %s",
4478 StateAsCString(process_state
));
4482 StackFrame
*frame
= m_exe_ctx
.GetFramePtr();
4484 result
.AppendError("invalid current frame");
4488 ModuleSP
frame_module_sp(
4489 frame
->GetSymbolContext(eSymbolContextModule
).module_sp
);
4490 if (!frame_module_sp
) {
4491 result
.AppendError("frame has no module");
4495 ModuleSpec module_spec
;
4496 module_spec
.GetUUID() = frame_module_sp
->GetUUID();
4497 module_spec
.GetArchitecture() = frame_module_sp
->GetArchitecture();
4498 module_spec
.GetFileSpec() = frame_module_sp
->GetPlatformFileSpec();
4500 if (!DownloadObjectAndSymbolFile(module_spec
, result
, flush
)) {
4501 result
.AppendError("unable to find debug symbols for the current frame");
4508 bool AddSymbolsForStack(CommandReturnObject
&result
, bool &flush
) {
4509 assert(m_current_stack_option
.GetOptionValue().OptionWasSet());
4511 Process
*process
= m_exe_ctx
.GetProcessPtr();
4514 "a process must exist in order to use the --stack option");
4518 const StateType process_state
= process
->GetState();
4519 if (!StateIsStoppedState(process_state
, true)) {
4520 result
.AppendErrorWithFormat("process is not stopped: %s",
4521 StateAsCString(process_state
));
4525 Thread
*thread
= m_exe_ctx
.GetThreadPtr();
4527 result
.AppendError("invalid current thread");
4531 bool symbols_found
= false;
4532 uint32_t frame_count
= thread
->GetStackFrameCount();
4533 for (uint32_t i
= 0; i
< frame_count
; ++i
) {
4534 lldb::StackFrameSP frame_sp
= thread
->GetStackFrameAtIndex(i
);
4536 ModuleSP
frame_module_sp(
4537 frame_sp
->GetSymbolContext(eSymbolContextModule
).module_sp
);
4538 if (!frame_module_sp
)
4541 ModuleSpec module_spec
;
4542 module_spec
.GetUUID() = frame_module_sp
->GetUUID();
4543 module_spec
.GetFileSpec() = frame_module_sp
->GetPlatformFileSpec();
4544 module_spec
.GetArchitecture() = frame_module_sp
->GetArchitecture();
4546 bool current_frame_flush
= false;
4547 if (DownloadObjectAndSymbolFile(module_spec
, result
, current_frame_flush
))
4548 symbols_found
= true;
4549 flush
|= current_frame_flush
;
4552 if (!symbols_found
) {
4554 "unable to find debug symbols in the current call stack");
4561 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
4562 Target
*target
= m_exe_ctx
.GetTargetPtr();
4563 result
.SetStatus(eReturnStatusFailed
);
4565 ModuleSpec module_spec
;
4566 const bool uuid_option_set
=
4567 m_uuid_option_group
.GetOptionValue().OptionWasSet();
4568 const bool file_option_set
= m_file_option
.GetOptionValue().OptionWasSet();
4569 const bool frame_option_set
=
4570 m_current_frame_option
.GetOptionValue().OptionWasSet();
4571 const bool stack_option_set
=
4572 m_current_stack_option
.GetOptionValue().OptionWasSet();
4573 const size_t argc
= args
.GetArgumentCount();
4576 if (uuid_option_set
)
4577 AddSymbolsForUUID(result
, flush
);
4578 else if (file_option_set
)
4579 AddSymbolsForFile(result
, flush
);
4580 else if (frame_option_set
)
4581 AddSymbolsForFrame(result
, flush
);
4582 else if (stack_option_set
)
4583 AddSymbolsForStack(result
, flush
);
4585 result
.AppendError("one or more symbol file paths must be specified, "
4586 "or options must be specified");
4588 if (uuid_option_set
) {
4589 result
.AppendError("specify either one or more paths to symbol files "
4590 "or use the --uuid option without arguments");
4591 } else if (frame_option_set
) {
4592 result
.AppendError("specify either one or more paths to symbol files "
4593 "or use the --frame option without arguments");
4594 } else if (file_option_set
&& argc
> 1) {
4595 result
.AppendError("specify at most one symbol file path when "
4596 "--shlib option is set");
4598 PlatformSP
platform_sp(target
->GetPlatform());
4600 for (auto &entry
: args
.entries()) {
4601 if (!entry
.ref().empty()) {
4602 auto &symbol_file_spec
= module_spec
.GetSymbolFileSpec();
4603 symbol_file_spec
.SetFile(entry
.ref(), FileSpec::Style::native
);
4604 FileSystem::Instance().Resolve(symbol_file_spec
);
4605 if (file_option_set
) {
4606 module_spec
.GetFileSpec() =
4607 m_file_option
.GetOptionValue().GetCurrentValue();
4610 FileSpec symfile_spec
;
4612 ->ResolveSymbolFile(*target
, module_spec
, symfile_spec
)
4614 module_spec
.GetSymbolFileSpec() = symfile_spec
;
4617 bool symfile_exists
=
4618 FileSystem::Instance().Exists(module_spec
.GetSymbolFileSpec());
4620 if (symfile_exists
) {
4621 if (!AddModuleSymbols(target
, module_spec
, flush
, result
))
4624 std::string resolved_symfile_path
=
4625 module_spec
.GetSymbolFileSpec().GetPath();
4626 if (resolved_symfile_path
!= entry
.ref()) {
4627 result
.AppendErrorWithFormat(
4628 "invalid module path '%s' with resolved path '%s'\n",
4629 entry
.c_str(), resolved_symfile_path
.c_str());
4632 result
.AppendErrorWithFormat("invalid module path '%s'\n",
4642 Process
*process
= m_exe_ctx
.GetProcessPtr();
4648 OptionGroupOptions m_option_group
;
4649 OptionGroupUUID m_uuid_option_group
;
4650 OptionGroupFile m_file_option
;
4651 OptionGroupBoolean m_current_frame_option
;
4652 OptionGroupBoolean m_current_stack_option
;
4655 #pragma mark CommandObjectTargetSymbols
4657 // CommandObjectTargetSymbols
4659 class CommandObjectTargetSymbols
: public CommandObjectMultiword
{
4661 // Constructors and Destructors
4662 CommandObjectTargetSymbols(CommandInterpreter
&interpreter
)
4663 : CommandObjectMultiword(
4664 interpreter
, "target symbols",
4665 "Commands for adding and managing debug symbol files.",
4666 "target symbols <sub-command> ...") {
4668 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter
)));
4671 ~CommandObjectTargetSymbols() override
= default;
4674 // For CommandObjectTargetModules only
4675 CommandObjectTargetSymbols(const CommandObjectTargetSymbols
&) = delete;
4676 const CommandObjectTargetSymbols
&
4677 operator=(const CommandObjectTargetSymbols
&) = delete;
4680 #pragma mark CommandObjectTargetStopHookAdd
4682 // CommandObjectTargetStopHookAdd
4683 #define LLDB_OPTIONS_target_stop_hook_add
4684 #include "CommandOptions.inc"
4686 class CommandObjectTargetStopHookAdd
: public CommandObjectParsed
,
4687 public IOHandlerDelegateMultiline
{
4689 class CommandOptions
: public OptionGroup
{
4691 CommandOptions() : m_line_end(UINT_MAX
) {}
4693 ~CommandOptions() override
= default;
4695 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
4696 return llvm::ArrayRef(g_target_stop_hook_add_options
);
4699 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
4700 ExecutionContext
*execution_context
) override
{
4702 const int short_option
=
4703 g_target_stop_hook_add_options
[option_idx
].short_option
;
4705 switch (short_option
) {
4707 m_class_name
= std::string(option_arg
);
4708 m_sym_ctx_specified
= true;
4712 if (option_arg
.getAsInteger(0, m_line_end
)) {
4713 error
= Status::FromErrorStringWithFormat(
4714 "invalid end line number: \"%s\"", option_arg
.str().c_str());
4717 m_sym_ctx_specified
= true;
4721 bool value
, success
;
4722 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
4724 m_auto_continue
= value
;
4726 error
= Status::FromErrorStringWithFormat(
4727 "invalid boolean value '%s' passed for -G option",
4728 option_arg
.str().c_str());
4731 if (option_arg
.getAsInteger(0, m_line_start
)) {
4732 error
= Status::FromErrorStringWithFormat(
4733 "invalid start line number: \"%s\"", option_arg
.str().c_str());
4736 m_sym_ctx_specified
= true;
4740 m_no_inlines
= true;
4744 m_function_name
= std::string(option_arg
);
4745 m_func_name_type_mask
|= eFunctionNameTypeAuto
;
4746 m_sym_ctx_specified
= true;
4750 m_file_name
= std::string(option_arg
);
4751 m_sym_ctx_specified
= true;
4755 m_module_name
= std::string(option_arg
);
4756 m_sym_ctx_specified
= true;
4760 if (option_arg
.getAsInteger(0, m_thread_id
))
4761 error
= Status::FromErrorStringWithFormat(
4762 "invalid thread id string '%s'", option_arg
.str().c_str());
4763 m_thread_specified
= true;
4767 m_thread_name
= std::string(option_arg
);
4768 m_thread_specified
= true;
4772 m_queue_name
= std::string(option_arg
);
4773 m_thread_specified
= true;
4777 if (option_arg
.getAsInteger(0, m_thread_index
))
4778 error
= Status::FromErrorStringWithFormat(
4779 "invalid thread index string '%s'", option_arg
.str().c_str());
4780 m_thread_specified
= true;
4784 m_use_one_liner
= true;
4785 m_one_liner
.push_back(std::string(option_arg
));
4789 llvm_unreachable("Unimplemented option");
4794 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
4795 m_class_name
.clear();
4796 m_function_name
.clear();
4798 m_line_end
= LLDB_INVALID_LINE_NUMBER
;
4799 m_file_name
.clear();
4800 m_module_name
.clear();
4801 m_func_name_type_mask
= eFunctionNameTypeAuto
;
4802 m_thread_id
= LLDB_INVALID_THREAD_ID
;
4803 m_thread_index
= UINT32_MAX
;
4804 m_thread_name
.clear();
4805 m_queue_name
.clear();
4807 m_no_inlines
= false;
4808 m_sym_ctx_specified
= false;
4809 m_thread_specified
= false;
4811 m_use_one_liner
= false;
4812 m_one_liner
.clear();
4813 m_auto_continue
= false;
4816 std::string m_class_name
;
4817 std::string m_function_name
;
4818 uint32_t m_line_start
= 0;
4819 uint32_t m_line_end
= LLDB_INVALID_LINE_NUMBER
;
4820 std::string m_file_name
;
4821 std::string m_module_name
;
4822 uint32_t m_func_name_type_mask
=
4823 eFunctionNameTypeAuto
; // A pick from lldb::FunctionNameType.
4824 lldb::tid_t m_thread_id
= LLDB_INVALID_THREAD_ID
;
4825 uint32_t m_thread_index
= UINT32_MAX
;
4826 std::string m_thread_name
;
4827 std::string m_queue_name
;
4828 bool m_sym_ctx_specified
= false;
4829 bool m_no_inlines
= false;
4830 bool m_thread_specified
= false;
4831 // Instance variables to hold the values for one_liner options.
4832 bool m_use_one_liner
= false;
4833 std::vector
<std::string
> m_one_liner
;
4835 bool m_auto_continue
= false;
4838 CommandObjectTargetStopHookAdd(CommandInterpreter
&interpreter
)
4839 : CommandObjectParsed(interpreter
, "target stop-hook add",
4840 "Add a hook to be executed when the target stops."
4841 "The hook can either be a list of commands or an "
4842 "appropriately defined Python class. You can also "
4843 "add filters so the hook only runs a certain stop "
4845 "target stop-hook add"),
4846 IOHandlerDelegateMultiline("DONE",
4847 IOHandlerDelegate::Completion::LLDBCommand
),
4848 m_python_class_options("scripted stop-hook", true, 'P') {
4851 Command Based stop-hooks:
4852 -------------------------
4853 Stop hooks can run a list of lldb commands by providing one or more
4854 --one-line-command options. The commands will get run in the order they are
4855 added. Or you can provide no commands, in which case you will enter a
4856 command editor where you can enter the commands to be run.
4858 Python Based Stop Hooks:
4859 ------------------------
4860 Stop hooks can be implemented with a suitably defined Python class, whose name
4861 is passed in the --python-class option.
4863 When the stop hook is added, the class is initialized by calling:
4865 def __init__(self, target, extra_args, internal_dict):
4867 target: The target that the stop hook is being added to.
4868 extra_args: An SBStructuredData Dictionary filled with the -key -value
4869 option pairs passed to the command.
4870 dict: An implementation detail provided by lldb.
4872 Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4873 The method has the signature:
4875 def handle_stop(self, exe_ctx, stream):
4877 exe_ctx: An SBExecutionContext for the thread that has stopped.
4878 stream: An SBStream, anything written to this stream will be printed in the
4879 the stop message when the process stops.
4881 Return Value: The method returns "should_stop
". If should_stop is false
4882 from all the stop hook executions on threads that stopped
4883 with a reason, then the process will continue. Note that this
4884 will happen only after all the stop hooks are run.
4888 Stop hooks can be set to always run, or to only run when the stopped thread
4889 matches the filter options passed on the command line. The available filter
4890 options include a shared library or a thread or queue specification,
4891 a line range in a source file, a function name or a class name.
4893 m_all_options
.Append(&m_python_class_options
,
4894 LLDB_OPT_SET_1
| LLDB_OPT_SET_2
,
4895 LLDB_OPT_SET_FROM_TO(4, 6));
4896 m_all_options
.Append(&m_options
);
4897 m_all_options
.Finalize();
4900 ~CommandObjectTargetStopHookAdd() override
= default;
4902 Options
*GetOptions() override
{ return &m_all_options
; }
4905 void IOHandlerActivated(IOHandler
&io_handler
, bool interactive
) override
{
4906 StreamFileSP
output_sp(io_handler
.GetOutputStreamFileSP());
4907 if (output_sp
&& interactive
) {
4908 output_sp
->PutCString(
4909 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4914 void IOHandlerInputComplete(IOHandler
&io_handler
,
4915 std::string
&line
) override
{
4916 if (m_stop_hook_sp
) {
4918 StreamFileSP
error_sp(io_handler
.GetErrorStreamFileSP());
4920 error_sp
->Printf("error: stop hook #%" PRIu64
4921 " aborted, no commands.\n",
4922 m_stop_hook_sp
->GetID());
4925 GetTarget().UndoCreateStopHook(m_stop_hook_sp
->GetID());
4927 // The IOHandler editor is only for command lines stop hooks:
4928 Target::StopHookCommandLine
*hook_ptr
=
4929 static_cast<Target::StopHookCommandLine
*>(m_stop_hook_sp
.get());
4931 hook_ptr
->SetActionFromString(line
);
4932 StreamFileSP
output_sp(io_handler
.GetOutputStreamFileSP());
4934 output_sp
->Printf("Stop hook #%" PRIu64
" added.\n",
4935 m_stop_hook_sp
->GetID());
4939 m_stop_hook_sp
.reset();
4941 io_handler
.SetIsDone(true);
4944 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
4945 m_stop_hook_sp
.reset();
4947 Target
&target
= GetTarget();
4948 Target::StopHookSP new_hook_sp
=
4949 target
.CreateStopHook(m_python_class_options
.GetName().empty() ?
4950 Target::StopHook::StopHookKind::CommandBased
4951 : Target::StopHook::StopHookKind::ScriptBased
);
4953 // First step, make the specifier.
4954 std::unique_ptr
<SymbolContextSpecifier
> specifier_up
;
4955 if (m_options
.m_sym_ctx_specified
) {
4956 specifier_up
= std::make_unique
<SymbolContextSpecifier
>(
4957 GetDebugger().GetSelectedTarget());
4959 if (!m_options
.m_module_name
.empty()) {
4960 specifier_up
->AddSpecification(
4961 m_options
.m_module_name
.c_str(),
4962 SymbolContextSpecifier::eModuleSpecified
);
4965 if (!m_options
.m_class_name
.empty()) {
4966 specifier_up
->AddSpecification(
4967 m_options
.m_class_name
.c_str(),
4968 SymbolContextSpecifier::eClassOrNamespaceSpecified
);
4971 if (!m_options
.m_file_name
.empty()) {
4972 specifier_up
->AddSpecification(m_options
.m_file_name
.c_str(),
4973 SymbolContextSpecifier::eFileSpecified
);
4976 if (m_options
.m_line_start
!= 0) {
4977 specifier_up
->AddLineSpecification(
4978 m_options
.m_line_start
,
4979 SymbolContextSpecifier::eLineStartSpecified
);
4982 if (m_options
.m_line_end
!= UINT_MAX
) {
4983 specifier_up
->AddLineSpecification(
4984 m_options
.m_line_end
, SymbolContextSpecifier::eLineEndSpecified
);
4987 if (!m_options
.m_function_name
.empty()) {
4988 specifier_up
->AddSpecification(
4989 m_options
.m_function_name
.c_str(),
4990 SymbolContextSpecifier::eFunctionSpecified
);
4995 new_hook_sp
->SetSpecifier(specifier_up
.release());
4997 // Next see if any of the thread options have been entered:
4999 if (m_options
.m_thread_specified
) {
5000 ThreadSpec
*thread_spec
= new ThreadSpec();
5002 if (m_options
.m_thread_id
!= LLDB_INVALID_THREAD_ID
) {
5003 thread_spec
->SetTID(m_options
.m_thread_id
);
5006 if (m_options
.m_thread_index
!= UINT32_MAX
)
5007 thread_spec
->SetIndex(m_options
.m_thread_index
);
5009 if (!m_options
.m_thread_name
.empty())
5010 thread_spec
->SetName(m_options
.m_thread_name
.c_str());
5012 if (!m_options
.m_queue_name
.empty())
5013 thread_spec
->SetQueueName(m_options
.m_queue_name
.c_str());
5015 new_hook_sp
->SetThreadSpecifier(thread_spec
);
5018 new_hook_sp
->SetAutoContinue(m_options
.m_auto_continue
);
5019 if (m_options
.m_use_one_liner
) {
5020 // This is a command line stop hook:
5021 Target::StopHookCommandLine
*hook_ptr
=
5022 static_cast<Target::StopHookCommandLine
*>(new_hook_sp
.get());
5023 hook_ptr
->SetActionFromStrings(m_options
.m_one_liner
);
5024 result
.AppendMessageWithFormat("Stop hook #%" PRIu64
" added.\n",
5025 new_hook_sp
->GetID());
5026 } else if (!m_python_class_options
.GetName().empty()) {
5027 // This is a scripted stop hook:
5028 Target::StopHookScripted
*hook_ptr
=
5029 static_cast<Target::StopHookScripted
*>(new_hook_sp
.get());
5030 Status error
= hook_ptr
->SetScriptCallback(
5031 m_python_class_options
.GetName(),
5032 m_python_class_options
.GetStructuredData());
5033 if (error
.Success())
5034 result
.AppendMessageWithFormat("Stop hook #%" PRIu64
" added.\n",
5035 new_hook_sp
->GetID());
5037 // FIXME: Set the stop hook ID counter back.
5038 result
.AppendErrorWithFormat("Couldn't add stop hook: %s",
5040 target
.UndoCreateStopHook(new_hook_sp
->GetID());
5044 m_stop_hook_sp
= new_hook_sp
;
5045 m_interpreter
.GetLLDBCommandsFromIOHandler("> ", // Prompt
5046 *this); // IOHandlerDelegate
5048 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
5052 CommandOptions m_options
;
5053 OptionGroupPythonClassWithDict m_python_class_options
;
5054 OptionGroupOptions m_all_options
;
5056 Target::StopHookSP m_stop_hook_sp
;
5059 #pragma mark CommandObjectTargetStopHookDelete
5061 // CommandObjectTargetStopHookDelete
5063 class CommandObjectTargetStopHookDelete
: public CommandObjectParsed
{
5065 CommandObjectTargetStopHookDelete(CommandInterpreter
&interpreter
)
5066 : CommandObjectParsed(interpreter
, "target stop-hook delete",
5067 "Delete a stop-hook.",
5068 "target stop-hook delete [<idx>]") {
5069 AddSimpleArgumentList(eArgTypeStopHookID
, eArgRepeatStar
);
5072 ~CommandObjectTargetStopHookDelete() override
= default;
5075 HandleArgumentCompletion(CompletionRequest
&request
,
5076 OptionElementVector
&opt_element_vector
) override
{
5077 if (request
.GetCursorIndex())
5079 CommandObject::HandleArgumentCompletion(request
, opt_element_vector
);
5083 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5084 Target
&target
= GetTarget();
5085 // FIXME: see if we can use the breakpoint id style parser?
5086 size_t num_args
= command
.GetArgumentCount();
5087 if (num_args
== 0) {
5088 if (!m_interpreter
.Confirm("Delete all stop hooks?", true)) {
5089 result
.SetStatus(eReturnStatusFailed
);
5092 target
.RemoveAllStopHooks();
5095 for (size_t i
= 0; i
< num_args
; i
++) {
5096 lldb::user_id_t user_id
;
5097 if (!llvm::to_integer(command
.GetArgumentAtIndex(i
), user_id
)) {
5098 result
.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
5099 command
.GetArgumentAtIndex(i
));
5102 if (!target
.RemoveStopHookByID(user_id
)) {
5103 result
.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
5104 command
.GetArgumentAtIndex(i
));
5109 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
5113 #pragma mark CommandObjectTargetStopHookEnableDisable
5115 // CommandObjectTargetStopHookEnableDisable
5117 class CommandObjectTargetStopHookEnableDisable
: public CommandObjectParsed
{
5119 CommandObjectTargetStopHookEnableDisable(CommandInterpreter
&interpreter
,
5120 bool enable
, const char *name
,
5121 const char *help
, const char *syntax
)
5122 : CommandObjectParsed(interpreter
, name
, help
, syntax
), m_enable(enable
) {
5123 AddSimpleArgumentList(eArgTypeStopHookID
, eArgRepeatStar
);
5126 ~CommandObjectTargetStopHookEnableDisable() override
= default;
5129 HandleArgumentCompletion(CompletionRequest
&request
,
5130 OptionElementVector
&opt_element_vector
) override
{
5131 if (request
.GetCursorIndex())
5133 CommandObject::HandleArgumentCompletion(request
, opt_element_vector
);
5137 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5138 Target
&target
= GetTarget();
5139 // FIXME: see if we can use the breakpoint id style parser?
5140 size_t num_args
= command
.GetArgumentCount();
5143 if (num_args
== 0) {
5144 target
.SetAllStopHooksActiveState(m_enable
);
5146 for (size_t i
= 0; i
< num_args
; i
++) {
5147 lldb::user_id_t user_id
;
5148 if (!llvm::to_integer(command
.GetArgumentAtIndex(i
), user_id
)) {
5149 result
.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
5150 command
.GetArgumentAtIndex(i
));
5153 success
= target
.SetStopHookActiveStateByID(user_id
, m_enable
);
5155 result
.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
5156 command
.GetArgumentAtIndex(i
));
5161 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
5168 #pragma mark CommandObjectTargetStopHookList
5170 // CommandObjectTargetStopHookList
5172 class CommandObjectTargetStopHookList
: public CommandObjectParsed
{
5174 CommandObjectTargetStopHookList(CommandInterpreter
&interpreter
)
5175 : CommandObjectParsed(interpreter
, "target stop-hook list",
5176 "List all stop-hooks.", "target stop-hook list") {}
5178 ~CommandObjectTargetStopHookList() override
= default;
5181 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5182 Target
&target
= GetTarget();
5184 size_t num_hooks
= target
.GetNumStopHooks();
5185 if (num_hooks
== 0) {
5186 result
.GetOutputStream().PutCString("No stop hooks.\n");
5188 for (size_t i
= 0; i
< num_hooks
; i
++) {
5189 Target::StopHookSP this_hook
= target
.GetStopHookAtIndex(i
);
5191 result
.GetOutputStream().PutCString("\n");
5192 this_hook
->GetDescription(result
.GetOutputStream(),
5193 eDescriptionLevelFull
);
5196 result
.SetStatus(eReturnStatusSuccessFinishResult
);
5200 #pragma mark CommandObjectMultiwordTargetStopHooks
5202 // CommandObjectMultiwordTargetStopHooks
5204 class CommandObjectMultiwordTargetStopHooks
: public CommandObjectMultiword
{
5206 CommandObjectMultiwordTargetStopHooks(CommandInterpreter
&interpreter
)
5207 : CommandObjectMultiword(
5208 interpreter
, "target stop-hook",
5209 "Commands for operating on debugger target stop-hooks.",
5210 "target stop-hook <subcommand> [<subcommand-options>]") {
5211 LoadSubCommand("add", CommandObjectSP(
5212 new CommandObjectTargetStopHookAdd(interpreter
)));
5215 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter
)));
5216 LoadSubCommand("disable",
5217 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5218 interpreter
, false, "target stop-hook disable [<id>]",
5219 "Disable a stop-hook.", "target stop-hook disable")));
5220 LoadSubCommand("enable",
5221 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5222 interpreter
, true, "target stop-hook enable [<id>]",
5223 "Enable a stop-hook.", "target stop-hook enable")));
5224 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
5228 ~CommandObjectMultiwordTargetStopHooks() override
= default;
5231 #pragma mark CommandObjectTargetDumpTypesystem
5233 /// Dumps the TypeSystem of the selected Target.
5234 class CommandObjectTargetDumpTypesystem
: public CommandObjectParsed
{
5236 CommandObjectTargetDumpTypesystem(CommandInterpreter
&interpreter
)
5237 : CommandObjectParsed(
5238 interpreter
, "target dump typesystem",
5239 "Dump the state of the target's internal type system. Intended to "
5240 "be used for debugging LLDB itself.",
5241 nullptr, eCommandRequiresTarget
) {}
5243 ~CommandObjectTargetDumpTypesystem() override
= default;
5246 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5247 // Go over every scratch TypeSystem and dump to the command output.
5248 for (lldb::TypeSystemSP ts
: GetTarget().GetScratchTypeSystems())
5250 ts
->Dump(result
.GetOutputStream().AsRawOstream());
5252 result
.SetStatus(eReturnStatusSuccessFinishResult
);
5256 #pragma mark CommandObjectTargetDumpSectionLoadList
5258 /// Dumps the SectionLoadList of the selected Target.
5259 class CommandObjectTargetDumpSectionLoadList
: public CommandObjectParsed
{
5261 CommandObjectTargetDumpSectionLoadList(CommandInterpreter
&interpreter
)
5262 : CommandObjectParsed(
5263 interpreter
, "target dump section-load-list",
5264 "Dump the state of the target's internal section load list. "
5265 "Intended to be used for debugging LLDB itself.",
5266 nullptr, eCommandRequiresTarget
) {}
5268 ~CommandObjectTargetDumpSectionLoadList() override
= default;
5271 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5272 Target
&target
= GetTarget();
5273 target
.GetSectionLoadList().Dump(result
.GetOutputStream(), &target
);
5274 result
.SetStatus(eReturnStatusSuccessFinishResult
);
5278 #pragma mark CommandObjectTargetDump
5280 /// Multi-word command for 'target dump'.
5281 class CommandObjectTargetDump
: public CommandObjectMultiword
{
5283 // Constructors and Destructors
5284 CommandObjectTargetDump(CommandInterpreter
&interpreter
)
5285 : CommandObjectMultiword(
5286 interpreter
, "target dump",
5287 "Commands for dumping information about the target.",
5288 "target dump [typesystem|section-load-list]") {
5291 CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter
)));
5292 LoadSubCommand("section-load-list",
5293 CommandObjectSP(new CommandObjectTargetDumpSectionLoadList(
5297 ~CommandObjectTargetDump() override
= default;
5300 #pragma mark CommandObjectMultiwordTarget
5302 // CommandObjectMultiwordTarget
5304 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5305 CommandInterpreter
&interpreter
)
5306 : CommandObjectMultiword(interpreter
, "target",
5307 "Commands for operating on debugger targets.",
5308 "target <subcommand> [<subcommand-options>]") {
5309 LoadSubCommand("create",
5310 CommandObjectSP(new CommandObjectTargetCreate(interpreter
)));
5311 LoadSubCommand("delete",
5312 CommandObjectSP(new CommandObjectTargetDelete(interpreter
)));
5313 LoadSubCommand("dump",
5314 CommandObjectSP(new CommandObjectTargetDump(interpreter
)));
5315 LoadSubCommand("list",
5316 CommandObjectSP(new CommandObjectTargetList(interpreter
)));
5317 LoadSubCommand("select",
5318 CommandObjectSP(new CommandObjectTargetSelect(interpreter
)));
5319 LoadSubCommand("show-launch-environment",
5320 CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
5324 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter
)));
5325 LoadSubCommand("modules",
5326 CommandObjectSP(new CommandObjectTargetModules(interpreter
)));
5327 LoadSubCommand("symbols",
5328 CommandObjectSP(new CommandObjectTargetSymbols(interpreter
)));
5329 LoadSubCommand("variable",
5330 CommandObjectSP(new CommandObjectTargetVariable(interpreter
)));
5333 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;