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/Debugger.h"
12 #include "lldb/Core/IOHandler.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Core/ValueObjectVariable.h"
17 #include "lldb/DataFormatters/ValueObjectPrinter.h"
18 #include "lldb/Host/OptionParser.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
21 #include "lldb/Interpreter/CommandReturnObject.h"
22 #include "lldb/Interpreter/OptionArgParser.h"
23 #include "lldb/Interpreter/OptionGroupArchitecture.h"
24 #include "lldb/Interpreter/OptionGroupBoolean.h"
25 #include "lldb/Interpreter/OptionGroupFile.h"
26 #include "lldb/Interpreter/OptionGroupFormat.h"
27 #include "lldb/Interpreter/OptionGroupPlatform.h"
28 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
29 #include "lldb/Interpreter/OptionGroupString.h"
30 #include "lldb/Interpreter/OptionGroupUInt64.h"
31 #include "lldb/Interpreter/OptionGroupUUID.h"
32 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
33 #include "lldb/Interpreter/OptionGroupVariable.h"
34 #include "lldb/Interpreter/Options.h"
35 #include "lldb/Symbol/CompileUnit.h"
36 #include "lldb/Symbol/FuncUnwinders.h"
37 #include "lldb/Symbol/LineTable.h"
38 #include "lldb/Symbol/LocateSymbolFile.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/StructuredData.h"
56 #include "lldb/Utility/Timer.h"
57 #include "lldb/lldb-enumerations.h"
58 #include "lldb/lldb-private-enumerations.h"
60 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
61 #include "clang/Frontend/CompilerInstance.h"
62 #include "clang/Frontend/CompilerInvocation.h"
63 #include "clang/Frontend/FrontendActions.h"
64 #include "llvm/ADT/ScopeExit.h"
65 #include "llvm/ADT/StringRef.h"
66 #include "llvm/Support/FileSystem.h"
67 #include "llvm/Support/FormatAdapters.h"
71 using namespace lldb_private
;
73 static void DumpTargetInfo(uint32_t target_idx
, Target
*target
,
74 const char *prefix_cstr
,
75 bool show_stopped_process_status
, Stream
&strm
) {
76 const ArchSpec
&target_arch
= target
->GetArchitecture();
78 Module
*exe_module
= target
->GetExecutableModulePointer();
79 char exe_path
[PATH_MAX
];
80 bool exe_valid
= false;
82 exe_valid
= exe_module
->GetFileSpec().GetPath(exe_path
, sizeof(exe_path
));
85 ::strcpy(exe_path
, "<none>");
87 std::string formatted_label
= "";
88 const std::string
&label
= target
->GetLabel();
90 formatted_label
= " (" + label
+ ")";
93 strm
.Printf("%starget #%u%s: %s", prefix_cstr
? prefix_cstr
: "", target_idx
,
94 formatted_label
.data(), exe_path
);
96 uint32_t properties
= 0;
97 if (target_arch
.IsValid()) {
98 strm
.Printf("%sarch=", properties
++ > 0 ? ", " : " ( ");
99 target_arch
.DumpTriple(strm
.AsRawOstream());
102 PlatformSP
platform_sp(target
->GetPlatform());
104 strm
.Format("{0}platform={1}", properties
++ > 0 ? ", " : " ( ",
105 platform_sp
->GetName());
107 ProcessSP
process_sp(target
->GetProcessSP());
108 bool show_process_status
= false;
110 lldb::pid_t pid
= process_sp
->GetID();
111 StateType state
= process_sp
->GetState();
112 if (show_stopped_process_status
)
113 show_process_status
= StateIsStoppedState(state
, true);
114 const char *state_cstr
= StateAsCString(state
);
115 if (pid
!= LLDB_INVALID_PROCESS_ID
)
116 strm
.Printf("%spid=%" PRIu64
, properties
++ > 0 ? ", " : " ( ", pid
);
117 strm
.Printf("%sstate=%s", properties
++ > 0 ? ", " : " ( ", state_cstr
);
120 strm
.PutCString(" )\n");
123 if (show_process_status
) {
124 const bool only_threads_with_stop_reason
= true;
125 const uint32_t start_frame
= 0;
126 const uint32_t num_frames
= 1;
127 const uint32_t num_frames_with_source
= 1;
128 const bool stop_format
= false;
129 process_sp
->GetStatus(strm
);
130 process_sp
->GetThreadStatus(strm
, only_threads_with_stop_reason
,
131 start_frame
, num_frames
, num_frames_with_source
,
136 static uint32_t DumpTargetList(TargetList
&target_list
,
137 bool show_stopped_process_status
, Stream
&strm
) {
138 const uint32_t num_targets
= target_list
.GetNumTargets();
140 TargetSP
selected_target_sp(target_list
.GetSelectedTarget());
141 strm
.PutCString("Current targets:\n");
142 for (uint32_t i
= 0; i
< num_targets
; ++i
) {
143 TargetSP
target_sp(target_list
.GetTargetAtIndex(i
));
145 bool is_selected
= target_sp
.get() == selected_target_sp
.get();
146 DumpTargetInfo(i
, target_sp
.get(), is_selected
? "* " : " ",
147 show_stopped_process_status
, strm
);
154 #define LLDB_OPTIONS_target_dependents
155 #include "CommandOptions.inc"
157 class OptionGroupDependents
: public OptionGroup
{
159 OptionGroupDependents() = default;
161 ~OptionGroupDependents() override
= default;
163 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
164 return llvm::ArrayRef(g_target_dependents_options
);
167 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_value
,
168 ExecutionContext
*execution_context
) override
{
171 // For compatibility no value means don't load dependents.
172 if (option_value
.empty()) {
173 m_load_dependent_files
= eLoadDependentsNo
;
177 const char short_option
=
178 g_target_dependents_options
[option_idx
].short_option
;
179 if (short_option
== 'd') {
180 LoadDependentFiles tmp_load_dependents
;
181 tmp_load_dependents
= (LoadDependentFiles
)OptionArgParser::ToOptionEnum(
182 option_value
, g_target_dependents_options
[option_idx
].enum_values
, 0,
185 m_load_dependent_files
= tmp_load_dependents
;
187 error
.SetErrorStringWithFormat("unrecognized short option '%c'",
194 Status
SetOptionValue(uint32_t, const char *, ExecutionContext
*) = delete;
196 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
197 m_load_dependent_files
= eLoadDependentsDefault
;
200 LoadDependentFiles m_load_dependent_files
;
203 OptionGroupDependents(const OptionGroupDependents
&) = delete;
204 const OptionGroupDependents
&
205 operator=(const OptionGroupDependents
&) = delete;
208 #pragma mark CommandObjectTargetCreate
210 class CommandObjectTargetCreate
: public CommandObjectParsed
{
212 CommandObjectTargetCreate(CommandInterpreter
&interpreter
)
213 : CommandObjectParsed(
214 interpreter
, "target create",
215 "Create a target using the argument as the main executable.",
217 m_platform_options(true), // Include the --platform option.
218 m_core_file(LLDB_OPT_SET_1
, false, "core", 'c', 0, eArgTypeFilename
,
219 "Fullpath to a core file to use for this target."),
220 m_label(LLDB_OPT_SET_1
, false, "label", 'l', 0, eArgTypeName
,
221 "Optional name for this target.", nullptr),
222 m_symbol_file(LLDB_OPT_SET_1
, false, "symfile", 's', 0,
224 "Fullpath to a stand alone debug "
225 "symbols file for when debug symbols "
226 "are not in the executable."),
228 LLDB_OPT_SET_1
, false, "remote-file", 'r', 0, eArgTypeFilename
,
229 "Fullpath to the file on the remote host if debugging remotely.") {
230 CommandArgumentEntry arg
;
231 CommandArgumentData file_arg
;
233 // Define the first (and only) variant of this arg.
234 file_arg
.arg_type
= eArgTypeFilename
;
235 file_arg
.arg_repetition
= eArgRepeatPlain
;
237 // There is only one variant this argument could be; put it into the
239 arg
.push_back(file_arg
);
241 // Push the data for the first argument into the m_arguments vector.
242 m_arguments
.push_back(arg
);
244 m_option_group
.Append(&m_arch_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
245 m_option_group
.Append(&m_platform_options
, LLDB_OPT_SET_ALL
, 1);
246 m_option_group
.Append(&m_core_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
247 m_option_group
.Append(&m_label
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
248 m_option_group
.Append(&m_symbol_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
249 m_option_group
.Append(&m_remote_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
250 m_option_group
.Append(&m_add_dependents
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
251 m_option_group
.Finalize();
254 ~CommandObjectTargetCreate() override
= default;
256 Options
*GetOptions() override
{ return &m_option_group
; }
259 HandleArgumentCompletion(CompletionRequest
&request
,
260 OptionElementVector
&opt_element_vector
) override
{
261 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
262 GetCommandInterpreter(), lldb::eDiskFileCompletion
, request
, nullptr);
266 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
267 const size_t argc
= command
.GetArgumentCount();
268 FileSpec
core_file(m_core_file
.GetOptionValue().GetCurrentValue());
269 FileSpec
remote_file(m_remote_file
.GetOptionValue().GetCurrentValue());
272 auto file
= FileSystem::Instance().Open(
273 core_file
, lldb_private::File::eOpenOptionReadOnly
);
276 result
.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
278 llvm::toString(file
.takeError()));
283 if (argc
== 1 || core_file
|| remote_file
) {
284 FileSpec
symfile(m_symbol_file
.GetOptionValue().GetCurrentValue());
286 auto file
= FileSystem::Instance().Open(
287 symfile
, lldb_private::File::eOpenOptionReadOnly
);
290 result
.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
292 llvm::toString(file
.takeError()));
297 const char *file_path
= command
.GetArgumentAtIndex(0);
298 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path
);
300 bool must_set_platform_path
= false;
302 Debugger
&debugger
= GetDebugger();
305 llvm::StringRef arch_cstr
= m_arch_option
.GetArchitectureName();
306 Status
error(debugger
.GetTargetList().CreateTarget(
307 debugger
, file_path
, arch_cstr
,
308 m_add_dependents
.m_load_dependent_files
, &m_platform_options
,
312 result
.AppendError(error
.AsCString());
316 const llvm::StringRef label
=
317 m_label
.GetOptionValue().GetCurrentValueAsRef();
318 if (!label
.empty()) {
319 if (auto E
= target_sp
->SetLabel(label
))
320 result
.SetError(std::move(E
));
324 auto on_error
= llvm::make_scope_exit(
325 [&target_list
= debugger
.GetTargetList(), &target_sp
]() {
326 target_list
.DeleteTarget(target_sp
);
329 // Only get the platform after we create the target because we might
330 // have switched platforms depending on what the arguments were to
331 // CreateTarget() we can't rely on the selected platform.
333 PlatformSP platform_sp
= target_sp
->GetPlatform();
337 file_spec
.SetFile(file_path
, FileSpec::Style::native
);
338 FileSystem::Instance().Resolve(file_spec
);
340 // Try to resolve the exe based on PATH and/or platform-specific
341 // suffixes, but only if using the host platform.
342 if (platform_sp
&& platform_sp
->IsHost() &&
343 !FileSystem::Instance().Exists(file_spec
))
344 FileSystem::Instance().ResolveExecutableLocation(file_spec
);
349 // I have a remote file.. two possible cases
350 if (file_spec
&& FileSystem::Instance().Exists(file_spec
)) {
351 // if the remote file does not exist, push it there
352 if (!platform_sp
->GetFileExists(remote_file
)) {
353 Status err
= platform_sp
->PutFile(file_spec
, remote_file
);
355 result
.AppendError(err
.AsCString());
360 // there is no local file and we need one
361 // in order to make the remote ---> local transfer we need a
363 // TODO: if the user has passed in a --platform argument, use it
364 // to fetch the right platform
366 // copy the remote file to the local file
367 Status err
= platform_sp
->GetFile(remote_file
, file_spec
);
369 result
.AppendError(err
.AsCString());
373 // If the remote file exists, we can debug reading that out of
374 // memory. If the platform is already connected to an lldb-server
375 // then we can at least check the file exists remotely. Otherwise
376 // we'll just have to trust that it will be there when we do
378 // I don't do this for the host platform because it seems odd to
379 // support supplying a remote file but no local file for a local
381 if (platform_sp
->IsHost()) {
382 result
.AppendError("Supply a local file, not a remote file, "
383 "when debugging on the host.");
386 if (platform_sp
->IsConnected() && !platform_sp
->GetFileExists(remote_file
)) {
387 result
.AppendError("remote --> local transfer without local "
388 "path is not implemented yet");
391 // Since there's only a remote file, we need to set the executable
392 // file spec to the remote one.
393 ProcessLaunchInfo launch_info
= target_sp
->GetProcessLaunchInfo();
394 launch_info
.SetExecutableFile(FileSpec(remote_file
), true);
395 target_sp
->SetProcessLaunchInfo(launch_info
);
399 result
.AppendError("no platform found for target");
404 if (symfile
|| remote_file
) {
405 ModuleSP
module_sp(target_sp
->GetExecutableModule());
408 module_sp
->SetSymbolFileFileSpec(symfile
);
410 std::string remote_path
= remote_file
.GetPath();
411 target_sp
->SetArg0(remote_path
.c_str());
412 module_sp
->SetPlatformFileSpec(remote_file
);
417 if (must_set_platform_path
) {
418 ModuleSpec
main_module_spec(file_spec
);
420 target_sp
->GetOrCreateModule(main_module_spec
, true /* notify */);
422 module_sp
->SetPlatformFileSpec(remote_file
);
426 FileSpec core_file_dir
;
427 core_file_dir
.SetDirectory(core_file
.GetDirectory());
428 target_sp
->AppendExecutableSearchPaths(core_file_dir
);
430 ProcessSP
process_sp(target_sp
->CreateProcess(
431 GetDebugger().GetListener(), llvm::StringRef(), &core_file
, false));
434 // Seems weird that we Launch a core file, but that is what we
436 error
= process_sp
->LoadCore();
440 error
.AsCString("can't find plug-in for core file"));
443 result
.AppendMessageWithFormatv(
444 "Core file '{0}' ({1}) was loaded.\n", core_file
.GetPath(),
445 target_sp
->GetArchitecture().GetArchitectureName());
446 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
450 result
.AppendErrorWithFormatv(
451 "Unable to find process plug-in for core file '{0}'\n",
452 core_file
.GetPath());
455 result
.AppendMessageWithFormat(
456 "Current executable set to '%s' (%s).\n",
457 file_spec
.GetPath().c_str(),
458 target_sp
->GetArchitecture().GetArchitectureName());
459 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
463 result
.AppendErrorWithFormat("'%s' takes exactly one executable path "
464 "argument, or use the --core option.\n",
470 OptionGroupOptions m_option_group
;
471 OptionGroupArchitecture m_arch_option
;
472 OptionGroupPlatform m_platform_options
;
473 OptionGroupFile m_core_file
;
474 OptionGroupString m_label
;
475 OptionGroupFile m_symbol_file
;
476 OptionGroupFile m_remote_file
;
477 OptionGroupDependents m_add_dependents
;
480 #pragma mark CommandObjectTargetList
482 class CommandObjectTargetList
: public CommandObjectParsed
{
484 CommandObjectTargetList(CommandInterpreter
&interpreter
)
485 : CommandObjectParsed(
486 interpreter
, "target list",
487 "List all current targets in the current debug session.", nullptr) {
490 ~CommandObjectTargetList() override
= default;
493 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
494 Stream
&strm
= result
.GetOutputStream();
496 bool show_stopped_process_status
= false;
497 if (DumpTargetList(GetDebugger().GetTargetList(),
498 show_stopped_process_status
, strm
) == 0) {
499 strm
.PutCString("No targets.\n");
501 result
.SetStatus(eReturnStatusSuccessFinishResult
);
505 #pragma mark CommandObjectTargetSelect
507 class CommandObjectTargetSelect
: public CommandObjectParsed
{
509 CommandObjectTargetSelect(CommandInterpreter
&interpreter
)
510 : CommandObjectParsed(
511 interpreter
, "target select",
512 "Select a target as the current target by target index.", nullptr) {
513 CommandArgumentData target_arg
{eArgTypeTargetID
, eArgRepeatPlain
};
514 m_arguments
.push_back({target_arg
});
517 ~CommandObjectTargetSelect() override
= default;
520 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
521 if (args
.GetArgumentCount() == 1) {
522 const char *target_identifier
= args
.GetArgumentAtIndex(0);
523 uint32_t target_idx
= LLDB_INVALID_INDEX32
;
524 TargetList
&target_list
= GetDebugger().GetTargetList();
525 const uint32_t num_targets
= target_list
.GetNumTargets();
526 if (llvm::to_integer(target_identifier
, target_idx
)) {
527 if (target_idx
< num_targets
) {
528 target_list
.SetSelectedTarget(target_idx
);
529 Stream
&strm
= result
.GetOutputStream();
530 bool show_stopped_process_status
= false;
531 DumpTargetList(target_list
, show_stopped_process_status
, strm
);
532 result
.SetStatus(eReturnStatusSuccessFinishResult
);
534 if (num_targets
> 0) {
535 result
.AppendErrorWithFormat(
536 "index %u is out of range, valid target indexes are 0 - %u\n",
537 target_idx
, num_targets
- 1);
539 result
.AppendErrorWithFormat(
540 "index %u is out of range since there are no active targets\n",
545 for (size_t i
= 0; i
< num_targets
; i
++) {
546 if (TargetSP target_sp
= target_list
.GetTargetAtIndex(i
)) {
547 const std::string
&label
= target_sp
->GetLabel();
548 if (!label
.empty() && label
== target_identifier
) {
555 if (target_idx
!= LLDB_INVALID_INDEX32
) {
556 target_list
.SetSelectedTarget(target_idx
);
557 Stream
&strm
= result
.GetOutputStream();
558 bool show_stopped_process_status
= false;
559 DumpTargetList(target_list
, show_stopped_process_status
, strm
);
560 result
.SetStatus(eReturnStatusSuccessFinishResult
);
562 result
.AppendErrorWithFormat("invalid index string value '%s'\n",
568 "'target select' takes a single argument: a target index\n");
573 #pragma mark CommandObjectTargetDelete
575 class CommandObjectTargetDelete
: public CommandObjectParsed
{
577 CommandObjectTargetDelete(CommandInterpreter
&interpreter
)
578 : CommandObjectParsed(interpreter
, "target delete",
579 "Delete one or more targets by target index.",
581 m_all_option(LLDB_OPT_SET_1
, false, "all", 'a', "Delete all targets.",
584 LLDB_OPT_SET_1
, false, "clean", 'c',
585 "Perform extra cleanup to minimize memory consumption after "
586 "deleting the target. "
587 "By default, LLDB will keep in memory any modules previously "
588 "loaded by the target as well "
589 "as all of its debug info. Specifying --clean will unload all of "
590 "these shared modules and "
591 "cause them to be reparsed again the next time the target is run",
593 m_option_group
.Append(&m_all_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
594 m_option_group
.Append(&m_cleanup_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
595 m_option_group
.Finalize();
596 CommandArgumentData target_arg
{eArgTypeTargetID
, eArgRepeatStar
};
597 m_arguments
.push_back({target_arg
});
600 ~CommandObjectTargetDelete() override
= default;
602 Options
*GetOptions() override
{ return &m_option_group
; }
605 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
606 const size_t argc
= args
.GetArgumentCount();
607 std::vector
<TargetSP
> delete_target_list
;
608 TargetList
&target_list
= GetDebugger().GetTargetList();
611 if (m_all_option
.GetOptionValue()) {
612 for (size_t i
= 0; i
< target_list
.GetNumTargets(); ++i
)
613 delete_target_list
.push_back(target_list
.GetTargetAtIndex(i
));
614 } else if (argc
> 0) {
615 const uint32_t num_targets
= target_list
.GetNumTargets();
616 // Bail out if don't have any targets.
617 if (num_targets
== 0) {
618 result
.AppendError("no targets to delete");
622 for (auto &entry
: args
.entries()) {
624 if (entry
.ref().getAsInteger(0, target_idx
)) {
625 result
.AppendErrorWithFormat("invalid target index '%s'\n",
629 if (target_idx
< num_targets
) {
630 target_sp
= target_list
.GetTargetAtIndex(target_idx
);
632 delete_target_list
.push_back(target_sp
);
637 result
.AppendErrorWithFormat("target index %u is out of range, valid "
638 "target indexes are 0 - %u\n",
639 target_idx
, num_targets
- 1);
641 result
.AppendErrorWithFormat(
642 "target index %u is out of range, the only valid index is 0\n",
648 target_sp
= target_list
.GetSelectedTarget();
650 result
.AppendErrorWithFormat("no target is currently selected\n");
653 delete_target_list
.push_back(target_sp
);
656 const size_t num_targets_to_delete
= delete_target_list
.size();
657 for (size_t idx
= 0; idx
< num_targets_to_delete
; ++idx
) {
658 target_sp
= delete_target_list
[idx
];
659 target_list
.DeleteTarget(target_sp
);
660 target_sp
->Destroy();
662 // If "--clean" was specified, prune any orphaned shared modules from the
663 // global shared module list
664 if (m_cleanup_option
.GetOptionValue()) {
665 const bool mandatory
= true;
666 ModuleList::RemoveOrphanSharedModules(mandatory
);
668 result
.GetOutputStream().Printf("%u targets deleted.\n",
669 (uint32_t)num_targets_to_delete
);
670 result
.SetStatus(eReturnStatusSuccessFinishResult
);
675 OptionGroupOptions m_option_group
;
676 OptionGroupBoolean m_all_option
;
677 OptionGroupBoolean m_cleanup_option
;
680 class CommandObjectTargetShowLaunchEnvironment
: public CommandObjectParsed
{
682 CommandObjectTargetShowLaunchEnvironment(CommandInterpreter
&interpreter
)
683 : CommandObjectParsed(
684 interpreter
, "target show-launch-environment",
685 "Shows the environment being passed to the process when launched, "
686 "taking info account 3 settings: target.env-vars, "
687 "target.inherit-env and target.unset-env-vars.",
688 nullptr, eCommandRequiresTarget
) {}
690 ~CommandObjectTargetShowLaunchEnvironment() override
= default;
693 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
694 Target
*target
= m_exe_ctx
.GetTargetPtr();
695 Environment env
= target
->GetEnvironment();
697 std::vector
<Environment::value_type
*> env_vector
;
698 env_vector
.reserve(env
.size());
700 env_vector
.push_back(&KV
);
701 std::sort(env_vector
.begin(), env_vector
.end(),
702 [](Environment::value_type
*a
, Environment::value_type
*b
) {
703 return a
->first() < b
->first();
706 auto &strm
= result
.GetOutputStream();
707 for (auto &KV
: env_vector
)
708 strm
.Format("{0}={1}\n", KV
->first(), KV
->second
);
710 result
.SetStatus(eReturnStatusSuccessFinishResult
);
714 #pragma mark CommandObjectTargetVariable
716 class CommandObjectTargetVariable
: public CommandObjectParsed
{
717 static const uint32_t SHORT_OPTION_FILE
= 0x66696c65; // 'file'
718 static const uint32_t SHORT_OPTION_SHLB
= 0x73686c62; // 'shlb'
721 CommandObjectTargetVariable(CommandInterpreter
&interpreter
)
722 : CommandObjectParsed(interpreter
, "target variable",
723 "Read global variables for the current target, "
724 "before or while running a process.",
725 nullptr, eCommandRequiresTarget
),
726 m_option_variable(false), // Don't include frame options
727 m_option_format(eFormatDefault
),
728 m_option_compile_units(LLDB_OPT_SET_1
, false, "file", SHORT_OPTION_FILE
,
730 "A basename or fullpath to a file that contains "
731 "global variables. This option can be "
732 "specified multiple times."),
733 m_option_shared_libraries(
734 LLDB_OPT_SET_1
, false, "shlib", SHORT_OPTION_SHLB
, 0,
736 "A basename or fullpath to a shared library to use in the search "
738 "variables. This option can be specified multiple times.") {
739 CommandArgumentEntry arg
;
740 CommandArgumentData var_name_arg
;
742 // Define the first (and only) variant of this arg.
743 var_name_arg
.arg_type
= eArgTypeVarName
;
744 var_name_arg
.arg_repetition
= eArgRepeatPlus
;
746 // There is only one variant this argument could be; put it into the
748 arg
.push_back(var_name_arg
);
750 // Push the data for the first argument into the m_arguments vector.
751 m_arguments
.push_back(arg
);
753 m_option_group
.Append(&m_varobj_options
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
754 m_option_group
.Append(&m_option_variable
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
755 m_option_group
.Append(&m_option_format
,
756 OptionGroupFormat::OPTION_GROUP_FORMAT
|
757 OptionGroupFormat::OPTION_GROUP_GDB_FMT
,
759 m_option_group
.Append(&m_option_compile_units
, LLDB_OPT_SET_ALL
,
761 m_option_group
.Append(&m_option_shared_libraries
, LLDB_OPT_SET_ALL
,
763 m_option_group
.Finalize();
766 ~CommandObjectTargetVariable() override
= default;
768 void DumpValueObject(Stream
&s
, VariableSP
&var_sp
, ValueObjectSP
&valobj_sp
,
769 const char *root_name
) {
770 DumpValueObjectOptions
options(m_varobj_options
.GetAsDumpOptions());
772 if (!valobj_sp
->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
773 valobj_sp
->IsRuntimeSupportValue())
776 switch (var_sp
->GetScope()) {
777 case eValueTypeVariableGlobal
:
778 if (m_option_variable
.show_scope
)
779 s
.PutCString("GLOBAL: ");
782 case eValueTypeVariableStatic
:
783 if (m_option_variable
.show_scope
)
784 s
.PutCString("STATIC: ");
787 case eValueTypeVariableArgument
:
788 if (m_option_variable
.show_scope
)
789 s
.PutCString(" ARG: ");
792 case eValueTypeVariableLocal
:
793 if (m_option_variable
.show_scope
)
794 s
.PutCString(" LOCAL: ");
797 case eValueTypeVariableThreadLocal
:
798 if (m_option_variable
.show_scope
)
799 s
.PutCString("THREAD: ");
806 if (m_option_variable
.show_decl
) {
807 bool show_fullpaths
= false;
808 bool show_module
= true;
809 if (var_sp
->DumpDeclaration(&s
, show_fullpaths
, show_module
))
813 const Format format
= m_option_format
.GetFormat();
814 if (format
!= eFormatDefault
)
815 options
.SetFormat(format
);
817 options
.SetRootValueObjectName(root_name
);
819 valobj_sp
->Dump(s
, options
);
822 static size_t GetVariableCallback(void *baton
, const char *name
,
823 VariableList
&variable_list
) {
824 size_t old_size
= variable_list
.GetSize();
825 Target
*target
= static_cast<Target
*>(baton
);
827 target
->GetImages().FindGlobalVariables(ConstString(name
), UINT32_MAX
,
829 return variable_list
.GetSize() - old_size
;
832 Options
*GetOptions() override
{ return &m_option_group
; }
835 void DumpGlobalVariableList(const ExecutionContext
&exe_ctx
,
836 const SymbolContext
&sc
,
837 const VariableList
&variable_list
, Stream
&s
) {
838 if (variable_list
.Empty())
842 s
.Format("Global variables for {0} in {1}:\n",
843 sc
.comp_unit
->GetPrimaryFile(), sc
.module_sp
->GetFileSpec());
845 s
.Printf("Global variables for %s\n",
846 sc
.module_sp
->GetFileSpec().GetPath().c_str());
848 } else if (sc
.comp_unit
) {
849 s
.Format("Global variables for {0}\n", sc
.comp_unit
->GetPrimaryFile());
852 for (VariableSP var_sp
: variable_list
) {
855 ValueObjectSP
valobj_sp(ValueObjectVariable::Create(
856 exe_ctx
.GetBestExecutionContextScope(), var_sp
));
859 DumpValueObject(s
, var_sp
, valobj_sp
, var_sp
->GetName().GetCString());
863 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
864 Target
*target
= m_exe_ctx
.GetTargetPtr();
865 const size_t argc
= args
.GetArgumentCount();
866 Stream
&s
= result
.GetOutputStream();
869 for (const Args::ArgEntry
&arg
: args
) {
870 VariableList variable_list
;
871 ValueObjectList valobj_list
;
874 bool use_var_name
= false;
875 if (m_option_variable
.use_regex
) {
876 RegularExpression
regex(arg
.ref());
877 if (!regex
.IsValid()) {
878 result
.GetErrorStream().Printf(
879 "error: invalid regular expression: '%s'\n", arg
.c_str());
883 target
->GetImages().FindGlobalVariables(regex
, UINT32_MAX
,
885 matches
= variable_list
.GetSize();
887 Status
error(Variable::GetValuesForVariableExpressionPath(
888 arg
.c_str(), m_exe_ctx
.GetBestExecutionContextScope(),
889 GetVariableCallback
, target
, variable_list
, valobj_list
));
890 matches
= variable_list
.GetSize();
894 result
.AppendErrorWithFormat("can't find global variable '%s'",
898 for (uint32_t global_idx
= 0; global_idx
< matches
; ++global_idx
) {
899 VariableSP
var_sp(variable_list
.GetVariableAtIndex(global_idx
));
901 ValueObjectSP
valobj_sp(
902 valobj_list
.GetValueObjectAtIndex(global_idx
));
904 valobj_sp
= ValueObjectVariable::Create(
905 m_exe_ctx
.GetBestExecutionContextScope(), var_sp
);
908 DumpValueObject(s
, var_sp
, valobj_sp
,
909 use_var_name
? var_sp
->GetName().GetCString()
916 const FileSpecList
&compile_units
=
917 m_option_compile_units
.GetOptionValue().GetCurrentValue();
918 const FileSpecList
&shlibs
=
919 m_option_shared_libraries
.GetOptionValue().GetCurrentValue();
920 SymbolContextList sc_list
;
921 const size_t num_compile_units
= compile_units
.GetSize();
922 const size_t num_shlibs
= shlibs
.GetSize();
923 if (num_compile_units
== 0 && num_shlibs
== 0) {
924 bool success
= false;
925 StackFrame
*frame
= m_exe_ctx
.GetFramePtr();
926 CompileUnit
*comp_unit
= nullptr;
928 SymbolContext sc
= frame
->GetSymbolContext(eSymbolContextCompUnit
);
929 comp_unit
= sc
.comp_unit
;
931 const bool can_create
= true;
932 VariableListSP
comp_unit_varlist_sp(
933 sc
.comp_unit
->GetVariableList(can_create
));
934 if (comp_unit_varlist_sp
) {
935 size_t count
= comp_unit_varlist_sp
->GetSize();
937 DumpGlobalVariableList(m_exe_ctx
, sc
, *comp_unit_varlist_sp
, s
);
946 result
.AppendErrorWithFormatv(
947 "no global variables in current compile unit: {0}\n",
948 comp_unit
->GetPrimaryFile());
950 result
.AppendErrorWithFormat(
951 "no debug information for frame %u\n",
952 frame
->GetFrameIndex());
954 result
.AppendError("'target variable' takes one or more global "
955 "variable names as arguments\n");
958 SymbolContextList sc_list
;
959 // We have one or more compile unit or shlib
960 if (num_shlibs
> 0) {
961 for (size_t shlib_idx
= 0; shlib_idx
< num_shlibs
; ++shlib_idx
) {
962 const FileSpec
module_file(shlibs
.GetFileSpecAtIndex(shlib_idx
));
963 ModuleSpec
module_spec(module_file
);
966 target
->GetImages().FindFirstModule(module_spec
));
968 if (num_compile_units
> 0) {
969 for (size_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
)
970 module_sp
->FindCompileUnits(
971 compile_units
.GetFileSpecAtIndex(cu_idx
), sc_list
);
974 sc
.module_sp
= module_sp
;
978 // Didn't find matching shlib/module in target...
979 result
.AppendErrorWithFormat(
980 "target doesn't contain the specified shared library: %s\n",
981 module_file
.GetPath().c_str());
985 // No shared libraries, we just want to find globals for the compile
986 // units files that were specified
987 for (size_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
)
988 target
->GetImages().FindCompileUnits(
989 compile_units
.GetFileSpecAtIndex(cu_idx
), sc_list
);
992 for (const SymbolContext
&sc
: sc_list
) {
994 const bool can_create
= true;
995 VariableListSP
comp_unit_varlist_sp(
996 sc
.comp_unit
->GetVariableList(can_create
));
997 if (comp_unit_varlist_sp
)
998 DumpGlobalVariableList(m_exe_ctx
, sc
, *comp_unit_varlist_sp
, s
);
999 } else if (sc
.module_sp
) {
1000 // Get all global variables for this module
1001 lldb_private::RegularExpression
all_globals_regex(
1002 llvm::StringRef(".")); // Any global with at least one character
1003 VariableList variable_list
;
1004 sc
.module_sp
->FindGlobalVariables(all_globals_regex
, UINT32_MAX
,
1006 DumpGlobalVariableList(m_exe_ctx
, sc
, variable_list
, s
);
1012 m_interpreter
.PrintWarningsIfNecessary(result
.GetOutputStream(),
1016 OptionGroupOptions m_option_group
;
1017 OptionGroupVariable m_option_variable
;
1018 OptionGroupFormat m_option_format
;
1019 OptionGroupFileList m_option_compile_units
;
1020 OptionGroupFileList m_option_shared_libraries
;
1021 OptionGroupValueObjectDisplay m_varobj_options
;
1024 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1026 class CommandObjectTargetModulesSearchPathsAdd
: public CommandObjectParsed
{
1028 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter
&interpreter
)
1029 : CommandObjectParsed(interpreter
, "target modules search-paths add",
1030 "Add new image search paths substitution pairs to "
1031 "the current target.",
1032 nullptr, eCommandRequiresTarget
) {
1033 CommandArgumentEntry arg
;
1034 CommandArgumentData old_prefix_arg
;
1035 CommandArgumentData new_prefix_arg
;
1037 // Define the first variant of this arg pair.
1038 old_prefix_arg
.arg_type
= eArgTypeOldPathPrefix
;
1039 old_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1041 // Define the first variant of this arg pair.
1042 new_prefix_arg
.arg_type
= eArgTypeNewPathPrefix
;
1043 new_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1045 // There are two required arguments that must always occur together, i.e.
1046 // an argument "pair". Because they must always occur together, they are
1047 // treated as two variants of one argument rather than two independent
1048 // arguments. Push them both into the first argument position for
1051 arg
.push_back(old_prefix_arg
);
1052 arg
.push_back(new_prefix_arg
);
1054 m_arguments
.push_back(arg
);
1057 ~CommandObjectTargetModulesSearchPathsAdd() override
= default;
1060 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1061 Target
*target
= &GetSelectedTarget();
1062 const size_t argc
= command
.GetArgumentCount();
1064 result
.AppendError("add requires an even number of arguments\n");
1066 for (size_t i
= 0; i
< argc
; i
+= 2) {
1067 const char *from
= command
.GetArgumentAtIndex(i
);
1068 const char *to
= command
.GetArgumentAtIndex(i
+ 1);
1070 if (from
[0] && to
[0]) {
1071 Log
*log
= GetLog(LLDBLog::Host
);
1074 "target modules search path adding ImageSearchPath "
1075 "pair: '%s' -> '%s'",
1078 bool last_pair
= ((argc
- i
) == 2);
1079 target
->GetImageSearchPathList().Append(
1080 from
, to
, last_pair
); // Notify if this is the last pair
1081 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1084 result
.AppendError("<path-prefix> can't be empty\n");
1086 result
.AppendError("<new-path-prefix> can't be empty\n");
1093 #pragma mark CommandObjectTargetModulesSearchPathsClear
1095 class CommandObjectTargetModulesSearchPathsClear
: public CommandObjectParsed
{
1097 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter
&interpreter
)
1098 : CommandObjectParsed(interpreter
, "target modules search-paths clear",
1099 "Clear all current image search path substitution "
1100 "pairs from the current target.",
1101 "target modules search-paths clear",
1102 eCommandRequiresTarget
) {}
1104 ~CommandObjectTargetModulesSearchPathsClear() override
= default;
1107 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1108 Target
*target
= &GetSelectedTarget();
1110 target
->GetImageSearchPathList().Clear(notify
);
1111 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1115 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1117 class CommandObjectTargetModulesSearchPathsInsert
: public CommandObjectParsed
{
1119 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter
&interpreter
)
1120 : CommandObjectParsed(interpreter
, "target modules search-paths insert",
1121 "Insert a new image search path substitution pair "
1122 "into the current target at the specified index.",
1123 nullptr, eCommandRequiresTarget
) {
1124 CommandArgumentEntry arg1
;
1125 CommandArgumentEntry arg2
;
1126 CommandArgumentData index_arg
;
1127 CommandArgumentData old_prefix_arg
;
1128 CommandArgumentData new_prefix_arg
;
1130 // Define the first and only variant of this arg.
1131 index_arg
.arg_type
= eArgTypeIndex
;
1132 index_arg
.arg_repetition
= eArgRepeatPlain
;
1134 // Put the one and only variant into the first arg for m_arguments:
1135 arg1
.push_back(index_arg
);
1137 // Define the first variant of this arg pair.
1138 old_prefix_arg
.arg_type
= eArgTypeOldPathPrefix
;
1139 old_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1141 // Define the first variant of this arg pair.
1142 new_prefix_arg
.arg_type
= eArgTypeNewPathPrefix
;
1143 new_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1145 // There are two required arguments that must always occur together, i.e.
1146 // an argument "pair". Because they must always occur together, they are
1147 // treated as two variants of one argument rather than two independent
1148 // arguments. Push them both into the same argument position for
1151 arg2
.push_back(old_prefix_arg
);
1152 arg2
.push_back(new_prefix_arg
);
1154 // Add arguments to m_arguments.
1155 m_arguments
.push_back(arg1
);
1156 m_arguments
.push_back(arg2
);
1159 ~CommandObjectTargetModulesSearchPathsInsert() override
= default;
1162 HandleArgumentCompletion(CompletionRequest
&request
,
1163 OptionElementVector
&opt_element_vector
) override
{
1164 if (!m_exe_ctx
.HasTargetScope() || request
.GetCursorIndex() != 0)
1167 Target
*target
= m_exe_ctx
.GetTargetPtr();
1168 const PathMappingList
&list
= target
->GetImageSearchPathList();
1169 const size_t num
= list
.GetSize();
1170 ConstString old_path
, new_path
;
1171 for (size_t i
= 0; i
< num
; ++i
) {
1172 if (!list
.GetPathsAtIndex(i
, old_path
, new_path
))
1175 strm
<< old_path
<< " -> " << new_path
;
1176 request
.TryCompleteCurrentArg(std::to_string(i
), strm
.GetString());
1181 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1182 Target
*target
= &GetSelectedTarget();
1183 size_t argc
= command
.GetArgumentCount();
1184 // check for at least 3 arguments and an odd number of parameters
1185 if (argc
>= 3 && argc
& 1) {
1186 uint32_t insert_idx
;
1188 if (!llvm::to_integer(command
.GetArgumentAtIndex(0), insert_idx
)) {
1189 result
.AppendErrorWithFormat(
1190 "<index> parameter is not an integer: '%s'.\n",
1191 command
.GetArgumentAtIndex(0));
1195 // shift off the index
1197 argc
= command
.GetArgumentCount();
1199 for (uint32_t i
= 0; i
< argc
; i
+= 2, ++insert_idx
) {
1200 const char *from
= command
.GetArgumentAtIndex(i
);
1201 const char *to
= command
.GetArgumentAtIndex(i
+ 1);
1203 if (from
[0] && to
[0]) {
1204 bool last_pair
= ((argc
- i
) == 2);
1205 target
->GetImageSearchPathList().Insert(from
, to
, insert_idx
,
1207 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1210 result
.AppendError("<path-prefix> can't be empty\n");
1212 result
.AppendError("<new-path-prefix> can't be empty\n");
1217 result
.AppendError("insert requires at least three arguments\n");
1222 #pragma mark CommandObjectTargetModulesSearchPathsList
1224 class CommandObjectTargetModulesSearchPathsList
: public CommandObjectParsed
{
1226 CommandObjectTargetModulesSearchPathsList(CommandInterpreter
&interpreter
)
1227 : CommandObjectParsed(interpreter
, "target modules search-paths list",
1228 "List all current image search path substitution "
1229 "pairs in the current target.",
1230 "target modules search-paths list",
1231 eCommandRequiresTarget
) {}
1233 ~CommandObjectTargetModulesSearchPathsList() override
= default;
1236 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1237 Target
*target
= &GetSelectedTarget();
1239 target
->GetImageSearchPathList().Dump(&result
.GetOutputStream());
1240 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1244 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1246 class CommandObjectTargetModulesSearchPathsQuery
: public CommandObjectParsed
{
1248 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter
&interpreter
)
1249 : CommandObjectParsed(
1250 interpreter
, "target modules search-paths query",
1251 "Transform a path using the first applicable image search path.",
1252 nullptr, eCommandRequiresTarget
) {
1253 CommandArgumentEntry arg
;
1254 CommandArgumentData path_arg
;
1256 // Define the first (and only) variant of this arg.
1257 path_arg
.arg_type
= eArgTypeDirectoryName
;
1258 path_arg
.arg_repetition
= eArgRepeatPlain
;
1260 // There is only one variant this argument could be; put it into the
1262 arg
.push_back(path_arg
);
1264 // Push the data for the first argument into the m_arguments vector.
1265 m_arguments
.push_back(arg
);
1268 ~CommandObjectTargetModulesSearchPathsQuery() override
= default;
1271 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1272 Target
*target
= &GetSelectedTarget();
1273 if (command
.GetArgumentCount() != 1) {
1274 result
.AppendError("query requires one argument\n");
1278 ConstString
orig(command
.GetArgumentAtIndex(0));
1279 ConstString transformed
;
1280 if (target
->GetImageSearchPathList().RemapPath(orig
, transformed
))
1281 result
.GetOutputStream().Printf("%s\n", transformed
.GetCString());
1283 result
.GetOutputStream().Printf("%s\n", orig
.GetCString());
1285 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1289 // Static Helper functions
1290 static void DumpModuleArchitecture(Stream
&strm
, Module
*module
,
1291 bool full_triple
, uint32_t width
) {
1293 StreamString arch_strm
;
1296 module
->GetArchitecture().DumpTriple(arch_strm
.AsRawOstream());
1298 arch_strm
.PutCString(module
->GetArchitecture().GetArchitectureName());
1299 std::string arch_str
= std::string(arch_strm
.GetString());
1302 strm
.Printf("%-*s", width
, arch_str
.c_str());
1304 strm
.PutCString(arch_str
);
1308 static void DumpModuleUUID(Stream
&strm
, Module
*module
) {
1309 if (module
&& module
->GetUUID().IsValid())
1310 module
->GetUUID().Dump(strm
);
1312 strm
.PutCString(" ");
1315 static uint32_t DumpCompileUnitLineTable(CommandInterpreter
&interpreter
,
1316 Stream
&strm
, Module
*module
,
1317 const FileSpec
&file_spec
,
1318 lldb::DescriptionLevel desc_level
) {
1319 uint32_t num_matches
= 0;
1321 SymbolContextList sc_list
;
1322 num_matches
= module
->ResolveSymbolContextsForFileSpec(
1323 file_spec
, 0, false, eSymbolContextCompUnit
, sc_list
);
1325 bool first_module
= true;
1326 for (const SymbolContext
&sc
: sc_list
) {
1330 strm
<< "Line table for " << sc
.comp_unit
->GetPrimaryFile() << " in `"
1331 << module
->GetFileSpec().GetFilename() << "\n";
1332 LineTable
*line_table
= sc
.comp_unit
->GetLineTable();
1334 line_table
->GetDescription(
1335 &strm
, interpreter
.GetExecutionContext().GetTargetPtr(),
1338 strm
<< "No line table";
1340 first_module
= false;
1346 static void DumpFullpath(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1348 if (file_spec_ptr
) {
1350 std::string fullpath
= file_spec_ptr
->GetPath();
1351 strm
.Printf("%-*s", width
, fullpath
.c_str());
1354 file_spec_ptr
->Dump(strm
.AsRawOstream());
1358 // Keep the width spacing correct if things go wrong...
1360 strm
.Printf("%-*s", width
, "");
1363 static void DumpDirectory(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1365 if (file_spec_ptr
) {
1367 strm
.Printf("%-*s", width
, file_spec_ptr
->GetDirectory().AsCString(""));
1369 file_spec_ptr
->GetDirectory().Dump(&strm
);
1372 // Keep the width spacing correct if things go wrong...
1374 strm
.Printf("%-*s", width
, "");
1377 static void DumpBasename(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1379 if (file_spec_ptr
) {
1381 strm
.Printf("%-*s", width
, file_spec_ptr
->GetFilename().AsCString(""));
1383 file_spec_ptr
->GetFilename().Dump(&strm
);
1386 // Keep the width spacing correct if things go wrong...
1388 strm
.Printf("%-*s", width
, "");
1391 static size_t DumpModuleObjfileHeaders(Stream
&strm
, ModuleList
&module_list
) {
1392 std::lock_guard
<std::recursive_mutex
> guard(module_list
.GetMutex());
1393 const size_t num_modules
= module_list
.GetSize();
1394 if (num_modules
== 0)
1397 size_t num_dumped
= 0;
1398 strm
.Format("Dumping headers for {0} module(s).\n", num_modules
);
1400 for (ModuleSP module_sp
: module_list
.ModulesNoLocking()) {
1402 if (num_dumped
++ > 0) {
1406 ObjectFile
*objfile
= module_sp
->GetObjectFile();
1408 objfile
->Dump(&strm
);
1410 strm
.Format("No object file for module: {0:F}\n",
1411 module_sp
->GetFileSpec());
1419 static void DumpModuleSymtab(CommandInterpreter
&interpreter
, Stream
&strm
,
1420 Module
*module
, SortOrder sort_order
,
1421 Mangled::NamePreference name_preference
) {
1424 if (Symtab
*symtab
= module
->GetSymtab())
1425 symtab
->Dump(&strm
, interpreter
.GetExecutionContext().GetTargetPtr(),
1426 sort_order
, name_preference
);
1429 static void DumpModuleSections(CommandInterpreter
&interpreter
, Stream
&strm
,
1432 SectionList
*section_list
= module
->GetSectionList();
1434 strm
.Printf("Sections for '%s' (%s):\n",
1435 module
->GetSpecificationDescription().c_str(),
1436 module
->GetArchitecture().GetArchitectureName());
1437 section_list
->Dump(strm
.AsRawOstream(), strm
.GetIndentLevel() + 2,
1438 interpreter
.GetExecutionContext().GetTargetPtr(), true,
1444 static bool DumpModuleSymbolFile(Stream
&strm
, Module
*module
) {
1446 if (SymbolFile
*symbol_file
= module
->GetSymbolFile(true)) {
1447 symbol_file
->Dump(strm
);
1454 static bool GetSeparateDebugInfoList(StructuredData::Array
&list
,
1457 if (SymbolFile
*symbol_file
= module
->GetSymbolFile(/*can_create=*/true)) {
1458 StructuredData::Dictionary d
;
1459 if (symbol_file
->GetSeparateDebugInfo(d
)) {
1461 std::make_shared
<StructuredData::Dictionary
>(std::move(d
)));
1469 static void DumpDwoFilesTable(Stream
&strm
,
1470 StructuredData::Array
&dwo_listings
) {
1471 strm
.PutCString("Dwo ID Err Dwo Path");
1474 "------------------ --- -----------------------------------------");
1476 dwo_listings
.ForEach([&strm
](StructuredData::Object
*dwo
) {
1477 StructuredData::Dictionary
*dict
= dwo
->GetAsDictionary();
1482 if (dict
->GetValueForKeyAsInteger("dwo_id", dwo_id
))
1483 strm
.Printf("0x%16.16" PRIx64
" ", dwo_id
);
1485 strm
.Printf("0x???????????????? ");
1487 llvm::StringRef error
;
1488 if (dict
->GetValueForKeyAsString("error", error
))
1489 strm
<< "E " << error
;
1491 llvm::StringRef resolved_dwo_path
;
1492 if (dict
->GetValueForKeyAsString("resolved_dwo_path",
1493 resolved_dwo_path
)) {
1494 strm
<< " " << resolved_dwo_path
;
1495 if (resolved_dwo_path
.ends_with(".dwp")) {
1496 llvm::StringRef dwo_name
;
1497 if (dict
->GetValueForKeyAsString("dwo_name", dwo_name
))
1498 strm
<< "(" << dwo_name
<< ")";
1507 static void DumpOsoFilesTable(Stream
&strm
,
1508 StructuredData::Array
&oso_listings
) {
1509 strm
.PutCString("Mod Time Err Oso Path");
1511 strm
.PutCString("------------------ --- ---------------------");
1513 oso_listings
.ForEach([&strm
](StructuredData::Object
*oso
) {
1514 StructuredData::Dictionary
*dict
= oso
->GetAsDictionary();
1518 uint32_t oso_mod_time
;
1519 if (dict
->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time
))
1520 strm
.Printf("0x%16.16" PRIx32
" ", oso_mod_time
);
1522 llvm::StringRef error
;
1523 if (dict
->GetValueForKeyAsString("error", error
))
1524 strm
<< "E " << error
;
1526 llvm::StringRef oso_path
;
1527 if (dict
->GetValueForKeyAsString("oso_path", oso_path
))
1528 strm
<< " " << oso_path
;
1535 static void DumpAddress(ExecutionContextScope
*exe_scope
,
1536 const Address
&so_addr
, bool verbose
, bool all_ranges
,
1539 strm
.Indent(" Address: ");
1540 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleModuleWithFileAddress
);
1541 strm
.PutCString(" (");
1542 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleSectionNameOffset
);
1543 strm
.PutCString(")\n");
1544 strm
.Indent(" Summary: ");
1545 const uint32_t save_indent
= strm
.GetIndentLevel();
1546 strm
.SetIndentLevel(save_indent
+ 13);
1547 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleResolvedDescription
);
1548 strm
.SetIndentLevel(save_indent
);
1549 // Print out detailed address information when verbose is enabled
1552 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleDetailedSymbolContext
,
1553 Address::DumpStyleInvalid
, UINT32_MAX
, all_ranges
);
1558 static bool LookupAddressInModule(CommandInterpreter
&interpreter
, Stream
&strm
,
1559 Module
*module
, uint32_t resolve_mask
,
1560 lldb::addr_t raw_addr
, lldb::addr_t offset
,
1561 bool verbose
, bool all_ranges
) {
1563 lldb::addr_t addr
= raw_addr
- offset
;
1566 Target
*target
= interpreter
.GetExecutionContext().GetTargetPtr();
1567 if (target
&& !target
->GetSectionLoadList().IsEmpty()) {
1568 if (!target
->GetSectionLoadList().ResolveLoadAddress(addr
, so_addr
))
1570 else if (so_addr
.GetModule().get() != module
)
1573 if (!module
->ResolveFileAddress(addr
, so_addr
))
1577 ExecutionContextScope
*exe_scope
=
1578 interpreter
.GetExecutionContext().GetBestExecutionContextScope();
1579 DumpAddress(exe_scope
, so_addr
, verbose
, all_ranges
, strm
);
1586 static uint32_t LookupSymbolInModule(CommandInterpreter
&interpreter
,
1587 Stream
&strm
, Module
*module
,
1588 const char *name
, bool name_is_regex
,
1589 bool verbose
, bool all_ranges
) {
1593 Symtab
*symtab
= module
->GetSymtab();
1598 std::vector
<uint32_t> match_indexes
;
1599 ConstString
symbol_name(name
);
1600 uint32_t num_matches
= 0;
1601 if (name_is_regex
) {
1602 RegularExpression
name_regexp(symbol_name
.GetStringRef());
1603 num_matches
= symtab
->AppendSymbolIndexesMatchingRegExAndType(
1604 name_regexp
, eSymbolTypeAny
, match_indexes
);
1607 symtab
->AppendSymbolIndexesWithName(symbol_name
, match_indexes
);
1610 if (num_matches
> 0) {
1612 strm
.Printf("%u symbols match %s'%s' in ", num_matches
,
1613 name_is_regex
? "the regular expression " : "", name
);
1614 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1615 strm
.PutCString(":\n");
1617 for (uint32_t i
= 0; i
< num_matches
; ++i
) {
1618 Symbol
*symbol
= symtab
->SymbolAtIndex(match_indexes
[i
]);
1620 if (symbol
->ValueIsAddress()) {
1622 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1623 symbol
->GetAddressRef(), verbose
, all_ranges
, strm
);
1627 strm
.Indent(" Name: ");
1628 strm
.PutCString(symbol
->GetDisplayName().GetStringRef());
1630 strm
.Indent(" Value: ");
1631 strm
.Printf("0x%16.16" PRIx64
"\n", symbol
->GetRawValue());
1632 if (symbol
->GetByteSizeIsValid()) {
1633 strm
.Indent(" Size: ");
1634 strm
.Printf("0x%16.16" PRIx64
"\n", symbol
->GetByteSize());
1645 static void DumpSymbolContextList(ExecutionContextScope
*exe_scope
,
1647 const SymbolContextList
&sc_list
,
1648 bool verbose
, bool all_ranges
) {
1650 bool first_module
= true;
1651 for (const SymbolContext
&sc
: sc_list
) {
1657 sc
.GetAddressRange(eSymbolContextEverything
, 0, true, range
);
1659 DumpAddress(exe_scope
, range
.GetBaseAddress(), verbose
, all_ranges
, strm
);
1660 first_module
= false;
1665 static size_t LookupFunctionInModule(CommandInterpreter
&interpreter
,
1666 Stream
&strm
, Module
*module
,
1667 const char *name
, bool name_is_regex
,
1668 const ModuleFunctionSearchOptions
&options
,
1669 bool verbose
, bool all_ranges
) {
1670 if (module
&& name
&& name
[0]) {
1671 SymbolContextList sc_list
;
1672 size_t num_matches
= 0;
1673 if (name_is_regex
) {
1674 RegularExpression
function_name_regex((llvm::StringRef(name
)));
1675 module
->FindFunctions(function_name_regex
, options
, sc_list
);
1677 ConstString
function_name(name
);
1678 module
->FindFunctions(function_name
, CompilerDeclContext(),
1679 eFunctionNameTypeAuto
, options
, sc_list
);
1681 num_matches
= sc_list
.GetSize();
1684 strm
.Printf("%" PRIu64
" match%s found in ", (uint64_t)num_matches
,
1685 num_matches
> 1 ? "es" : "");
1686 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1687 strm
.PutCString(":\n");
1688 DumpSymbolContextList(
1689 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1690 strm
, sc_list
, verbose
, all_ranges
);
1697 static size_t LookupTypeInModule(Target
*target
,
1698 CommandInterpreter
&interpreter
, Stream
&strm
,
1699 Module
*module
, const char *name_cstr
,
1700 bool name_is_regex
) {
1702 if (module
&& name_cstr
&& name_cstr
[0]) {
1703 const uint32_t max_num_matches
= UINT32_MAX
;
1704 bool name_is_fully_qualified
= false;
1706 ConstString
name(name_cstr
);
1707 llvm::DenseSet
<lldb_private::SymbolFile
*> searched_symbol_files
;
1708 module
->FindTypes(name
, name_is_fully_qualified
, max_num_matches
,
1709 searched_symbol_files
, type_list
);
1711 if (type_list
.Empty())
1714 const uint64_t num_matches
= type_list
.GetSize();
1717 strm
.Printf("%" PRIu64
" match%s found in ", num_matches
,
1718 num_matches
> 1 ? "es" : "");
1719 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1720 strm
.PutCString(":\n");
1721 for (TypeSP type_sp
: type_list
.Types()) {
1724 // Resolve the clang type so that any forward references to types
1725 // that haven't yet been parsed will get parsed.
1726 type_sp
->GetFullCompilerType();
1727 type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true, target
);
1728 // Print all typedef chains
1729 TypeSP
typedef_type_sp(type_sp
);
1730 TypeSP
typedefed_type_sp(typedef_type_sp
->GetTypedefType());
1731 while (typedefed_type_sp
) {
1733 strm
.Printf(" typedef '%s': ",
1734 typedef_type_sp
->GetName().GetCString());
1735 typedefed_type_sp
->GetFullCompilerType();
1736 typedefed_type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true,
1738 typedef_type_sp
= typedefed_type_sp
;
1739 typedefed_type_sp
= typedef_type_sp
->GetTypedefType();
1744 return type_list
.GetSize();
1747 static size_t LookupTypeHere(Target
*target
, CommandInterpreter
&interpreter
,
1748 Stream
&strm
, Module
&module
,
1749 const char *name_cstr
, bool name_is_regex
) {
1751 const uint32_t max_num_matches
= UINT32_MAX
;
1752 bool name_is_fully_qualified
= false;
1754 ConstString
name(name_cstr
);
1755 llvm::DenseSet
<SymbolFile
*> searched_symbol_files
;
1756 module
.FindTypes(name
, name_is_fully_qualified
, max_num_matches
,
1757 searched_symbol_files
, type_list
);
1759 if (type_list
.Empty())
1763 strm
.PutCString("Best match found in ");
1764 DumpFullpath(strm
, &module
.GetFileSpec(), 0);
1765 strm
.PutCString(":\n");
1767 TypeSP
type_sp(type_list
.GetTypeAtIndex(0));
1769 // Resolve the clang type so that any forward references to types that
1770 // haven't yet been parsed will get parsed.
1771 type_sp
->GetFullCompilerType();
1772 type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true, target
);
1773 // Print all typedef chains.
1774 TypeSP
typedef_type_sp(type_sp
);
1775 TypeSP
typedefed_type_sp(typedef_type_sp
->GetTypedefType());
1776 while (typedefed_type_sp
) {
1778 strm
.Printf(" typedef '%s': ",
1779 typedef_type_sp
->GetName().GetCString());
1780 typedefed_type_sp
->GetFullCompilerType();
1781 typedefed_type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true,
1783 typedef_type_sp
= typedefed_type_sp
;
1784 typedefed_type_sp
= typedef_type_sp
->GetTypedefType();
1788 return type_list
.GetSize();
1791 static uint32_t LookupFileAndLineInModule(CommandInterpreter
&interpreter
,
1792 Stream
&strm
, Module
*module
,
1793 const FileSpec
&file_spec
,
1794 uint32_t line
, bool check_inlines
,
1795 bool verbose
, bool all_ranges
) {
1796 if (module
&& file_spec
) {
1797 SymbolContextList sc_list
;
1798 const uint32_t num_matches
= module
->ResolveSymbolContextsForFileSpec(
1799 file_spec
, line
, check_inlines
, eSymbolContextEverything
, sc_list
);
1800 if (num_matches
> 0) {
1802 strm
.Printf("%u match%s found in ", num_matches
,
1803 num_matches
> 1 ? "es" : "");
1806 strm
.Printf(":%u", line
);
1808 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1809 strm
.PutCString(":\n");
1810 DumpSymbolContextList(
1811 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1812 strm
, sc_list
, verbose
, all_ranges
);
1819 static size_t FindModulesByName(Target
*target
, const char *module_name
,
1820 ModuleList
&module_list
,
1821 bool check_global_list
) {
1822 FileSpec
module_file_spec(module_name
);
1823 ModuleSpec
module_spec(module_file_spec
);
1825 const size_t initial_size
= module_list
.GetSize();
1827 if (check_global_list
) {
1828 // Check the global list
1829 std::lock_guard
<std::recursive_mutex
> guard(
1830 Module::GetAllocationModuleCollectionMutex());
1831 const size_t num_modules
= Module::GetNumberAllocatedModules();
1833 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
1834 Module
*module
= Module::GetAllocatedModuleAtIndex(image_idx
);
1837 if (module
->MatchesModuleSpec(module_spec
)) {
1838 module_sp
= module
->shared_from_this();
1839 module_list
.AppendIfNeeded(module_sp
);
1845 target
->GetImages().FindModules(module_spec
, module_list
);
1846 const size_t num_matches
= module_list
.GetSize();
1848 // Not found in our module list for our target, check the main shared
1849 // module list in case it is a extra file used somewhere else
1850 if (num_matches
== 0) {
1851 module_spec
.GetArchitecture() = target
->GetArchitecture();
1852 ModuleList::FindSharedModules(module_spec
, module_list
);
1855 ModuleList::FindSharedModules(module_spec
, module_list
);
1859 return module_list
.GetSize() - initial_size
;
1862 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1864 // A base command object class that can auto complete with module file
1867 class CommandObjectTargetModulesModuleAutoComplete
1868 : public CommandObjectParsed
{
1870 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter
&interpreter
,
1875 : CommandObjectParsed(interpreter
, name
, help
, syntax
, flags
) {
1876 CommandArgumentEntry arg
;
1877 CommandArgumentData file_arg
;
1879 // Define the first (and only) variant of this arg.
1880 file_arg
.arg_type
= eArgTypeFilename
;
1881 file_arg
.arg_repetition
= eArgRepeatStar
;
1883 // There is only one variant this argument could be; put it into the
1885 arg
.push_back(file_arg
);
1887 // Push the data for the first argument into the m_arguments vector.
1888 m_arguments
.push_back(arg
);
1891 ~CommandObjectTargetModulesModuleAutoComplete() override
= default;
1894 HandleArgumentCompletion(CompletionRequest
&request
,
1895 OptionElementVector
&opt_element_vector
) override
{
1896 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1897 GetCommandInterpreter(), lldb::eModuleCompletion
, request
, nullptr);
1901 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1903 // A base command object class that can auto complete with module source
1906 class CommandObjectTargetModulesSourceFileAutoComplete
1907 : public CommandObjectParsed
{
1909 CommandObjectTargetModulesSourceFileAutoComplete(
1910 CommandInterpreter
&interpreter
, const char *name
, const char *help
,
1911 const char *syntax
, uint32_t flags
)
1912 : CommandObjectParsed(interpreter
, name
, help
, syntax
, flags
) {
1913 CommandArgumentEntry arg
;
1914 CommandArgumentData source_file_arg
;
1916 // Define the first (and only) variant of this arg.
1917 source_file_arg
.arg_type
= eArgTypeSourceFile
;
1918 source_file_arg
.arg_repetition
= eArgRepeatPlus
;
1920 // There is only one variant this argument could be; put it into the
1922 arg
.push_back(source_file_arg
);
1924 // Push the data for the first argument into the m_arguments vector.
1925 m_arguments
.push_back(arg
);
1928 ~CommandObjectTargetModulesSourceFileAutoComplete() override
= default;
1931 HandleArgumentCompletion(CompletionRequest
&request
,
1932 OptionElementVector
&opt_element_vector
) override
{
1933 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1934 GetCommandInterpreter(), lldb::eSourceFileCompletion
, request
, nullptr);
1938 #pragma mark CommandObjectTargetModulesDumpObjfile
1940 class CommandObjectTargetModulesDumpObjfile
1941 : public CommandObjectTargetModulesModuleAutoComplete
{
1943 CommandObjectTargetModulesDumpObjfile(CommandInterpreter
&interpreter
)
1944 : CommandObjectTargetModulesModuleAutoComplete(
1945 interpreter
, "target modules dump objfile",
1946 "Dump the object file headers from one or more target modules.",
1947 nullptr, eCommandRequiresTarget
) {}
1949 ~CommandObjectTargetModulesDumpObjfile() override
= default;
1952 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1953 Target
*target
= &GetSelectedTarget();
1955 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
1956 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
1957 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
1959 size_t num_dumped
= 0;
1960 if (command
.GetArgumentCount() == 0) {
1961 // Dump all headers for all modules images
1962 num_dumped
= DumpModuleObjfileHeaders(result
.GetOutputStream(),
1963 target
->GetImages());
1964 if (num_dumped
== 0) {
1965 result
.AppendError("the target has no associated executable images");
1968 // Find the modules that match the basename or full path.
1969 ModuleList module_list
;
1970 const char *arg_cstr
;
1971 for (int arg_idx
= 0;
1972 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
1974 size_t num_matched
=
1975 FindModulesByName(target
, arg_cstr
, module_list
, true);
1976 if (num_matched
== 0) {
1977 result
.AppendWarningWithFormat(
1978 "Unable to find an image that matches '%s'.\n", arg_cstr
);
1981 // Dump all the modules we found.
1983 DumpModuleObjfileHeaders(result
.GetOutputStream(), module_list
);
1986 if (num_dumped
> 0) {
1987 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1989 result
.AppendError("no matching executable images found");
1994 #define LLDB_OPTIONS_target_modules_dump_symtab
1995 #include "CommandOptions.inc"
1997 class CommandObjectTargetModulesDumpSymtab
1998 : public CommandObjectTargetModulesModuleAutoComplete
{
2000 CommandObjectTargetModulesDumpSymtab(CommandInterpreter
&interpreter
)
2001 : CommandObjectTargetModulesModuleAutoComplete(
2002 interpreter
, "target modules dump symtab",
2003 "Dump the symbol table from one or more target modules.", nullptr,
2004 eCommandRequiresTarget
) {}
2006 ~CommandObjectTargetModulesDumpSymtab() override
= default;
2008 Options
*GetOptions() override
{ return &m_options
; }
2010 class CommandOptions
: public Options
{
2012 CommandOptions() = default;
2014 ~CommandOptions() override
= default;
2016 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2017 ExecutionContext
*execution_context
) override
{
2019 const int short_option
= m_getopt_table
[option_idx
].val
;
2021 switch (short_option
) {
2023 m_prefer_mangled
.SetCurrentValue(true);
2024 m_prefer_mangled
.SetOptionWasSet();
2028 m_sort_order
= (SortOrder
)OptionArgParser::ToOptionEnum(
2029 option_arg
, GetDefinitions()[option_idx
].enum_values
,
2030 eSortOrderNone
, error
);
2034 llvm_unreachable("Unimplemented option");
2039 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2040 m_sort_order
= eSortOrderNone
;
2041 m_prefer_mangled
.Clear();
2044 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2045 return llvm::ArrayRef(g_target_modules_dump_symtab_options
);
2048 SortOrder m_sort_order
= eSortOrderNone
;
2049 OptionValueBoolean m_prefer_mangled
= {false, false};
2053 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2054 Target
*target
= &GetSelectedTarget();
2055 uint32_t num_dumped
= 0;
2056 Mangled::NamePreference name_preference
=
2057 (m_options
.m_prefer_mangled
? Mangled::ePreferMangled
2058 : Mangled::ePreferDemangled
);
2060 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2061 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2062 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2064 if (command
.GetArgumentCount() == 0) {
2065 // Dump all sections for all modules images
2066 const ModuleList
&module_list
= target
->GetImages();
2067 std::lock_guard
<std::recursive_mutex
> guard(module_list
.GetMutex());
2068 const size_t num_modules
= module_list
.GetSize();
2069 if (num_modules
> 0) {
2070 result
.GetOutputStream().Format(
2071 "Dumping symbol table for {0} modules.\n", num_modules
);
2072 for (ModuleSP module_sp
: module_list
.ModulesNoLocking()) {
2073 if (num_dumped
> 0) {
2074 result
.GetOutputStream().EOL();
2075 result
.GetOutputStream().EOL();
2077 if (INTERRUPT_REQUESTED(GetDebugger(),
2078 "Interrupted in dump all symtabs with {0} "
2079 "of {1} dumped.", num_dumped
, num_modules
))
2083 DumpModuleSymtab(m_interpreter
, result
.GetOutputStream(),
2084 module_sp
.get(), m_options
.m_sort_order
,
2088 result
.AppendError("the target has no associated executable images");
2092 // Dump specified images (by basename or fullpath)
2093 const char *arg_cstr
;
2094 for (int arg_idx
= 0;
2095 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2097 ModuleList module_list
;
2098 const size_t num_matches
=
2099 FindModulesByName(target
, arg_cstr
, module_list
, true);
2100 if (num_matches
> 0) {
2101 for (ModuleSP module_sp
: module_list
.Modules()) {
2103 if (num_dumped
> 0) {
2104 result
.GetOutputStream().EOL();
2105 result
.GetOutputStream().EOL();
2107 if (INTERRUPT_REQUESTED(GetDebugger(),
2108 "Interrupted in dump symtab list with {0} of {1} dumped.",
2109 num_dumped
, num_matches
))
2113 DumpModuleSymtab(m_interpreter
, result
.GetOutputStream(),
2114 module_sp
.get(), m_options
.m_sort_order
,
2119 result
.AppendWarningWithFormat(
2120 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2125 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2127 result
.AppendError("no matching executable images found");
2131 CommandOptions m_options
;
2134 #pragma mark CommandObjectTargetModulesDumpSections
2136 // Image section dumping command
2138 class CommandObjectTargetModulesDumpSections
2139 : public CommandObjectTargetModulesModuleAutoComplete
{
2141 CommandObjectTargetModulesDumpSections(CommandInterpreter
&interpreter
)
2142 : CommandObjectTargetModulesModuleAutoComplete(
2143 interpreter
, "target modules dump sections",
2144 "Dump the sections from one or more target modules.",
2145 //"target modules dump sections [<file1> ...]")
2146 nullptr, eCommandRequiresTarget
) {}
2148 ~CommandObjectTargetModulesDumpSections() override
= default;
2151 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2152 Target
*target
= &GetSelectedTarget();
2153 uint32_t num_dumped
= 0;
2155 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2156 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2157 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2159 if (command
.GetArgumentCount() == 0) {
2160 // Dump all sections for all modules images
2161 const size_t num_modules
= target
->GetImages().GetSize();
2162 if (num_modules
== 0) {
2163 result
.AppendError("the target has no associated executable images");
2167 result
.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2169 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
2170 if (INTERRUPT_REQUESTED(GetDebugger(),
2171 "Interrupted in dump all sections with {0} of {1} dumped",
2172 image_idx
, num_modules
))
2177 m_interpreter
, result
.GetOutputStream(),
2178 target
->GetImages().GetModulePointerAtIndex(image_idx
));
2181 // Dump specified images (by basename or fullpath)
2182 const char *arg_cstr
;
2183 for (int arg_idx
= 0;
2184 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2186 ModuleList module_list
;
2187 const size_t num_matches
=
2188 FindModulesByName(target
, arg_cstr
, module_list
, true);
2189 if (num_matches
> 0) {
2190 for (size_t i
= 0; i
< num_matches
; ++i
) {
2191 if (INTERRUPT_REQUESTED(GetDebugger(),
2192 "Interrupted in dump section list with {0} of {1} dumped.",
2196 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2199 DumpModuleSections(m_interpreter
, result
.GetOutputStream(),
2204 // Check the global list
2205 std::lock_guard
<std::recursive_mutex
> guard(
2206 Module::GetAllocationModuleCollectionMutex());
2208 result
.AppendWarningWithFormat(
2209 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2215 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2217 result
.AppendError("no matching executable images found");
2222 class CommandObjectTargetModulesDumpClangPCMInfo
: public CommandObjectParsed
{
2224 CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter
&interpreter
)
2225 : CommandObjectParsed(
2226 interpreter
, "target modules dump pcm-info",
2227 "Dump information about the given clang module (pcm).") {
2228 // Take a single file argument.
2229 CommandArgumentData arg
{eArgTypeFilename
, eArgRepeatPlain
};
2230 m_arguments
.push_back({arg
});
2233 ~CommandObjectTargetModulesDumpClangPCMInfo() override
= default;
2236 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2237 if (command
.GetArgumentCount() != 1) {
2238 result
.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",
2239 m_cmd_name
.c_str());
2243 const char *pcm_path
= command
.GetArgumentAtIndex(0);
2244 const FileSpec pcm_file
{pcm_path
};
2246 if (pcm_file
.GetFileNameExtension() != ".pcm") {
2247 result
.AppendError("file must have a .pcm extension");
2251 if (!FileSystem::Instance().Exists(pcm_file
)) {
2252 result
.AppendError("pcm file does not exist");
2256 clang::CompilerInstance compiler
;
2257 compiler
.createDiagnostics();
2259 const char *clang_args
[] = {"clang", pcm_path
};
2260 compiler
.setInvocation(clang::createInvocation(clang_args
));
2262 // Pass empty deleter to not attempt to free memory that was allocated
2263 // outside of the current scope, possibly statically.
2264 std::shared_ptr
<llvm::raw_ostream
> Out(
2265 &result
.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream
*) {});
2266 clang::DumpModuleInfoAction
dump_module_info(Out
);
2267 // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2268 compiler
.getPCHContainerOperations()->registerReader(
2269 std::make_unique
<clang::ObjectFilePCHContainerReader
>());
2271 if (compiler
.ExecuteAction(dump_module_info
))
2272 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2276 #pragma mark CommandObjectTargetModulesDumpClangAST
2278 // Clang AST dumping command
2280 class CommandObjectTargetModulesDumpClangAST
2281 : public CommandObjectTargetModulesModuleAutoComplete
{
2283 CommandObjectTargetModulesDumpClangAST(CommandInterpreter
&interpreter
)
2284 : CommandObjectTargetModulesModuleAutoComplete(
2285 interpreter
, "target modules dump ast",
2286 "Dump the clang ast for a given module's symbol file.",
2287 //"target modules dump ast [<file1> ...]")
2288 nullptr, eCommandRequiresTarget
) {}
2290 ~CommandObjectTargetModulesDumpClangAST() override
= default;
2293 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2294 Target
*target
= &GetSelectedTarget();
2296 const ModuleList
&module_list
= target
->GetImages();
2297 const size_t num_modules
= module_list
.GetSize();
2298 if (num_modules
== 0) {
2299 result
.AppendError("the target has no associated executable images");
2303 if (command
.GetArgumentCount() == 0) {
2304 // Dump all ASTs for all modules images
2305 result
.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2307 for (ModuleSP module_sp
: module_list
.ModulesNoLocking()) {
2308 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
2310 if (SymbolFile
*sf
= module_sp
->GetSymbolFile())
2311 sf
->DumpClangAST(result
.GetOutputStream());
2313 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2317 // Dump specified ASTs (by basename or fullpath)
2318 for (const Args::ArgEntry
&arg
: command
.entries()) {
2319 ModuleList module_list
;
2320 const size_t num_matches
=
2321 FindModulesByName(target
, arg
.c_str(), module_list
, true);
2322 if (num_matches
== 0) {
2323 // Check the global list
2324 std::lock_guard
<std::recursive_mutex
> guard(
2325 Module::GetAllocationModuleCollectionMutex());
2327 result
.AppendWarningWithFormat(
2328 "Unable to find an image that matches '%s'.\n", arg
.c_str());
2332 for (size_t i
= 0; i
< num_matches
; ++i
) {
2333 if (INTERRUPT_REQUESTED(GetDebugger(),
2334 "Interrupted in dump clang ast list with {0} of {1} dumped.",
2338 Module
*m
= module_list
.GetModulePointerAtIndex(i
);
2339 if (SymbolFile
*sf
= m
->GetSymbolFile())
2340 sf
->DumpClangAST(result
.GetOutputStream());
2343 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2347 #pragma mark CommandObjectTargetModulesDumpSymfile
2349 // Image debug symbol dumping command
2351 class CommandObjectTargetModulesDumpSymfile
2352 : public CommandObjectTargetModulesModuleAutoComplete
{
2354 CommandObjectTargetModulesDumpSymfile(CommandInterpreter
&interpreter
)
2355 : CommandObjectTargetModulesModuleAutoComplete(
2356 interpreter
, "target modules dump symfile",
2357 "Dump the debug symbol file for one or more target modules.",
2358 //"target modules dump symfile [<file1> ...]")
2359 nullptr, eCommandRequiresTarget
) {}
2361 ~CommandObjectTargetModulesDumpSymfile() override
= default;
2364 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2365 Target
*target
= &GetSelectedTarget();
2366 uint32_t num_dumped
= 0;
2368 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2369 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2370 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2372 if (command
.GetArgumentCount() == 0) {
2373 // Dump all sections for all modules images
2374 const ModuleList
&target_modules
= target
->GetImages();
2375 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2376 const size_t num_modules
= target_modules
.GetSize();
2377 if (num_modules
== 0) {
2378 result
.AppendError("the target has no associated executable images");
2381 result
.GetOutputStream().Format(
2382 "Dumping debug symbols for {0} modules.\n", num_modules
);
2383 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
2384 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2385 "debug symbols with {0} of {1} modules dumped",
2386 num_dumped
, num_modules
))
2389 if (DumpModuleSymbolFile(result
.GetOutputStream(), module_sp
.get()))
2393 // Dump specified images (by basename or fullpath)
2394 const char *arg_cstr
;
2395 for (int arg_idx
= 0;
2396 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2398 ModuleList module_list
;
2399 const size_t num_matches
=
2400 FindModulesByName(target
, arg_cstr
, module_list
, true);
2401 if (num_matches
> 0) {
2402 for (size_t i
= 0; i
< num_matches
; ++i
) {
2403 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2404 "of {1} requested modules",
2407 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2409 if (DumpModuleSymbolFile(result
.GetOutputStream(), module
))
2414 result
.AppendWarningWithFormat(
2415 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2420 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2422 result
.AppendError("no matching executable images found");
2427 #pragma mark CommandObjectTargetModulesDumpLineTable
2428 #define LLDB_OPTIONS_target_modules_dump
2429 #include "CommandOptions.inc"
2431 // Image debug line table dumping command
2433 class CommandObjectTargetModulesDumpLineTable
2434 : public CommandObjectTargetModulesSourceFileAutoComplete
{
2436 CommandObjectTargetModulesDumpLineTable(CommandInterpreter
&interpreter
)
2437 : CommandObjectTargetModulesSourceFileAutoComplete(
2438 interpreter
, "target modules dump line-table",
2439 "Dump the line table for one or more compilation units.", nullptr,
2440 eCommandRequiresTarget
) {}
2442 ~CommandObjectTargetModulesDumpLineTable() override
= default;
2444 Options
*GetOptions() override
{ return &m_options
; }
2447 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2448 Target
*target
= m_exe_ctx
.GetTargetPtr();
2449 uint32_t total_num_dumped
= 0;
2451 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2452 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2453 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2455 if (command
.GetArgumentCount() == 0) {
2456 result
.AppendError("file option must be specified.");
2459 // Dump specified images (by basename or fullpath)
2460 const char *arg_cstr
;
2461 for (int arg_idx
= 0;
2462 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2464 FileSpec
file_spec(arg_cstr
);
2466 const ModuleList
&target_modules
= target
->GetImages();
2467 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2468 size_t num_modules
= target_modules
.GetSize();
2469 if (num_modules
> 0) {
2470 uint32_t num_dumped
= 0;
2471 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
2472 if (INTERRUPT_REQUESTED(GetDebugger(),
2473 "Interrupted in dump all line tables with "
2474 "{0} of {1} dumped", num_dumped
,
2478 if (DumpCompileUnitLineTable(
2479 m_interpreter
, result
.GetOutputStream(), module_sp
.get(),
2481 m_options
.m_verbose
? eDescriptionLevelFull
2482 : eDescriptionLevelBrief
))
2485 if (num_dumped
== 0)
2486 result
.AppendWarningWithFormat(
2487 "No source filenames matched '%s'.\n", arg_cstr
);
2489 total_num_dumped
+= num_dumped
;
2494 if (total_num_dumped
> 0)
2495 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2497 result
.AppendError("no source filenames matched any command arguments");
2501 class CommandOptions
: public Options
{
2503 CommandOptions() { OptionParsingStarting(nullptr); }
2505 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2506 ExecutionContext
*execution_context
) override
{
2507 assert(option_idx
== 0 && "We only have one option.");
2513 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2517 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2518 return llvm::ArrayRef(g_target_modules_dump_options
);
2524 CommandOptions m_options
;
2527 #pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2528 #define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2529 #include "CommandOptions.inc"
2531 // Image debug separate debug info dumping command
2533 class CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2534 : public CommandObjectTargetModulesModuleAutoComplete
{
2536 CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2537 CommandInterpreter
&interpreter
)
2538 : CommandObjectTargetModulesModuleAutoComplete(
2539 interpreter
, "target modules dump separate-debug-info",
2540 "List the separate debug info symbol files for one or more target "
2542 nullptr, eCommandRequiresTarget
) {}
2544 ~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override
= default;
2546 Options
*GetOptions() override
{ return &m_options
; }
2548 class CommandOptions
: public Options
{
2550 CommandOptions() = default;
2552 ~CommandOptions() override
= default;
2554 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2555 ExecutionContext
*execution_context
) override
{
2557 const int short_option
= m_getopt_table
[option_idx
].val
;
2559 switch (short_option
) {
2561 m_json
.SetCurrentValue(true);
2562 m_json
.SetOptionWasSet();
2566 llvm_unreachable("Unimplemented option");
2571 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2575 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2576 return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options
);
2579 OptionValueBoolean m_json
= false;
2583 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2584 Target
&target
= GetSelectedTarget();
2585 uint32_t num_dumped
= 0;
2587 uint32_t addr_byte_size
= target
.GetArchitecture().GetAddressByteSize();
2588 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2589 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2591 StructuredData::Array separate_debug_info_lists_by_module
;
2592 if (command
.GetArgumentCount() == 0) {
2593 // Dump all sections for all modules images
2594 const ModuleList
&target_modules
= target
.GetImages();
2595 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2596 const size_t num_modules
= target_modules
.GetSize();
2597 if (num_modules
== 0) {
2598 result
.AppendError("the target has no associated executable images");
2601 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
2602 if (INTERRUPT_REQUESTED(
2604 "Interrupted in dumping all "
2605 "separate debug info with {0} of {1} modules dumped",
2606 num_dumped
, num_modules
))
2609 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module
,
2614 // Dump specified images (by basename or fullpath)
2615 const char *arg_cstr
;
2616 for (int arg_idx
= 0;
2617 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2619 ModuleList module_list
;
2620 const size_t num_matches
=
2621 FindModulesByName(&target
, arg_cstr
, module_list
, true);
2622 if (num_matches
> 0) {
2623 for (size_t i
= 0; i
< num_matches
; ++i
) {
2624 if (INTERRUPT_REQUESTED(GetDebugger(),
2625 "Interrupted dumping {0} "
2626 "of {1} requested modules",
2629 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2630 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module
,
2635 result
.AppendWarningWithFormat(
2636 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2640 if (num_dumped
> 0) {
2641 Stream
&strm
= result
.GetOutputStream();
2642 if (m_options
.m_json
) {
2643 separate_debug_info_lists_by_module
.Dump(strm
,
2644 /*pretty_print=*/true);
2646 // List the debug info files in human readable form.
2647 separate_debug_info_lists_by_module
.ForEach(
2648 [&result
, &strm
](StructuredData::Object
*obj
) {
2653 // Each item in `separate_debug_info_lists_by_module` should be a
2654 // valid structured data dictionary.
2655 StructuredData::Dictionary
*separate_debug_info_list
=
2656 obj
->GetAsDictionary();
2657 if (!separate_debug_info_list
) {
2661 llvm::StringRef type
;
2662 llvm::StringRef symfile
;
2663 StructuredData::Array
*files
;
2664 if (!(separate_debug_info_list
->GetValueForKeyAsString("type",
2666 separate_debug_info_list
->GetValueForKeyAsString("symfile",
2668 separate_debug_info_list
->GetValueForKeyAsArray(
2669 "separate-debug-info-files", files
))) {
2673 strm
<< "Symbol file: " << symfile
;
2675 strm
<< "Type: \"" << type
<< "\"";
2677 if (type
== "dwo") {
2678 DumpDwoFilesTable(strm
, *files
);
2679 } else if (type
== "oso") {
2680 DumpOsoFilesTable(strm
, *files
);
2682 result
.AppendWarningWithFormat(
2683 "Found unsupported debug info type '%s'.\n",
2684 type
.str().c_str());
2689 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2691 result
.AppendError("no matching executable images found");
2695 CommandOptions m_options
;
2698 #pragma mark CommandObjectTargetModulesDump
2700 // Dump multi-word command for target modules
2702 class CommandObjectTargetModulesDump
: public CommandObjectMultiword
{
2704 // Constructors and Destructors
2705 CommandObjectTargetModulesDump(CommandInterpreter
&interpreter
)
2706 : CommandObjectMultiword(
2707 interpreter
, "target modules dump",
2708 "Commands for dumping information about one or more target "
2710 "target modules dump "
2711 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2713 "[<file1> <file2> ...]") {
2714 LoadSubCommand("objfile",
2716 new CommandObjectTargetModulesDumpObjfile(interpreter
)));
2719 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter
)));
2720 LoadSubCommand("sections",
2721 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2723 LoadSubCommand("symfile",
2725 new CommandObjectTargetModulesDumpSymfile(interpreter
)));
2727 "ast", CommandObjectSP(
2728 new CommandObjectTargetModulesDumpClangAST(interpreter
)));
2729 LoadSubCommand("line-table",
2730 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2735 new CommandObjectTargetModulesDumpClangPCMInfo(interpreter
)));
2736 LoadSubCommand("separate-debug-info",
2738 new CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2742 ~CommandObjectTargetModulesDump() override
= default;
2745 class CommandObjectTargetModulesAdd
: public CommandObjectParsed
{
2747 CommandObjectTargetModulesAdd(CommandInterpreter
&interpreter
)
2748 : CommandObjectParsed(interpreter
, "target modules add",
2749 "Add a new module to the current target's modules.",
2750 "target modules add [<module>]",
2751 eCommandRequiresTarget
),
2752 m_symbol_file(LLDB_OPT_SET_1
, false, "symfile", 's', 0,
2754 "Fullpath to a stand alone debug "
2755 "symbols file for when debug symbols "
2756 "are not in the executable.") {
2757 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
2759 m_option_group
.Append(&m_symbol_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2760 m_option_group
.Finalize();
2761 CommandArgumentData module_arg
{eArgTypePath
, eArgRepeatStar
};
2762 m_arguments
.push_back({module_arg
});
2765 ~CommandObjectTargetModulesAdd() override
= default;
2767 Options
*GetOptions() override
{ return &m_option_group
; }
2770 HandleArgumentCompletion(CompletionRequest
&request
,
2771 OptionElementVector
&opt_element_vector
) override
{
2772 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
2773 GetCommandInterpreter(), lldb::eDiskFileCompletion
, request
, nullptr);
2777 OptionGroupOptions m_option_group
;
2778 OptionGroupUUID m_uuid_option_group
;
2779 OptionGroupFile m_symbol_file
;
2781 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
2782 Target
*target
= &GetSelectedTarget();
2785 const size_t argc
= args
.GetArgumentCount();
2787 if (m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2788 // We are given a UUID only, go locate the file
2789 ModuleSpec module_spec
;
2790 module_spec
.GetUUID() =
2791 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2792 if (m_symbol_file
.GetOptionValue().OptionWasSet())
2793 module_spec
.GetSymbolFileSpec() =
2794 m_symbol_file
.GetOptionValue().GetCurrentValue();
2796 if (Symbols::DownloadObjectAndSymbolFile(module_spec
, error
)) {
2798 target
->GetOrCreateModule(module_spec
, true /* notify */));
2800 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2804 module_spec
.GetUUID().Dump(strm
);
2805 if (module_spec
.GetFileSpec()) {
2806 if (module_spec
.GetSymbolFileSpec()) {
2807 result
.AppendErrorWithFormat(
2808 "Unable to create the executable or symbol file with "
2809 "UUID %s with path %s and symbol file %s",
2810 strm
.GetData(), module_spec
.GetFileSpec().GetPath().c_str(),
2811 module_spec
.GetSymbolFileSpec().GetPath().c_str());
2813 result
.AppendErrorWithFormat(
2814 "Unable to create the executable or symbol file with "
2815 "UUID %s with path %s",
2817 module_spec
.GetFileSpec().GetPath().c_str());
2820 result
.AppendErrorWithFormat("Unable to create the executable "
2821 "or symbol file with UUID %s",
2828 module_spec
.GetUUID().Dump(strm
);
2829 result
.AppendErrorWithFormat(
2830 "Unable to locate the executable or symbol file with UUID %s",
2832 result
.SetError(error
);
2837 "one or more executable image paths must be specified");
2841 for (auto &entry
: args
.entries()) {
2842 if (entry
.ref().empty())
2845 FileSpec
file_spec(entry
.ref());
2846 if (FileSystem::Instance().Exists(file_spec
)) {
2847 ModuleSpec
module_spec(file_spec
);
2848 if (m_uuid_option_group
.GetOptionValue().OptionWasSet())
2849 module_spec
.GetUUID() =
2850 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2851 if (m_symbol_file
.GetOptionValue().OptionWasSet())
2852 module_spec
.GetSymbolFileSpec() =
2853 m_symbol_file
.GetOptionValue().GetCurrentValue();
2854 if (!module_spec
.GetArchitecture().IsValid())
2855 module_spec
.GetArchitecture() = target
->GetArchitecture();
2857 ModuleSP
module_sp(target
->GetOrCreateModule(
2858 module_spec
, true /* notify */, &error
));
2860 const char *error_cstr
= error
.AsCString();
2862 result
.AppendError(error_cstr
);
2864 result
.AppendErrorWithFormat("unsupported module: %s",
2870 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2872 std::string resolved_path
= file_spec
.GetPath();
2873 if (resolved_path
!= entry
.ref()) {
2874 result
.AppendErrorWithFormat(
2875 "invalid module path '%s' with resolved path '%s'\n",
2876 entry
.ref().str().c_str(), resolved_path
.c_str());
2879 result
.AppendErrorWithFormat("invalid module path '%s'\n",
2887 ProcessSP process
= target
->GetProcessSP();
2894 class CommandObjectTargetModulesLoad
2895 : public CommandObjectTargetModulesModuleAutoComplete
{
2897 CommandObjectTargetModulesLoad(CommandInterpreter
&interpreter
)
2898 : CommandObjectTargetModulesModuleAutoComplete(
2899 interpreter
, "target modules load",
2900 "Set the load addresses for one or more sections in a target "
2902 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2903 "<address> [<sect-name> <address> ....]",
2904 eCommandRequiresTarget
),
2905 m_file_option(LLDB_OPT_SET_1
, false, "file", 'f', 0, eArgTypeName
,
2906 "Fullpath or basename for module to load.", ""),
2907 m_load_option(LLDB_OPT_SET_1
, false, "load", 'l',
2908 "Write file contents to the memory.", false, true),
2909 m_pc_option(LLDB_OPT_SET_1
, false, "set-pc-to-entry", 'p',
2910 "Set PC to the entry point."
2911 " Only applicable with '--load' option.",
2913 m_slide_option(LLDB_OPT_SET_1
, false, "slide", 's', 0, eArgTypeOffset
,
2914 "Set the load address for all sections to be the "
2915 "virtual address in the file plus the offset.",
2917 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
2919 m_option_group
.Append(&m_file_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2920 m_option_group
.Append(&m_load_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2921 m_option_group
.Append(&m_pc_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2922 m_option_group
.Append(&m_slide_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2923 m_option_group
.Finalize();
2926 ~CommandObjectTargetModulesLoad() override
= default;
2928 Options
*GetOptions() override
{ return &m_option_group
; }
2931 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
2932 Target
*target
= &GetSelectedTarget();
2933 const bool load
= m_load_option
.GetOptionValue().GetCurrentValue();
2934 const bool set_pc
= m_pc_option
.GetOptionValue().GetCurrentValue();
2936 const size_t argc
= args
.GetArgumentCount();
2937 ModuleSpec module_spec
;
2938 bool search_using_module_spec
= false;
2940 // Allow "load" option to work without --file or --uuid option.
2942 if (!m_file_option
.GetOptionValue().OptionWasSet() &&
2943 !m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2944 ModuleList
&module_list
= target
->GetImages();
2945 if (module_list
.GetSize() == 1) {
2946 search_using_module_spec
= true;
2947 module_spec
.GetFileSpec() =
2948 module_list
.GetModuleAtIndex(0)->GetFileSpec();
2953 if (m_file_option
.GetOptionValue().OptionWasSet()) {
2954 search_using_module_spec
= true;
2955 const char *arg_cstr
= m_file_option
.GetOptionValue().GetCurrentValue();
2956 const bool use_global_module_list
= true;
2957 ModuleList module_list
;
2958 const size_t num_matches
= FindModulesByName(
2959 target
, arg_cstr
, module_list
, use_global_module_list
);
2960 if (num_matches
== 1) {
2961 module_spec
.GetFileSpec() =
2962 module_list
.GetModuleAtIndex(0)->GetFileSpec();
2963 } else if (num_matches
> 1) {
2964 search_using_module_spec
= false;
2965 result
.AppendErrorWithFormat(
2966 "more than 1 module matched by name '%s'\n", arg_cstr
);
2968 search_using_module_spec
= false;
2969 result
.AppendErrorWithFormat("no object file for module '%s'\n",
2974 if (m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2975 search_using_module_spec
= true;
2976 module_spec
.GetUUID() =
2977 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2980 if (search_using_module_spec
) {
2981 ModuleList matching_modules
;
2982 target
->GetImages().FindModules(module_spec
, matching_modules
);
2983 const size_t num_matches
= matching_modules
.GetSize();
2985 char path
[PATH_MAX
];
2986 if (num_matches
== 1) {
2987 Module
*module
= matching_modules
.GetModulePointerAtIndex(0);
2989 ObjectFile
*objfile
= module
->GetObjectFile();
2991 SectionList
*section_list
= module
->GetSectionList();
2993 bool changed
= false;
2995 if (m_slide_option
.GetOptionValue().OptionWasSet()) {
2996 const addr_t slide
=
2997 m_slide_option
.GetOptionValue().GetCurrentValue();
2998 const bool slide_is_offset
= true;
2999 module
->SetLoadAddress(*target
, slide
, slide_is_offset
,
3002 result
.AppendError("one or more section name + load "
3003 "address pair must be specified");
3007 if (m_slide_option
.GetOptionValue().OptionWasSet()) {
3008 result
.AppendError("The \"--slide <offset>\" option can't "
3009 "be used in conjunction with setting "
3010 "section load addresses.\n");
3014 for (size_t i
= 0; i
< argc
; i
+= 2) {
3015 const char *sect_name
= args
.GetArgumentAtIndex(i
);
3016 const char *load_addr_cstr
= args
.GetArgumentAtIndex(i
+ 1);
3017 if (sect_name
&& load_addr_cstr
) {
3018 ConstString
const_sect_name(sect_name
);
3020 if (llvm::to_integer(load_addr_cstr
, load_addr
)) {
3021 SectionSP
section_sp(
3022 section_list
->FindSectionByName(const_sect_name
));
3024 if (section_sp
->IsThreadSpecific()) {
3025 result
.AppendErrorWithFormat(
3026 "thread specific sections are not yet "
3027 "supported (section '%s')\n",
3031 if (target
->GetSectionLoadList()
3032 .SetSectionLoadAddress(section_sp
, load_addr
))
3034 result
.AppendMessageWithFormat(
3035 "section '%s' loaded at 0x%" PRIx64
"\n",
3036 sect_name
, load_addr
);
3039 result
.AppendErrorWithFormat("no section found that "
3040 "matches the section "
3046 result
.AppendErrorWithFormat(
3047 "invalid load address string '%s'\n", load_addr_cstr
);
3052 result
.AppendError("section names must be followed by "
3053 "a load address.\n");
3055 result
.AppendError("one or more section name + load "
3056 "address pair must be specified.\n");
3063 target
->ModulesDidLoad(matching_modules
);
3064 Process
*process
= m_exe_ctx
.GetProcessPtr();
3069 ProcessSP process
= target
->CalculateProcess();
3070 Address file_entry
= objfile
->GetEntryPointAddress();
3072 result
.AppendError("No process");
3075 if (set_pc
&& !file_entry
.IsValid()) {
3076 result
.AppendError("No entry address in object file");
3079 std::vector
<ObjectFile::LoadableData
> loadables(
3080 objfile
->GetLoadableData(*target
));
3081 if (loadables
.size() == 0) {
3082 result
.AppendError("No loadable sections");
3085 Status error
= process
->WriteObjectFile(std::move(loadables
));
3087 result
.AppendError(error
.AsCString());
3091 ThreadList
&thread_list
= process
->GetThreadList();
3092 RegisterContextSP
reg_context(
3093 thread_list
.GetSelectedThread()->GetRegisterContext());
3094 addr_t file_entry_addr
= file_entry
.GetLoadAddress(target
);
3095 if (!reg_context
->SetPC(file_entry_addr
)) {
3096 result
.AppendErrorWithFormat("failed to set PC value to "
3103 module
->GetFileSpec().GetPath(path
, sizeof(path
));
3104 result
.AppendErrorWithFormat("no sections in object file '%s'\n",
3108 module
->GetFileSpec().GetPath(path
, sizeof(path
));
3109 result
.AppendErrorWithFormat("no object file for module '%s'\n",
3113 FileSpec
*module_spec_file
= module_spec
.GetFileSpecPtr();
3114 if (module_spec_file
) {
3115 module_spec_file
->GetPath(path
, sizeof(path
));
3116 result
.AppendErrorWithFormat("invalid module '%s'.\n", path
);
3118 result
.AppendError("no module spec");
3121 std::string uuid_str
;
3123 if (module_spec
.GetFileSpec())
3124 module_spec
.GetFileSpec().GetPath(path
, sizeof(path
));
3128 if (module_spec
.GetUUIDPtr())
3129 uuid_str
= module_spec
.GetUUID().GetAsString();
3130 if (num_matches
> 1) {
3131 result
.AppendErrorWithFormat(
3132 "multiple modules match%s%s%s%s:\n", path
[0] ? " file=" : "",
3133 path
, !uuid_str
.empty() ? " uuid=" : "", uuid_str
.c_str());
3134 for (size_t i
= 0; i
< num_matches
; ++i
) {
3135 if (matching_modules
.GetModulePointerAtIndex(i
)
3137 .GetPath(path
, sizeof(path
)))
3138 result
.AppendMessageWithFormat("%s\n", path
);
3141 result
.AppendErrorWithFormat(
3142 "no modules were found that match%s%s%s%s.\n",
3143 path
[0] ? " file=" : "", path
, !uuid_str
.empty() ? " uuid=" : "",
3148 result
.AppendError("either the \"--file <module>\" or the \"--uuid "
3149 "<uuid>\" option must be specified.\n");
3153 OptionGroupOptions m_option_group
;
3154 OptionGroupUUID m_uuid_option_group
;
3155 OptionGroupString m_file_option
;
3156 OptionGroupBoolean m_load_option
;
3157 OptionGroupBoolean m_pc_option
;
3158 OptionGroupUInt64 m_slide_option
;
3161 #pragma mark CommandObjectTargetModulesList
3162 // List images with associated information
3163 #define LLDB_OPTIONS_target_modules_list
3164 #include "CommandOptions.inc"
3166 class CommandObjectTargetModulesList
: public CommandObjectParsed
{
3168 class CommandOptions
: public Options
{
3170 CommandOptions() = default;
3172 ~CommandOptions() override
= default;
3174 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3175 ExecutionContext
*execution_context
) override
{
3178 const int short_option
= m_getopt_table
[option_idx
].val
;
3179 if (short_option
== 'g') {
3180 m_use_global_module_list
= true;
3181 } else if (short_option
== 'a') {
3182 m_module_addr
= OptionArgParser::ToAddress(
3183 execution_context
, option_arg
, LLDB_INVALID_ADDRESS
, &error
);
3185 unsigned long width
= 0;
3186 option_arg
.getAsInteger(0, width
);
3187 m_format_array
.push_back(std::make_pair(short_option
, width
));
3192 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3193 m_format_array
.clear();
3194 m_use_global_module_list
= false;
3195 m_module_addr
= LLDB_INVALID_ADDRESS
;
3198 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3199 return llvm::ArrayRef(g_target_modules_list_options
);
3202 // Instance variables to hold the values for command options.
3203 typedef std::vector
<std::pair
<char, uint32_t>> FormatWidthCollection
;
3204 FormatWidthCollection m_format_array
;
3205 bool m_use_global_module_list
= false;
3206 lldb::addr_t m_module_addr
= LLDB_INVALID_ADDRESS
;
3209 CommandObjectTargetModulesList(CommandInterpreter
&interpreter
)
3210 : CommandObjectParsed(
3211 interpreter
, "target modules list",
3212 "List current executable and dependent shared library images.") {
3213 CommandArgumentData module_arg
{eArgTypeShlibName
, eArgRepeatStar
};
3214 m_arguments
.push_back({module_arg
});
3217 ~CommandObjectTargetModulesList() override
= default;
3219 Options
*GetOptions() override
{ return &m_options
; }
3222 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
3223 Target
*target
= GetDebugger().GetSelectedTarget().get();
3224 const bool use_global_module_list
= m_options
.m_use_global_module_list
;
3225 // Define a local module list here to ensure it lives longer than any
3226 // "locker" object which might lock its contents below (through the
3227 // "module_list_ptr" variable).
3228 ModuleList module_list
;
3229 if (target
== nullptr && !use_global_module_list
) {
3230 result
.AppendError("invalid target, create a debug target using the "
3231 "'target create' command");
3235 uint32_t addr_byte_size
=
3236 target
->GetArchitecture().GetAddressByteSize();
3237 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
3238 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
3240 // Dump all sections for all modules images
3241 Stream
&strm
= result
.GetOutputStream();
3243 if (m_options
.m_module_addr
!= LLDB_INVALID_ADDRESS
) {
3245 Address module_address
;
3246 if (module_address
.SetLoadAddress(m_options
.m_module_addr
, target
)) {
3247 ModuleSP
module_sp(module_address
.GetModule());
3249 PrintModule(target
, module_sp
.get(), 0, strm
);
3250 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3252 result
.AppendErrorWithFormat(
3253 "Couldn't find module matching address: 0x%" PRIx64
".",
3254 m_options
.m_module_addr
);
3257 result
.AppendErrorWithFormat(
3258 "Couldn't find module containing address: 0x%" PRIx64
".",
3259 m_options
.m_module_addr
);
3263 "Can only look up modules by address with a valid target.");
3268 size_t num_modules
= 0;
3270 // This locker will be locked on the mutex in module_list_ptr if it is
3271 // non-nullptr. Otherwise it will lock the
3272 // AllocationModuleCollectionMutex when accessing the global module list
3274 std::unique_lock
<std::recursive_mutex
> guard(
3275 Module::GetAllocationModuleCollectionMutex(), std::defer_lock
);
3277 const ModuleList
*module_list_ptr
= nullptr;
3278 const size_t argc
= command
.GetArgumentCount();
3280 if (use_global_module_list
) {
3282 num_modules
= Module::GetNumberAllocatedModules();
3284 module_list_ptr
= &target
->GetImages();
3287 for (const Args::ArgEntry
&arg
: command
) {
3288 // Dump specified images (by basename or fullpath)
3289 const size_t num_matches
= FindModulesByName(
3290 target
, arg
.c_str(), module_list
, use_global_module_list
);
3291 if (num_matches
== 0) {
3293 result
.AppendErrorWithFormat("no modules found that match '%s'",
3300 module_list_ptr
= &module_list
;
3303 std::unique_lock
<std::recursive_mutex
> lock
;
3304 if (module_list_ptr
!= nullptr) {
3306 std::unique_lock
<std::recursive_mutex
>(module_list_ptr
->GetMutex());
3308 num_modules
= module_list_ptr
->GetSize();
3311 if (num_modules
> 0) {
3312 for (uint32_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
3315 if (module_list_ptr
) {
3316 module_sp
= module_list_ptr
->GetModuleAtIndexUnlocked(image_idx
);
3317 module
= module_sp
.get();
3319 module
= Module::GetAllocatedModuleAtIndex(image_idx
);
3320 module_sp
= module
->shared_from_this();
3323 const size_t indent
= strm
.Printf("[%3u] ", image_idx
);
3324 PrintModule(target
, module
, indent
, strm
);
3326 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3329 if (use_global_module_list
)
3331 "the global module list has no matching modules");
3333 result
.AppendError("the target has no matching modules");
3335 if (use_global_module_list
)
3336 result
.AppendError("the global module list is empty");
3339 "the target has no associated executable images");
3346 void PrintModule(Target
*target
, Module
*module
, int indent
, Stream
&strm
) {
3347 if (module
== nullptr) {
3348 strm
.PutCString("Null module");
3352 bool dump_object_name
= false;
3353 if (m_options
.m_format_array
.empty()) {
3354 m_options
.m_format_array
.push_back(std::make_pair('u', 0));
3355 m_options
.m_format_array
.push_back(std::make_pair('h', 0));
3356 m_options
.m_format_array
.push_back(std::make_pair('f', 0));
3357 m_options
.m_format_array
.push_back(std::make_pair('S', 0));
3359 const size_t num_entries
= m_options
.m_format_array
.size();
3360 bool print_space
= false;
3361 for (size_t i
= 0; i
< num_entries
; ++i
) {
3365 const char format_char
= m_options
.m_format_array
[i
].first
;
3366 uint32_t width
= m_options
.m_format_array
[i
].second
;
3367 switch (format_char
) {
3369 DumpModuleArchitecture(strm
, module
, false, width
);
3373 DumpModuleArchitecture(strm
, module
, true, width
);
3377 DumpFullpath(strm
, &module
->GetFileSpec(), width
);
3378 dump_object_name
= true;
3382 DumpDirectory(strm
, &module
->GetFileSpec(), width
);
3386 DumpBasename(strm
, &module
->GetFileSpec(), width
);
3387 dump_object_name
= true;
3392 // Image header address
3394 uint32_t addr_nibble_width
=
3395 target
? (target
->GetArchitecture().GetAddressByteSize() * 2)
3398 ObjectFile
*objfile
= module
->GetObjectFile();
3400 Address
base_addr(objfile
->GetBaseAddress());
3401 if (base_addr
.IsValid()) {
3402 if (target
&& !target
->GetSectionLoadList().IsEmpty()) {
3403 lldb::addr_t load_addr
= base_addr
.GetLoadAddress(target
);
3404 if (load_addr
== LLDB_INVALID_ADDRESS
) {
3405 base_addr
.Dump(&strm
, target
,
3406 Address::DumpStyleModuleWithFileAddress
,
3407 Address::DumpStyleFileAddress
);
3409 if (format_char
== 'o') {
3410 // Show the offset of slide for the image
3411 strm
.Printf("0x%*.*" PRIx64
, addr_nibble_width
,
3413 load_addr
- base_addr
.GetFileAddress());
3415 // Show the load address of the image
3416 strm
.Printf("0x%*.*" PRIx64
, addr_nibble_width
,
3417 addr_nibble_width
, load_addr
);
3422 // The address was valid, but the image isn't loaded, output the
3423 // address in an appropriate format
3424 base_addr
.Dump(&strm
, target
, Address::DumpStyleFileAddress
);
3428 strm
.Printf("%*s", addr_nibble_width
+ 2, "");
3433 size_t ref_count
= 0;
3434 ModuleSP
module_sp(module
->shared_from_this());
3436 // Take one away to make sure we don't count our local "module_sp"
3437 ref_count
= module_sp
.use_count() - 1;
3440 strm
.Printf("{%*" PRIu64
"}", width
, (uint64_t)ref_count
);
3442 strm
.Printf("{%" PRIu64
"}", (uint64_t)ref_count
);
3447 if (const SymbolFile
*symbol_file
= module
->GetSymbolFile()) {
3448 const FileSpec symfile_spec
=
3449 symbol_file
->GetObjectFile()->GetFileSpec();
3450 if (format_char
== 'S') {
3451 // Dump symbol file only if different from module file
3452 if (!symfile_spec
|| symfile_spec
== module
->GetFileSpec()) {
3453 print_space
= false;
3456 // Add a newline and indent past the index
3457 strm
.Printf("\n%*s", indent
, "");
3459 DumpFullpath(strm
, &symfile_spec
, width
);
3460 dump_object_name
= true;
3463 strm
.Printf("%.*s", width
, "<NONE>");
3467 strm
.Format("{0:%c}", llvm::fmt_align(module
->GetModificationTime(),
3468 llvm::AlignStyle::Left
, width
));
3472 strm
.Printf("%p", static_cast<void *>(module
));
3476 DumpModuleUUID(strm
, module
);
3483 if (dump_object_name
) {
3484 const char *object_name
= module
->GetObjectName().GetCString();
3486 strm
.Printf("(%s)", object_name
);
3491 CommandOptions m_options
;
3494 #pragma mark CommandObjectTargetModulesShowUnwind
3496 // Lookup unwind information in images
3497 #define LLDB_OPTIONS_target_modules_show_unwind
3498 #include "CommandOptions.inc"
3500 class CommandObjectTargetModulesShowUnwind
: public CommandObjectParsed
{
3503 eLookupTypeInvalid
= -1,
3504 eLookupTypeAddress
= 0,
3506 eLookupTypeFunction
,
3507 eLookupTypeFunctionOrSymbol
,
3511 class CommandOptions
: public Options
{
3513 CommandOptions() = default;
3515 ~CommandOptions() override
= default;
3517 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3518 ExecutionContext
*execution_context
) override
{
3521 const int short_option
= m_getopt_table
[option_idx
].val
;
3523 switch (short_option
) {
3525 m_str
= std::string(option_arg
);
3526 m_type
= eLookupTypeAddress
;
3527 m_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
3528 LLDB_INVALID_ADDRESS
, &error
);
3529 if (m_addr
== LLDB_INVALID_ADDRESS
)
3530 error
.SetErrorStringWithFormat("invalid address string '%s'",
3531 option_arg
.str().c_str());
3536 m_str
= std::string(option_arg
);
3537 m_type
= eLookupTypeFunctionOrSymbol
;
3541 llvm_unreachable("Unimplemented option");
3547 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3548 m_type
= eLookupTypeInvalid
;
3550 m_addr
= LLDB_INVALID_ADDRESS
;
3553 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3554 return llvm::ArrayRef(g_target_modules_show_unwind_options
);
3557 // Instance variables to hold the values for command options.
3559 int m_type
= eLookupTypeInvalid
; // Should be a eLookupTypeXXX enum after
3561 std::string m_str
; // Holds name lookup
3562 lldb::addr_t m_addr
= LLDB_INVALID_ADDRESS
; // Holds the address to lookup
3565 CommandObjectTargetModulesShowUnwind(CommandInterpreter
&interpreter
)
3566 : CommandObjectParsed(
3567 interpreter
, "target modules show-unwind",
3568 "Show synthesized unwind instructions for a function.", nullptr,
3569 eCommandRequiresTarget
| eCommandRequiresProcess
|
3570 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
) {}
3572 ~CommandObjectTargetModulesShowUnwind() override
= default;
3574 Options
*GetOptions() override
{ return &m_options
; }
3577 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
3578 Target
*target
= m_exe_ctx
.GetTargetPtr();
3579 Process
*process
= m_exe_ctx
.GetProcessPtr();
3582 abi
= process
->GetABI().get();
3584 if (process
== nullptr) {
3586 "You must have a process running to use this command.");
3590 ThreadList
threads(process
->GetThreadList());
3591 if (threads
.GetSize() == 0) {
3592 result
.AppendError("The process must be paused to use this command.");
3596 ThreadSP
thread(threads
.GetThreadAtIndex(0));
3598 result
.AppendError("The process must be paused to use this command.");
3602 SymbolContextList sc_list
;
3604 if (m_options
.m_type
== eLookupTypeFunctionOrSymbol
) {
3605 ConstString
function_name(m_options
.m_str
.c_str());
3606 ModuleFunctionSearchOptions function_options
;
3607 function_options
.include_symbols
= true;
3608 function_options
.include_inlines
= false;
3609 target
->GetImages().FindFunctions(function_name
, eFunctionNameTypeAuto
,
3610 function_options
, sc_list
);
3611 } else if (m_options
.m_type
== eLookupTypeAddress
&& target
) {
3613 if (target
->GetSectionLoadList().ResolveLoadAddress(m_options
.m_addr
,
3616 ModuleSP
module_sp(addr
.GetModule());
3617 module_sp
->ResolveSymbolContextForAddress(addr
,
3618 eSymbolContextEverything
, sc
);
3619 if (sc
.function
|| sc
.symbol
) {
3625 "address-expression or function name option must be specified.");
3629 if (sc_list
.GetSize() == 0) {
3630 result
.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3631 m_options
.m_str
.c_str());
3635 for (const SymbolContext
&sc
: sc_list
) {
3636 if (sc
.symbol
== nullptr && sc
.function
== nullptr)
3638 if (!sc
.module_sp
|| sc
.module_sp
->GetObjectFile() == nullptr)
3641 if (!sc
.GetAddressRange(eSymbolContextFunction
| eSymbolContextSymbol
, 0,
3644 if (!range
.GetBaseAddress().IsValid())
3646 ConstString
funcname(sc
.GetFunctionName());
3647 if (funcname
.IsEmpty())
3649 addr_t start_addr
= range
.GetBaseAddress().GetLoadAddress(target
);
3651 start_addr
= abi
->FixCodeAddress(start_addr
);
3653 FuncUnwindersSP
func_unwinders_sp(
3654 sc
.module_sp
->GetUnwindTable()
3655 .GetUncachedFuncUnwindersContainingAddress(start_addr
, sc
));
3656 if (!func_unwinders_sp
)
3659 result
.GetOutputStream().Printf(
3660 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64
")\n",
3661 sc
.module_sp
->GetPlatformFileSpec().GetFilename().AsCString(),
3662 funcname
.AsCString(), start_addr
);
3665 target
->GetUserSpecifiedTrapHandlerNames(args
);
3666 size_t count
= args
.GetArgumentCount();
3667 for (size_t i
= 0; i
< count
; i
++) {
3668 const char *trap_func_name
= args
.GetArgumentAtIndex(i
);
3669 if (strcmp(funcname
.GetCString(), trap_func_name
) == 0)
3670 result
.GetOutputStream().Printf(
3672 "treated as a trap handler function via user setting.\n");
3674 PlatformSP
platform_sp(target
->GetPlatform());
3676 const std::vector
<ConstString
> trap_handler_names(
3677 platform_sp
->GetTrapHandlerSymbolNames());
3678 for (ConstString trap_name
: trap_handler_names
) {
3679 if (trap_name
== funcname
) {
3680 result
.GetOutputStream().Printf(
3682 "name is listed by the platform as a trap handler.\n");
3687 result
.GetOutputStream().Printf("\n");
3689 UnwindPlanSP non_callsite_unwind_plan
=
3690 func_unwinders_sp
->GetUnwindPlanAtNonCallSite(*target
, *thread
);
3691 if (non_callsite_unwind_plan
) {
3692 result
.GetOutputStream().Printf(
3693 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3694 non_callsite_unwind_plan
->GetSourceName().AsCString());
3696 UnwindPlanSP callsite_unwind_plan
=
3697 func_unwinders_sp
->GetUnwindPlanAtCallSite(*target
, *thread
);
3698 if (callsite_unwind_plan
) {
3699 result
.GetOutputStream().Printf(
3700 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3701 callsite_unwind_plan
->GetSourceName().AsCString());
3703 UnwindPlanSP fast_unwind_plan
=
3704 func_unwinders_sp
->GetUnwindPlanFastUnwind(*target
, *thread
);
3705 if (fast_unwind_plan
) {
3706 result
.GetOutputStream().Printf(
3707 "Fast UnwindPlan is '%s'\n",
3708 fast_unwind_plan
->GetSourceName().AsCString());
3711 result
.GetOutputStream().Printf("\n");
3713 UnwindPlanSP assembly_sp
=
3714 func_unwinders_sp
->GetAssemblyUnwindPlan(*target
, *thread
);
3716 result
.GetOutputStream().Printf(
3717 "Assembly language inspection UnwindPlan:\n");
3718 assembly_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3719 LLDB_INVALID_ADDRESS
);
3720 result
.GetOutputStream().Printf("\n");
3723 UnwindPlanSP of_unwind_sp
=
3724 func_unwinders_sp
->GetObjectFileUnwindPlan(*target
);
3726 result
.GetOutputStream().Printf("object file UnwindPlan:\n");
3727 of_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3728 LLDB_INVALID_ADDRESS
);
3729 result
.GetOutputStream().Printf("\n");
3732 UnwindPlanSP of_unwind_augmented_sp
=
3733 func_unwinders_sp
->GetObjectFileAugmentedUnwindPlan(*target
, *thread
);
3734 if (of_unwind_augmented_sp
) {
3735 result
.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3736 of_unwind_augmented_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3737 LLDB_INVALID_ADDRESS
);
3738 result
.GetOutputStream().Printf("\n");
3741 UnwindPlanSP ehframe_sp
=
3742 func_unwinders_sp
->GetEHFrameUnwindPlan(*target
);
3744 result
.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3745 ehframe_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3746 LLDB_INVALID_ADDRESS
);
3747 result
.GetOutputStream().Printf("\n");
3750 UnwindPlanSP ehframe_augmented_sp
=
3751 func_unwinders_sp
->GetEHFrameAugmentedUnwindPlan(*target
, *thread
);
3752 if (ehframe_augmented_sp
) {
3753 result
.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3754 ehframe_augmented_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3755 LLDB_INVALID_ADDRESS
);
3756 result
.GetOutputStream().Printf("\n");
3759 if (UnwindPlanSP plan_sp
=
3760 func_unwinders_sp
->GetDebugFrameUnwindPlan(*target
)) {
3761 result
.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3762 plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3763 LLDB_INVALID_ADDRESS
);
3764 result
.GetOutputStream().Printf("\n");
3767 if (UnwindPlanSP plan_sp
=
3768 func_unwinders_sp
->GetDebugFrameAugmentedUnwindPlan(*target
,
3770 result
.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3771 plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3772 LLDB_INVALID_ADDRESS
);
3773 result
.GetOutputStream().Printf("\n");
3776 UnwindPlanSP arm_unwind_sp
=
3777 func_unwinders_sp
->GetArmUnwindUnwindPlan(*target
);
3778 if (arm_unwind_sp
) {
3779 result
.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3780 arm_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3781 LLDB_INVALID_ADDRESS
);
3782 result
.GetOutputStream().Printf("\n");
3785 if (UnwindPlanSP symfile_plan_sp
=
3786 func_unwinders_sp
->GetSymbolFileUnwindPlan(*thread
)) {
3787 result
.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3788 symfile_plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3789 LLDB_INVALID_ADDRESS
);
3790 result
.GetOutputStream().Printf("\n");
3793 UnwindPlanSP compact_unwind_sp
=
3794 func_unwinders_sp
->GetCompactUnwindUnwindPlan(*target
);
3795 if (compact_unwind_sp
) {
3796 result
.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3797 compact_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3798 LLDB_INVALID_ADDRESS
);
3799 result
.GetOutputStream().Printf("\n");
3802 if (fast_unwind_plan
) {
3803 result
.GetOutputStream().Printf("Fast UnwindPlan:\n");
3804 fast_unwind_plan
->Dump(result
.GetOutputStream(), thread
.get(),
3805 LLDB_INVALID_ADDRESS
);
3806 result
.GetOutputStream().Printf("\n");
3809 ABISP abi_sp
= process
->GetABI();
3811 UnwindPlan
arch_default(lldb::eRegisterKindGeneric
);
3812 if (abi_sp
->CreateDefaultUnwindPlan(arch_default
)) {
3813 result
.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3814 arch_default
.Dump(result
.GetOutputStream(), thread
.get(),
3815 LLDB_INVALID_ADDRESS
);
3816 result
.GetOutputStream().Printf("\n");
3819 UnwindPlan
arch_entry(lldb::eRegisterKindGeneric
);
3820 if (abi_sp
->CreateFunctionEntryUnwindPlan(arch_entry
)) {
3821 result
.GetOutputStream().Printf(
3822 "Arch default at entry point UnwindPlan:\n");
3823 arch_entry
.Dump(result
.GetOutputStream(), thread
.get(),
3824 LLDB_INVALID_ADDRESS
);
3825 result
.GetOutputStream().Printf("\n");
3829 result
.GetOutputStream().Printf("\n");
3833 CommandOptions m_options
;
3836 // Lookup information in images
3837 #define LLDB_OPTIONS_target_modules_lookup
3838 #include "CommandOptions.inc"
3840 class CommandObjectTargetModulesLookup
: public CommandObjectParsed
{
3843 eLookupTypeInvalid
= -1,
3844 eLookupTypeAddress
= 0,
3846 eLookupTypeFileLine
, // Line is optional
3847 eLookupTypeFunction
,
3848 eLookupTypeFunctionOrSymbol
,
3853 class CommandOptions
: public Options
{
3855 CommandOptions() { OptionParsingStarting(nullptr); }
3857 ~CommandOptions() override
= default;
3859 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3860 ExecutionContext
*execution_context
) override
{
3863 const int short_option
= m_getopt_table
[option_idx
].val
;
3865 switch (short_option
) {
3867 m_type
= eLookupTypeAddress
;
3868 m_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
3869 LLDB_INVALID_ADDRESS
, &error
);
3873 if (option_arg
.getAsInteger(0, m_offset
))
3874 error
.SetErrorStringWithFormat("invalid offset string '%s'",
3875 option_arg
.str().c_str());
3879 m_str
= std::string(option_arg
);
3880 m_type
= eLookupTypeSymbol
;
3884 m_file
.SetFile(option_arg
, FileSpec::Style::native
);
3885 m_type
= eLookupTypeFileLine
;
3889 m_include_inlines
= false;
3893 if (option_arg
.getAsInteger(0, m_line_number
))
3894 error
.SetErrorStringWithFormat("invalid line number string '%s'",
3895 option_arg
.str().c_str());
3896 else if (m_line_number
== 0)
3897 error
.SetErrorString("zero is an invalid line number");
3898 m_type
= eLookupTypeFileLine
;
3902 m_str
= std::string(option_arg
);
3903 m_type
= eLookupTypeFunction
;
3907 m_str
= std::string(option_arg
);
3908 m_type
= eLookupTypeFunctionOrSymbol
;
3912 m_str
= std::string(option_arg
);
3913 m_type
= eLookupTypeType
;
3929 m_all_ranges
= true;
3932 llvm_unreachable("Unimplemented option");
3938 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3939 m_type
= eLookupTypeInvalid
;
3942 m_addr
= LLDB_INVALID_ADDRESS
;
3945 m_use_regex
= false;
3946 m_include_inlines
= true;
3947 m_all_ranges
= false;
3949 m_print_all
= false;
3952 Status
OptionParsingFinished(ExecutionContext
*execution_context
) override
{
3954 if (m_all_ranges
&& !m_verbose
) {
3955 status
.SetErrorString("--show-variable-ranges must be used in "
3956 "conjunction with --verbose.");
3961 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3962 return llvm::ArrayRef(g_target_modules_lookup_options
);
3965 int m_type
; // Should be a eLookupTypeXXX enum after parsing options
3966 std::string m_str
; // Holds name lookup
3967 FileSpec m_file
; // Files for file lookups
3968 lldb::addr_t m_addr
; // Holds the address to lookup
3970 m_offset
; // Subtract this offset from m_addr before doing lookups.
3971 uint32_t m_line_number
; // Line number for file+line lookups
3972 bool m_use_regex
; // Name lookups in m_str are regular expressions.
3973 bool m_include_inlines
; // Check for inline entries when looking up by
3975 bool m_all_ranges
; // Print all ranges or single range.
3976 bool m_verbose
; // Enable verbose lookup info
3977 bool m_print_all
; // Print all matches, even in cases where there's a best
3981 CommandObjectTargetModulesLookup(CommandInterpreter
&interpreter
)
3982 : CommandObjectParsed(interpreter
, "target modules lookup",
3983 "Look up information within executable and "
3984 "dependent shared library images.",
3985 nullptr, eCommandRequiresTarget
) {
3986 CommandArgumentEntry arg
;
3987 CommandArgumentData file_arg
;
3989 // Define the first (and only) variant of this arg.
3990 file_arg
.arg_type
= eArgTypeFilename
;
3991 file_arg
.arg_repetition
= eArgRepeatStar
;
3993 // There is only one variant this argument could be; put it into the
3995 arg
.push_back(file_arg
);
3997 // Push the data for the first argument into the m_arguments vector.
3998 m_arguments
.push_back(arg
);
4001 ~CommandObjectTargetModulesLookup() override
= default;
4003 Options
*GetOptions() override
{ return &m_options
; }
4005 bool LookupHere(CommandInterpreter
&interpreter
, CommandReturnObject
&result
,
4006 bool &syntax_error
) {
4007 switch (m_options
.m_type
) {
4008 case eLookupTypeAddress
:
4009 case eLookupTypeFileLine
:
4010 case eLookupTypeFunction
:
4011 case eLookupTypeFunctionOrSymbol
:
4012 case eLookupTypeSymbol
:
4015 case eLookupTypeType
:
4019 StackFrameSP frame
= m_exe_ctx
.GetFrameSP();
4024 const SymbolContext
&sym_ctx(frame
->GetSymbolContext(eSymbolContextModule
));
4026 if (!sym_ctx
.module_sp
)
4029 switch (m_options
.m_type
) {
4032 case eLookupTypeType
:
4033 if (!m_options
.m_str
.empty()) {
4034 if (LookupTypeHere(&GetSelectedTarget(), m_interpreter
,
4035 result
.GetOutputStream(), *sym_ctx
.module_sp
,
4036 m_options
.m_str
.c_str(), m_options
.m_use_regex
)) {
4037 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4047 bool LookupInModule(CommandInterpreter
&interpreter
, Module
*module
,
4048 CommandReturnObject
&result
, bool &syntax_error
) {
4049 switch (m_options
.m_type
) {
4050 case eLookupTypeAddress
:
4051 if (m_options
.m_addr
!= LLDB_INVALID_ADDRESS
) {
4052 if (LookupAddressInModule(
4053 m_interpreter
, result
.GetOutputStream(), module
,
4054 eSymbolContextEverything
|
4055 (m_options
.m_verbose
4056 ? static_cast<int>(eSymbolContextVariable
)
4058 m_options
.m_addr
, m_options
.m_offset
, m_options
.m_verbose
,
4059 m_options
.m_all_ranges
)) {
4060 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4066 case eLookupTypeSymbol
:
4067 if (!m_options
.m_str
.empty()) {
4068 if (LookupSymbolInModule(m_interpreter
, result
.GetOutputStream(),
4069 module
, m_options
.m_str
.c_str(),
4070 m_options
.m_use_regex
, m_options
.m_verbose
,
4071 m_options
.m_all_ranges
)) {
4072 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4078 case eLookupTypeFileLine
:
4079 if (m_options
.m_file
) {
4080 if (LookupFileAndLineInModule(
4081 m_interpreter
, result
.GetOutputStream(), module
,
4082 m_options
.m_file
, m_options
.m_line_number
,
4083 m_options
.m_include_inlines
, m_options
.m_verbose
,
4084 m_options
.m_all_ranges
)) {
4085 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4091 case eLookupTypeFunctionOrSymbol
:
4092 case eLookupTypeFunction
:
4093 if (!m_options
.m_str
.empty()) {
4094 ModuleFunctionSearchOptions function_options
;
4095 function_options
.include_symbols
=
4096 m_options
.m_type
== eLookupTypeFunctionOrSymbol
;
4097 function_options
.include_inlines
= m_options
.m_include_inlines
;
4099 if (LookupFunctionInModule(m_interpreter
, result
.GetOutputStream(),
4100 module
, m_options
.m_str
.c_str(),
4101 m_options
.m_use_regex
, function_options
,
4102 m_options
.m_verbose
,
4103 m_options
.m_all_ranges
)) {
4104 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4110 case eLookupTypeType
:
4111 if (!m_options
.m_str
.empty()) {
4112 if (LookupTypeInModule(
4113 &GetSelectedTarget(), m_interpreter
, result
.GetOutputStream(),
4114 module
, m_options
.m_str
.c_str(), m_options
.m_use_regex
)) {
4115 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4122 m_options
.GenerateOptionUsage(
4123 result
.GetErrorStream(), *this,
4124 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
4125 syntax_error
= true;
4129 result
.SetStatus(eReturnStatusFailed
);
4134 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
4135 Target
*target
= &GetSelectedTarget();
4136 bool syntax_error
= false;
4138 uint32_t num_successful_lookups
= 0;
4139 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
4140 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
4141 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
4142 // Dump all sections for all modules images
4144 if (command
.GetArgumentCount() == 0) {
4145 ModuleSP current_module
;
4147 // Where it is possible to look in the current symbol context first,
4148 // try that. If this search was successful and --all was not passed,
4149 // don't print anything else.
4150 if (LookupHere(m_interpreter
, result
, syntax_error
)) {
4151 result
.GetOutputStream().EOL();
4152 num_successful_lookups
++;
4153 if (!m_options
.m_print_all
) {
4154 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4159 // Dump all sections for all other modules
4161 const ModuleList
&target_modules
= target
->GetImages();
4162 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
4163 if (target_modules
.GetSize() == 0) {
4164 result
.AppendError("the target has no associated executable images");
4168 for (ModuleSP module_sp
: target_modules
.ModulesNoLocking()) {
4169 if (module_sp
!= current_module
&&
4170 LookupInModule(m_interpreter
, module_sp
.get(), result
,
4172 result
.GetOutputStream().EOL();
4173 num_successful_lookups
++;
4177 // Dump specified images (by basename or fullpath)
4178 const char *arg_cstr
;
4179 for (i
= 0; (arg_cstr
= command
.GetArgumentAtIndex(i
)) != nullptr &&
4182 ModuleList module_list
;
4183 const size_t num_matches
=
4184 FindModulesByName(target
, arg_cstr
, module_list
, false);
4185 if (num_matches
> 0) {
4186 for (size_t j
= 0; j
< num_matches
; ++j
) {
4187 Module
*module
= module_list
.GetModulePointerAtIndex(j
);
4189 if (LookupInModule(m_interpreter
, module
, result
, syntax_error
)) {
4190 result
.GetOutputStream().EOL();
4191 num_successful_lookups
++;
4196 result
.AppendWarningWithFormat(
4197 "Unable to find an image that matches '%s'.\n", arg_cstr
);
4201 if (num_successful_lookups
> 0)
4202 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4204 result
.SetStatus(eReturnStatusFailed
);
4207 CommandOptions m_options
;
4210 #pragma mark CommandObjectMultiwordImageSearchPaths
4212 // CommandObjectMultiwordImageSearchPaths
4214 class CommandObjectTargetModulesImageSearchPaths
4215 : public CommandObjectMultiword
{
4217 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter
&interpreter
)
4218 : CommandObjectMultiword(
4219 interpreter
, "target modules search-paths",
4220 "Commands for managing module search paths for a target.",
4221 "target modules search-paths <subcommand> [<subcommand-options>]") {
4223 "add", CommandObjectSP(
4224 new CommandObjectTargetModulesSearchPathsAdd(interpreter
)));
4226 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
4231 new CommandObjectTargetModulesSearchPathsInsert(interpreter
)));
4233 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
4236 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
4240 ~CommandObjectTargetModulesImageSearchPaths() override
= default;
4243 #pragma mark CommandObjectTargetModules
4245 // CommandObjectTargetModules
4247 class CommandObjectTargetModules
: public CommandObjectMultiword
{
4249 // Constructors and Destructors
4250 CommandObjectTargetModules(CommandInterpreter
&interpreter
)
4251 : CommandObjectMultiword(interpreter
, "target modules",
4252 "Commands for accessing information for one or "
4253 "more target modules.",
4254 "target modules <sub-command> ...") {
4256 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter
)));
4257 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
4259 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
4261 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
4265 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter
)));
4269 new CommandObjectTargetModulesImageSearchPaths(interpreter
)));
4272 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter
)));
4275 ~CommandObjectTargetModules() override
= default;
4278 // For CommandObjectTargetModules only
4279 CommandObjectTargetModules(const CommandObjectTargetModules
&) = delete;
4280 const CommandObjectTargetModules
&
4281 operator=(const CommandObjectTargetModules
&) = delete;
4284 class CommandObjectTargetSymbolsAdd
: public CommandObjectParsed
{
4286 CommandObjectTargetSymbolsAdd(CommandInterpreter
&interpreter
)
4287 : CommandObjectParsed(
4288 interpreter
, "target symbols add",
4289 "Add a debug symbol file to one of the target's current modules by "
4290 "specifying a path to a debug symbols file or by using the options "
4291 "to specify a module.",
4292 "target symbols add <cmd-options> [<symfile>]",
4293 eCommandRequiresTarget
),
4295 LLDB_OPT_SET_1
, false, "shlib", 's', lldb::eModuleCompletion
,
4297 "Locate the debug symbols for the shared library specified by "
4299 m_current_frame_option(
4300 LLDB_OPT_SET_2
, false, "frame", 'F',
4301 "Locate the debug symbols for the currently selected frame.", false,
4303 m_current_stack_option(LLDB_OPT_SET_2
, false, "stack", 'S',
4304 "Locate the debug symbols for every frame in "
4305 "the current call stack.",
4309 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
4311 m_option_group
.Append(&m_file_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
4312 m_option_group
.Append(&m_current_frame_option
, LLDB_OPT_SET_2
,
4314 m_option_group
.Append(&m_current_stack_option
, LLDB_OPT_SET_2
,
4316 m_option_group
.Finalize();
4317 CommandArgumentData module_arg
{eArgTypeShlibName
, eArgRepeatPlain
};
4318 m_arguments
.push_back({module_arg
});
4321 ~CommandObjectTargetSymbolsAdd() override
= default;
4324 HandleArgumentCompletion(CompletionRequest
&request
,
4325 OptionElementVector
&opt_element_vector
) override
{
4326 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
4327 GetCommandInterpreter(), lldb::eDiskFileCompletion
, request
, nullptr);
4330 Options
*GetOptions() override
{ return &m_option_group
; }
4333 bool AddModuleSymbols(Target
*target
, ModuleSpec
&module_spec
, bool &flush
,
4334 CommandReturnObject
&result
) {
4335 const FileSpec
&symbol_fspec
= module_spec
.GetSymbolFileSpec();
4336 if (!symbol_fspec
) {
4338 "one or more executable image paths must be specified");
4342 char symfile_path
[PATH_MAX
];
4343 symbol_fspec
.GetPath(symfile_path
, sizeof(symfile_path
));
4345 if (!module_spec
.GetUUID().IsValid()) {
4346 if (!module_spec
.GetFileSpec() && !module_spec
.GetPlatformFileSpec())
4347 module_spec
.GetFileSpec().SetFilename(symbol_fspec
.GetFilename());
4350 // Now module_spec represents a symbol file for a module that might exist
4351 // in the current target. Let's find possible matches.
4352 ModuleList matching_modules
;
4354 // First extract all module specs from the symbol file
4355 lldb_private::ModuleSpecList symfile_module_specs
;
4356 if (ObjectFile::GetModuleSpecifications(module_spec
.GetSymbolFileSpec(),
4357 0, 0, symfile_module_specs
)) {
4358 // Now extract the module spec that matches the target architecture
4359 ModuleSpec target_arch_module_spec
;
4360 ModuleSpec symfile_module_spec
;
4361 target_arch_module_spec
.GetArchitecture() = target
->GetArchitecture();
4362 if (symfile_module_specs
.FindMatchingModuleSpec(target_arch_module_spec
,
4363 symfile_module_spec
)) {
4364 if (symfile_module_spec
.GetUUID().IsValid()) {
4365 // It has a UUID, look for this UUID in the target modules
4366 ModuleSpec symfile_uuid_module_spec
;
4367 symfile_uuid_module_spec
.GetUUID() = symfile_module_spec
.GetUUID();
4368 target
->GetImages().FindModules(symfile_uuid_module_spec
,
4373 if (matching_modules
.IsEmpty()) {
4374 // No matches yet. Iterate through the module specs to find a UUID
4375 // value that we can match up to an image in our target.
4376 const size_t num_symfile_module_specs
= symfile_module_specs
.GetSize();
4378 i
< num_symfile_module_specs
&& matching_modules
.IsEmpty(); ++i
) {
4379 if (symfile_module_specs
.GetModuleSpecAtIndex(
4380 i
, symfile_module_spec
)) {
4381 if (symfile_module_spec
.GetUUID().IsValid()) {
4382 // It has a UUID. Look for this UUID in the target modules.
4383 ModuleSpec symfile_uuid_module_spec
;
4384 symfile_uuid_module_spec
.GetUUID() =
4385 symfile_module_spec
.GetUUID();
4386 target
->GetImages().FindModules(symfile_uuid_module_spec
,
4394 // Just try to match up the file by basename if we have no matches at
4395 // this point. For example, module foo might have symbols in foo.debug.
4396 if (matching_modules
.IsEmpty())
4397 target
->GetImages().FindModules(module_spec
, matching_modules
);
4399 while (matching_modules
.IsEmpty()) {
4400 ConstString
filename_no_extension(
4401 module_spec
.GetFileSpec().GetFileNameStrippingExtension());
4402 // Empty string returned, let's bail
4403 if (!filename_no_extension
)
4406 // Check if there was no extension to strip and the basename is the same
4407 if (filename_no_extension
== module_spec
.GetFileSpec().GetFilename())
4410 // Replace basename with one fewer extension
4411 module_spec
.GetFileSpec().SetFilename(filename_no_extension
);
4412 target
->GetImages().FindModules(module_spec
, matching_modules
);
4415 if (matching_modules
.GetSize() > 1) {
4416 result
.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4417 "use the --uuid option to resolve the "
4423 if (matching_modules
.GetSize() == 1) {
4424 ModuleSP
module_sp(matching_modules
.GetModuleAtIndex(0));
4426 // The module has not yet created its symbol vendor, we can just give
4427 // the existing target module the symfile path to use for when it
4428 // decides to create it!
4429 module_sp
->SetSymbolFileFileSpec(symbol_fspec
);
4431 SymbolFile
*symbol_file
=
4432 module_sp
->GetSymbolFile(true, &result
.GetErrorStream());
4434 ObjectFile
*object_file
= symbol_file
->GetObjectFile();
4435 if (object_file
&& object_file
->GetFileSpec() == symbol_fspec
) {
4436 // Provide feedback that the symfile has been successfully added.
4437 const FileSpec
&module_fs
= module_sp
->GetFileSpec();
4438 result
.AppendMessageWithFormat(
4439 "symbol file '%s' has been added to '%s'\n", symfile_path
,
4440 module_fs
.GetPath().c_str());
4442 // Let clients know something changed in the module if it is
4444 ModuleList module_list
;
4445 module_list
.Append(module_sp
);
4446 target
->SymbolsDidLoad(module_list
);
4448 // Make sure we load any scripting resources that may be embedded
4449 // in the debug info files in case the platform supports that.
4451 StreamString feedback_stream
;
4452 module_sp
->LoadScriptingResourceInTarget(target
, error
,
4454 if (error
.Fail() && error
.AsCString())
4455 result
.AppendWarningWithFormat(
4456 "unable to load scripting data for module %s - error "
4458 module_sp
->GetFileSpec()
4459 .GetFileNameStrippingExtension()
4462 else if (feedback_stream
.GetSize())
4463 result
.AppendWarning(feedback_stream
.GetData());
4466 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4470 // Clear the symbol file spec if anything went wrong
4471 module_sp
->SetSymbolFileFileSpec(FileSpec());
4474 StreamString ss_symfile_uuid
;
4475 if (module_spec
.GetUUID().IsValid()) {
4476 ss_symfile_uuid
<< " (";
4477 module_spec
.GetUUID().Dump(ss_symfile_uuid
);
4478 ss_symfile_uuid
<< ')';
4480 result
.AppendErrorWithFormat(
4481 "symbol file '%s'%s does not match any existing module%s\n",
4482 symfile_path
, ss_symfile_uuid
.GetData(),
4483 !llvm::sys::fs::is_regular_file(symbol_fspec
.GetPath())
4484 ? "\n please specify the full path to the symbol file"
4489 bool DownloadObjectAndSymbolFile(ModuleSpec
&module_spec
,
4490 CommandReturnObject
&result
, bool &flush
) {
4492 if (Symbols::DownloadObjectAndSymbolFile(module_spec
, error
)) {
4493 if (module_spec
.GetSymbolFileSpec())
4494 return AddModuleSymbols(m_exe_ctx
.GetTargetPtr(), module_spec
, flush
,
4497 result
.SetError(error
);
4502 bool AddSymbolsForUUID(CommandReturnObject
&result
, bool &flush
) {
4503 assert(m_uuid_option_group
.GetOptionValue().OptionWasSet());
4505 ModuleSpec module_spec
;
4506 module_spec
.GetUUID() =
4507 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
4509 if (!DownloadObjectAndSymbolFile(module_spec
, result
, flush
)) {
4510 StreamString error_strm
;
4511 error_strm
.PutCString("unable to find debug symbols for UUID ");
4512 module_spec
.GetUUID().Dump(error_strm
);
4513 result
.AppendError(error_strm
.GetString());
4520 bool AddSymbolsForFile(CommandReturnObject
&result
, bool &flush
) {
4521 assert(m_file_option
.GetOptionValue().OptionWasSet());
4523 ModuleSpec module_spec
;
4524 module_spec
.GetFileSpec() =
4525 m_file_option
.GetOptionValue().GetCurrentValue();
4527 Target
*target
= m_exe_ctx
.GetTargetPtr();
4528 ModuleSP
module_sp(target
->GetImages().FindFirstModule(module_spec
));
4530 module_spec
.GetFileSpec() = module_sp
->GetFileSpec();
4531 module_spec
.GetPlatformFileSpec() = module_sp
->GetPlatformFileSpec();
4532 module_spec
.GetUUID() = module_sp
->GetUUID();
4533 module_spec
.GetArchitecture() = module_sp
->GetArchitecture();
4535 module_spec
.GetArchitecture() = target
->GetArchitecture();
4538 if (!DownloadObjectAndSymbolFile(module_spec
, result
, flush
)) {
4539 StreamString error_strm
;
4540 error_strm
.PutCString(
4541 "unable to find debug symbols for the executable file ");
4542 error_strm
<< module_spec
.GetFileSpec();
4543 result
.AppendError(error_strm
.GetString());
4550 bool AddSymbolsForFrame(CommandReturnObject
&result
, bool &flush
) {
4551 assert(m_current_frame_option
.GetOptionValue().OptionWasSet());
4553 Process
*process
= m_exe_ctx
.GetProcessPtr();
4556 "a process must exist in order to use the --frame option");
4560 const StateType process_state
= process
->GetState();
4561 if (!StateIsStoppedState(process_state
, true)) {
4562 result
.AppendErrorWithFormat("process is not stopped: %s",
4563 StateAsCString(process_state
));
4567 StackFrame
*frame
= m_exe_ctx
.GetFramePtr();
4569 result
.AppendError("invalid current frame");
4573 ModuleSP
frame_module_sp(
4574 frame
->GetSymbolContext(eSymbolContextModule
).module_sp
);
4575 if (!frame_module_sp
) {
4576 result
.AppendError("frame has no module");
4580 ModuleSpec module_spec
;
4581 module_spec
.GetUUID() = frame_module_sp
->GetUUID();
4583 if (FileSystem::Instance().Exists(frame_module_sp
->GetPlatformFileSpec())) {
4584 module_spec
.GetArchitecture() = frame_module_sp
->GetArchitecture();
4585 module_spec
.GetFileSpec() = frame_module_sp
->GetPlatformFileSpec();
4588 if (!DownloadObjectAndSymbolFile(module_spec
, result
, flush
)) {
4589 result
.AppendError("unable to find debug symbols for the current frame");
4596 bool AddSymbolsForStack(CommandReturnObject
&result
, bool &flush
) {
4597 assert(m_current_stack_option
.GetOptionValue().OptionWasSet());
4599 Process
*process
= m_exe_ctx
.GetProcessPtr();
4602 "a process must exist in order to use the --stack option");
4606 const StateType process_state
= process
->GetState();
4607 if (!StateIsStoppedState(process_state
, true)) {
4608 result
.AppendErrorWithFormat("process is not stopped: %s",
4609 StateAsCString(process_state
));
4613 Thread
*thread
= m_exe_ctx
.GetThreadPtr();
4615 result
.AppendError("invalid current thread");
4619 bool symbols_found
= false;
4620 uint32_t frame_count
= thread
->GetStackFrameCount();
4621 for (uint32_t i
= 0; i
< frame_count
; ++i
) {
4622 lldb::StackFrameSP frame_sp
= thread
->GetStackFrameAtIndex(i
);
4624 ModuleSP
frame_module_sp(
4625 frame_sp
->GetSymbolContext(eSymbolContextModule
).module_sp
);
4626 if (!frame_module_sp
)
4629 ModuleSpec module_spec
;
4630 module_spec
.GetUUID() = frame_module_sp
->GetUUID();
4632 if (FileSystem::Instance().Exists(
4633 frame_module_sp
->GetPlatformFileSpec())) {
4634 module_spec
.GetArchitecture() = frame_module_sp
->GetArchitecture();
4635 module_spec
.GetFileSpec() = frame_module_sp
->GetPlatformFileSpec();
4638 bool current_frame_flush
= false;
4639 if (DownloadObjectAndSymbolFile(module_spec
, result
, current_frame_flush
))
4640 symbols_found
= true;
4641 flush
|= current_frame_flush
;
4644 if (!symbols_found
) {
4646 "unable to find debug symbols in the current call stack");
4653 void DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
4654 Target
*target
= m_exe_ctx
.GetTargetPtr();
4655 result
.SetStatus(eReturnStatusFailed
);
4657 ModuleSpec module_spec
;
4658 const bool uuid_option_set
=
4659 m_uuid_option_group
.GetOptionValue().OptionWasSet();
4660 const bool file_option_set
= m_file_option
.GetOptionValue().OptionWasSet();
4661 const bool frame_option_set
=
4662 m_current_frame_option
.GetOptionValue().OptionWasSet();
4663 const bool stack_option_set
=
4664 m_current_stack_option
.GetOptionValue().OptionWasSet();
4665 const size_t argc
= args
.GetArgumentCount();
4668 if (uuid_option_set
)
4669 AddSymbolsForUUID(result
, flush
);
4670 else if (file_option_set
)
4671 AddSymbolsForFile(result
, flush
);
4672 else if (frame_option_set
)
4673 AddSymbolsForFrame(result
, flush
);
4674 else if (stack_option_set
)
4675 AddSymbolsForStack(result
, flush
);
4677 result
.AppendError("one or more symbol file paths must be specified, "
4678 "or options must be specified");
4680 if (uuid_option_set
) {
4681 result
.AppendError("specify either one or more paths to symbol files "
4682 "or use the --uuid option without arguments");
4683 } else if (frame_option_set
) {
4684 result
.AppendError("specify either one or more paths to symbol files "
4685 "or use the --frame option without arguments");
4686 } else if (file_option_set
&& argc
> 1) {
4687 result
.AppendError("specify at most one symbol file path when "
4688 "--shlib option is set");
4690 PlatformSP
platform_sp(target
->GetPlatform());
4692 for (auto &entry
: args
.entries()) {
4693 if (!entry
.ref().empty()) {
4694 auto &symbol_file_spec
= module_spec
.GetSymbolFileSpec();
4695 symbol_file_spec
.SetFile(entry
.ref(), FileSpec::Style::native
);
4696 FileSystem::Instance().Resolve(symbol_file_spec
);
4697 if (file_option_set
) {
4698 module_spec
.GetFileSpec() =
4699 m_file_option
.GetOptionValue().GetCurrentValue();
4702 FileSpec symfile_spec
;
4704 ->ResolveSymbolFile(*target
, module_spec
, symfile_spec
)
4706 module_spec
.GetSymbolFileSpec() = symfile_spec
;
4709 bool symfile_exists
=
4710 FileSystem::Instance().Exists(module_spec
.GetSymbolFileSpec());
4712 if (symfile_exists
) {
4713 if (!AddModuleSymbols(target
, module_spec
, flush
, result
))
4716 std::string resolved_symfile_path
=
4717 module_spec
.GetSymbolFileSpec().GetPath();
4718 if (resolved_symfile_path
!= entry
.ref()) {
4719 result
.AppendErrorWithFormat(
4720 "invalid module path '%s' with resolved path '%s'\n",
4721 entry
.c_str(), resolved_symfile_path
.c_str());
4724 result
.AppendErrorWithFormat("invalid module path '%s'\n",
4734 Process
*process
= m_exe_ctx
.GetProcessPtr();
4740 OptionGroupOptions m_option_group
;
4741 OptionGroupUUID m_uuid_option_group
;
4742 OptionGroupFile m_file_option
;
4743 OptionGroupBoolean m_current_frame_option
;
4744 OptionGroupBoolean m_current_stack_option
;
4747 #pragma mark CommandObjectTargetSymbols
4749 // CommandObjectTargetSymbols
4751 class CommandObjectTargetSymbols
: public CommandObjectMultiword
{
4753 // Constructors and Destructors
4754 CommandObjectTargetSymbols(CommandInterpreter
&interpreter
)
4755 : CommandObjectMultiword(
4756 interpreter
, "target symbols",
4757 "Commands for adding and managing debug symbol files.",
4758 "target symbols <sub-command> ...") {
4760 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter
)));
4763 ~CommandObjectTargetSymbols() override
= default;
4766 // For CommandObjectTargetModules only
4767 CommandObjectTargetSymbols(const CommandObjectTargetSymbols
&) = delete;
4768 const CommandObjectTargetSymbols
&
4769 operator=(const CommandObjectTargetSymbols
&) = delete;
4772 #pragma mark CommandObjectTargetStopHookAdd
4774 // CommandObjectTargetStopHookAdd
4775 #define LLDB_OPTIONS_target_stop_hook_add
4776 #include "CommandOptions.inc"
4778 class CommandObjectTargetStopHookAdd
: public CommandObjectParsed
,
4779 public IOHandlerDelegateMultiline
{
4781 class CommandOptions
: public OptionGroup
{
4783 CommandOptions() : m_line_end(UINT_MAX
) {}
4785 ~CommandOptions() override
= default;
4787 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
4788 return llvm::ArrayRef(g_target_stop_hook_add_options
);
4791 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
4792 ExecutionContext
*execution_context
) override
{
4794 const int short_option
=
4795 g_target_stop_hook_add_options
[option_idx
].short_option
;
4797 switch (short_option
) {
4799 m_class_name
= std::string(option_arg
);
4800 m_sym_ctx_specified
= true;
4804 if (option_arg
.getAsInteger(0, m_line_end
)) {
4805 error
.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4806 option_arg
.str().c_str());
4809 m_sym_ctx_specified
= true;
4813 bool value
, success
;
4814 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
4816 m_auto_continue
= value
;
4818 error
.SetErrorStringWithFormat(
4819 "invalid boolean value '%s' passed for -G option",
4820 option_arg
.str().c_str());
4823 if (option_arg
.getAsInteger(0, m_line_start
)) {
4824 error
.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4825 option_arg
.str().c_str());
4828 m_sym_ctx_specified
= true;
4832 m_no_inlines
= true;
4836 m_function_name
= std::string(option_arg
);
4837 m_func_name_type_mask
|= eFunctionNameTypeAuto
;
4838 m_sym_ctx_specified
= true;
4842 m_file_name
= std::string(option_arg
);
4843 m_sym_ctx_specified
= true;
4847 m_module_name
= std::string(option_arg
);
4848 m_sym_ctx_specified
= true;
4852 if (option_arg
.getAsInteger(0, m_thread_id
))
4853 error
.SetErrorStringWithFormat("invalid thread id string '%s'",
4854 option_arg
.str().c_str());
4855 m_thread_specified
= true;
4859 m_thread_name
= std::string(option_arg
);
4860 m_thread_specified
= true;
4864 m_queue_name
= std::string(option_arg
);
4865 m_thread_specified
= true;
4869 if (option_arg
.getAsInteger(0, m_thread_index
))
4870 error
.SetErrorStringWithFormat("invalid thread index string '%s'",
4871 option_arg
.str().c_str());
4872 m_thread_specified
= true;
4876 m_use_one_liner
= true;
4877 m_one_liner
.push_back(std::string(option_arg
));
4881 llvm_unreachable("Unimplemented option");
4886 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
4887 m_class_name
.clear();
4888 m_function_name
.clear();
4890 m_line_end
= LLDB_INVALID_LINE_NUMBER
;
4891 m_file_name
.clear();
4892 m_module_name
.clear();
4893 m_func_name_type_mask
= eFunctionNameTypeAuto
;
4894 m_thread_id
= LLDB_INVALID_THREAD_ID
;
4895 m_thread_index
= UINT32_MAX
;
4896 m_thread_name
.clear();
4897 m_queue_name
.clear();
4899 m_no_inlines
= false;
4900 m_sym_ctx_specified
= false;
4901 m_thread_specified
= false;
4903 m_use_one_liner
= false;
4904 m_one_liner
.clear();
4905 m_auto_continue
= false;
4908 std::string m_class_name
;
4909 std::string m_function_name
;
4910 uint32_t m_line_start
= 0;
4911 uint32_t m_line_end
= LLDB_INVALID_LINE_NUMBER
;
4912 std::string m_file_name
;
4913 std::string m_module_name
;
4914 uint32_t m_func_name_type_mask
=
4915 eFunctionNameTypeAuto
; // A pick from lldb::FunctionNameType.
4916 lldb::tid_t m_thread_id
= LLDB_INVALID_THREAD_ID
;
4917 uint32_t m_thread_index
= UINT32_MAX
;
4918 std::string m_thread_name
;
4919 std::string m_queue_name
;
4920 bool m_sym_ctx_specified
= false;
4921 bool m_no_inlines
= false;
4922 bool m_thread_specified
= false;
4923 // Instance variables to hold the values for one_liner options.
4924 bool m_use_one_liner
= false;
4925 std::vector
<std::string
> m_one_liner
;
4927 bool m_auto_continue
= false;
4930 CommandObjectTargetStopHookAdd(CommandInterpreter
&interpreter
)
4931 : CommandObjectParsed(interpreter
, "target stop-hook add",
4932 "Add a hook to be executed when the target stops."
4933 "The hook can either be a list of commands or an "
4934 "appropriately defined Python class. You can also "
4935 "add filters so the hook only runs a certain stop "
4937 "target stop-hook add"),
4938 IOHandlerDelegateMultiline("DONE",
4939 IOHandlerDelegate::Completion::LLDBCommand
),
4940 m_python_class_options("scripted stop-hook", true, 'P') {
4943 Command Based stop-hooks:
4944 -------------------------
4945 Stop hooks can run a list of lldb commands by providing one or more
4946 --one-line-command options. The commands will get run in the order they are
4947 added. Or you can provide no commands, in which case you will enter a
4948 command editor where you can enter the commands to be run.
4950 Python Based Stop Hooks:
4951 ------------------------
4952 Stop hooks can be implemented with a suitably defined Python class, whose name
4953 is passed in the --python-class option.
4955 When the stop hook is added, the class is initialized by calling:
4957 def __init__(self, target, extra_args, internal_dict):
4959 target: The target that the stop hook is being added to.
4960 extra_args: An SBStructuredData Dictionary filled with the -key -value
4961 option pairs passed to the command.
4962 dict: An implementation detail provided by lldb.
4964 Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4965 The method has the signature:
4967 def handle_stop(self, exe_ctx, stream):
4969 exe_ctx: An SBExecutionContext for the thread that has stopped.
4970 stream: An SBStream, anything written to this stream will be printed in the
4971 the stop message when the process stops.
4973 Return Value: The method returns "should_stop
". If should_stop is false
4974 from all the stop hook executions on threads that stopped
4975 with a reason, then the process will continue. Note that this
4976 will happen only after all the stop hooks are run.
4980 Stop hooks can be set to always run, or to only run when the stopped thread
4981 matches the filter options passed on the command line. The available filter
4982 options include a shared library or a thread or queue specification,
4983 a line range in a source file, a function name or a class name.
4985 m_all_options
.Append(&m_python_class_options
,
4986 LLDB_OPT_SET_1
| LLDB_OPT_SET_2
,
4987 LLDB_OPT_SET_FROM_TO(4, 6));
4988 m_all_options
.Append(&m_options
);
4989 m_all_options
.Finalize();
4992 ~CommandObjectTargetStopHookAdd() override
= default;
4994 Options
*GetOptions() override
{ return &m_all_options
; }
4997 void IOHandlerActivated(IOHandler
&io_handler
, bool interactive
) override
{
4998 StreamFileSP
output_sp(io_handler
.GetOutputStreamFileSP());
4999 if (output_sp
&& interactive
) {
5000 output_sp
->PutCString(
5001 "Enter your stop hook command(s). Type 'DONE' to end.\n");
5006 void IOHandlerInputComplete(IOHandler
&io_handler
,
5007 std::string
&line
) override
{
5008 if (m_stop_hook_sp
) {
5010 StreamFileSP
error_sp(io_handler
.GetErrorStreamFileSP());
5012 error_sp
->Printf("error: stop hook #%" PRIu64
5013 " aborted, no commands.\n",
5014 m_stop_hook_sp
->GetID());
5017 Target
*target
= GetDebugger().GetSelectedTarget().get();
5019 target
->UndoCreateStopHook(m_stop_hook_sp
->GetID());
5022 // The IOHandler editor is only for command lines stop hooks:
5023 Target::StopHookCommandLine
*hook_ptr
=
5024 static_cast<Target::StopHookCommandLine
*>(m_stop_hook_sp
.get());
5026 hook_ptr
->SetActionFromString(line
);
5027 StreamFileSP
output_sp(io_handler
.GetOutputStreamFileSP());
5029 output_sp
->Printf("Stop hook #%" PRIu64
" added.\n",
5030 m_stop_hook_sp
->GetID());
5034 m_stop_hook_sp
.reset();
5036 io_handler
.SetIsDone(true);
5039 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5040 m_stop_hook_sp
.reset();
5042 Target
&target
= GetSelectedOrDummyTarget();
5043 Target::StopHookSP new_hook_sp
=
5044 target
.CreateStopHook(m_python_class_options
.GetName().empty() ?
5045 Target::StopHook::StopHookKind::CommandBased
5046 : Target::StopHook::StopHookKind::ScriptBased
);
5048 // First step, make the specifier.
5049 std::unique_ptr
<SymbolContextSpecifier
> specifier_up
;
5050 if (m_options
.m_sym_ctx_specified
) {
5051 specifier_up
= std::make_unique
<SymbolContextSpecifier
>(
5052 GetDebugger().GetSelectedTarget());
5054 if (!m_options
.m_module_name
.empty()) {
5055 specifier_up
->AddSpecification(
5056 m_options
.m_module_name
.c_str(),
5057 SymbolContextSpecifier::eModuleSpecified
);
5060 if (!m_options
.m_class_name
.empty()) {
5061 specifier_up
->AddSpecification(
5062 m_options
.m_class_name
.c_str(),
5063 SymbolContextSpecifier::eClassOrNamespaceSpecified
);
5066 if (!m_options
.m_file_name
.empty()) {
5067 specifier_up
->AddSpecification(m_options
.m_file_name
.c_str(),
5068 SymbolContextSpecifier::eFileSpecified
);
5071 if (m_options
.m_line_start
!= 0) {
5072 specifier_up
->AddLineSpecification(
5073 m_options
.m_line_start
,
5074 SymbolContextSpecifier::eLineStartSpecified
);
5077 if (m_options
.m_line_end
!= UINT_MAX
) {
5078 specifier_up
->AddLineSpecification(
5079 m_options
.m_line_end
, SymbolContextSpecifier::eLineEndSpecified
);
5082 if (!m_options
.m_function_name
.empty()) {
5083 specifier_up
->AddSpecification(
5084 m_options
.m_function_name
.c_str(),
5085 SymbolContextSpecifier::eFunctionSpecified
);
5090 new_hook_sp
->SetSpecifier(specifier_up
.release());
5092 // Next see if any of the thread options have been entered:
5094 if (m_options
.m_thread_specified
) {
5095 ThreadSpec
*thread_spec
= new ThreadSpec();
5097 if (m_options
.m_thread_id
!= LLDB_INVALID_THREAD_ID
) {
5098 thread_spec
->SetTID(m_options
.m_thread_id
);
5101 if (m_options
.m_thread_index
!= UINT32_MAX
)
5102 thread_spec
->SetIndex(m_options
.m_thread_index
);
5104 if (!m_options
.m_thread_name
.empty())
5105 thread_spec
->SetName(m_options
.m_thread_name
.c_str());
5107 if (!m_options
.m_queue_name
.empty())
5108 thread_spec
->SetQueueName(m_options
.m_queue_name
.c_str());
5110 new_hook_sp
->SetThreadSpecifier(thread_spec
);
5113 new_hook_sp
->SetAutoContinue(m_options
.m_auto_continue
);
5114 if (m_options
.m_use_one_liner
) {
5115 // This is a command line stop hook:
5116 Target::StopHookCommandLine
*hook_ptr
=
5117 static_cast<Target::StopHookCommandLine
*>(new_hook_sp
.get());
5118 hook_ptr
->SetActionFromStrings(m_options
.m_one_liner
);
5119 result
.AppendMessageWithFormat("Stop hook #%" PRIu64
" added.\n",
5120 new_hook_sp
->GetID());
5121 } else if (!m_python_class_options
.GetName().empty()) {
5122 // This is a scripted stop hook:
5123 Target::StopHookScripted
*hook_ptr
=
5124 static_cast<Target::StopHookScripted
*>(new_hook_sp
.get());
5125 Status error
= hook_ptr
->SetScriptCallback(
5126 m_python_class_options
.GetName(),
5127 m_python_class_options
.GetStructuredData());
5128 if (error
.Success())
5129 result
.AppendMessageWithFormat("Stop hook #%" PRIu64
" added.\n",
5130 new_hook_sp
->GetID());
5132 // FIXME: Set the stop hook ID counter back.
5133 result
.AppendErrorWithFormat("Couldn't add stop hook: %s",
5135 target
.UndoCreateStopHook(new_hook_sp
->GetID());
5139 m_stop_hook_sp
= new_hook_sp
;
5140 m_interpreter
.GetLLDBCommandsFromIOHandler("> ", // Prompt
5141 *this); // IOHandlerDelegate
5143 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
5147 CommandOptions m_options
;
5148 OptionGroupPythonClassWithDict m_python_class_options
;
5149 OptionGroupOptions m_all_options
;
5151 Target::StopHookSP m_stop_hook_sp
;
5154 #pragma mark CommandObjectTargetStopHookDelete
5156 // CommandObjectTargetStopHookDelete
5158 class CommandObjectTargetStopHookDelete
: public CommandObjectParsed
{
5160 CommandObjectTargetStopHookDelete(CommandInterpreter
&interpreter
)
5161 : CommandObjectParsed(interpreter
, "target stop-hook delete",
5162 "Delete a stop-hook.",
5163 "target stop-hook delete [<idx>]") {
5164 CommandArgumentData hook_arg
{eArgTypeStopHookID
, eArgRepeatStar
};
5165 m_arguments
.push_back({hook_arg
});
5168 ~CommandObjectTargetStopHookDelete() override
= default;
5171 HandleArgumentCompletion(CompletionRequest
&request
,
5172 OptionElementVector
&opt_element_vector
) override
{
5173 if (request
.GetCursorIndex())
5175 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
5176 GetCommandInterpreter(), lldb::eStopHookIDCompletion
, request
, nullptr);
5180 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5181 Target
&target
= GetSelectedOrDummyTarget();
5182 // FIXME: see if we can use the breakpoint id style parser?
5183 size_t num_args
= command
.GetArgumentCount();
5184 if (num_args
== 0) {
5185 if (!m_interpreter
.Confirm("Delete all stop hooks?", true)) {
5186 result
.SetStatus(eReturnStatusFailed
);
5189 target
.RemoveAllStopHooks();
5192 for (size_t i
= 0; i
< num_args
; i
++) {
5193 lldb::user_id_t user_id
;
5194 if (!llvm::to_integer(command
.GetArgumentAtIndex(i
), user_id
)) {
5195 result
.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
5196 command
.GetArgumentAtIndex(i
));
5199 if (!target
.RemoveStopHookByID(user_id
)) {
5200 result
.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
5201 command
.GetArgumentAtIndex(i
));
5206 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
5210 #pragma mark CommandObjectTargetStopHookEnableDisable
5212 // CommandObjectTargetStopHookEnableDisable
5214 class CommandObjectTargetStopHookEnableDisable
: public CommandObjectParsed
{
5216 CommandObjectTargetStopHookEnableDisable(CommandInterpreter
&interpreter
,
5217 bool enable
, const char *name
,
5218 const char *help
, const char *syntax
)
5219 : CommandObjectParsed(interpreter
, name
, help
, syntax
), m_enable(enable
) {
5220 CommandArgumentData hook_arg
{eArgTypeStopHookID
, eArgRepeatStar
};
5221 m_arguments
.push_back({hook_arg
});
5224 ~CommandObjectTargetStopHookEnableDisable() override
= default;
5227 HandleArgumentCompletion(CompletionRequest
&request
,
5228 OptionElementVector
&opt_element_vector
) override
{
5229 if (request
.GetCursorIndex())
5231 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
5232 GetCommandInterpreter(), lldb::eStopHookIDCompletion
, request
, nullptr);
5236 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5237 Target
&target
= GetSelectedOrDummyTarget();
5238 // FIXME: see if we can use the breakpoint id style parser?
5239 size_t num_args
= command
.GetArgumentCount();
5242 if (num_args
== 0) {
5243 target
.SetAllStopHooksActiveState(m_enable
);
5245 for (size_t i
= 0; i
< num_args
; i
++) {
5246 lldb::user_id_t user_id
;
5247 if (!llvm::to_integer(command
.GetArgumentAtIndex(i
), user_id
)) {
5248 result
.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
5249 command
.GetArgumentAtIndex(i
));
5252 success
= target
.SetStopHookActiveStateByID(user_id
, m_enable
);
5254 result
.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
5255 command
.GetArgumentAtIndex(i
));
5260 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
5267 #pragma mark CommandObjectTargetStopHookList
5269 // CommandObjectTargetStopHookList
5271 class CommandObjectTargetStopHookList
: public CommandObjectParsed
{
5273 CommandObjectTargetStopHookList(CommandInterpreter
&interpreter
)
5274 : CommandObjectParsed(interpreter
, "target stop-hook list",
5275 "List all stop-hooks.", "target stop-hook list") {}
5277 ~CommandObjectTargetStopHookList() override
= default;
5280 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5281 Target
&target
= GetSelectedOrDummyTarget();
5283 size_t num_hooks
= target
.GetNumStopHooks();
5284 if (num_hooks
== 0) {
5285 result
.GetOutputStream().PutCString("No stop hooks.\n");
5287 for (size_t i
= 0; i
< num_hooks
; i
++) {
5288 Target::StopHookSP this_hook
= target
.GetStopHookAtIndex(i
);
5290 result
.GetOutputStream().PutCString("\n");
5291 this_hook
->GetDescription(result
.GetOutputStream(),
5292 eDescriptionLevelFull
);
5295 result
.SetStatus(eReturnStatusSuccessFinishResult
);
5299 #pragma mark CommandObjectMultiwordTargetStopHooks
5301 // CommandObjectMultiwordTargetStopHooks
5303 class CommandObjectMultiwordTargetStopHooks
: public CommandObjectMultiword
{
5305 CommandObjectMultiwordTargetStopHooks(CommandInterpreter
&interpreter
)
5306 : CommandObjectMultiword(
5307 interpreter
, "target stop-hook",
5308 "Commands for operating on debugger target stop-hooks.",
5309 "target stop-hook <subcommand> [<subcommand-options>]") {
5310 LoadSubCommand("add", CommandObjectSP(
5311 new CommandObjectTargetStopHookAdd(interpreter
)));
5314 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter
)));
5315 LoadSubCommand("disable",
5316 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5317 interpreter
, false, "target stop-hook disable [<id>]",
5318 "Disable a stop-hook.", "target stop-hook disable")));
5319 LoadSubCommand("enable",
5320 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5321 interpreter
, true, "target stop-hook enable [<id>]",
5322 "Enable a stop-hook.", "target stop-hook enable")));
5323 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
5327 ~CommandObjectMultiwordTargetStopHooks() override
= default;
5330 #pragma mark CommandObjectTargetDumpTypesystem
5332 /// Dumps the TypeSystem of the selected Target.
5333 class CommandObjectTargetDumpTypesystem
: public CommandObjectParsed
{
5335 CommandObjectTargetDumpTypesystem(CommandInterpreter
&interpreter
)
5336 : CommandObjectParsed(
5337 interpreter
, "target dump typesystem",
5338 "Dump the state of the target's internal type system. Intended to "
5339 "be used for debugging LLDB itself.",
5340 nullptr, eCommandRequiresTarget
) {}
5342 ~CommandObjectTargetDumpTypesystem() override
= default;
5345 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5346 // Go over every scratch TypeSystem and dump to the command output.
5347 for (lldb::TypeSystemSP ts
: GetSelectedTarget().GetScratchTypeSystems())
5349 ts
->Dump(result
.GetOutputStream().AsRawOstream());
5351 result
.SetStatus(eReturnStatusSuccessFinishResult
);
5355 #pragma mark CommandObjectTargetDumpSectionLoadList
5357 /// Dumps the SectionLoadList of the selected Target.
5358 class CommandObjectTargetDumpSectionLoadList
: public CommandObjectParsed
{
5360 CommandObjectTargetDumpSectionLoadList(CommandInterpreter
&interpreter
)
5361 : CommandObjectParsed(
5362 interpreter
, "target dump section-load-list",
5363 "Dump the state of the target's internal section load list. "
5364 "Intended to be used for debugging LLDB itself.",
5365 nullptr, eCommandRequiresTarget
) {}
5367 ~CommandObjectTargetDumpSectionLoadList() override
= default;
5370 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
5371 Target
&target
= GetSelectedTarget();
5372 target
.GetSectionLoadList().Dump(result
.GetOutputStream(), &target
);
5373 result
.SetStatus(eReturnStatusSuccessFinishResult
);
5377 #pragma mark CommandObjectTargetDump
5379 /// Multi-word command for 'target dump'.
5380 class CommandObjectTargetDump
: public CommandObjectMultiword
{
5382 // Constructors and Destructors
5383 CommandObjectTargetDump(CommandInterpreter
&interpreter
)
5384 : CommandObjectMultiword(
5385 interpreter
, "target dump",
5386 "Commands for dumping information about the target.",
5387 "target dump [typesystem|section-load-list]") {
5390 CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter
)));
5391 LoadSubCommand("section-load-list",
5392 CommandObjectSP(new CommandObjectTargetDumpSectionLoadList(
5396 ~CommandObjectTargetDump() override
= default;
5399 #pragma mark CommandObjectMultiwordTarget
5401 // CommandObjectMultiwordTarget
5403 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5404 CommandInterpreter
&interpreter
)
5405 : CommandObjectMultiword(interpreter
, "target",
5406 "Commands for operating on debugger targets.",
5407 "target <subcommand> [<subcommand-options>]") {
5408 LoadSubCommand("create",
5409 CommandObjectSP(new CommandObjectTargetCreate(interpreter
)));
5410 LoadSubCommand("delete",
5411 CommandObjectSP(new CommandObjectTargetDelete(interpreter
)));
5412 LoadSubCommand("dump",
5413 CommandObjectSP(new CommandObjectTargetDump(interpreter
)));
5414 LoadSubCommand("list",
5415 CommandObjectSP(new CommandObjectTargetList(interpreter
)));
5416 LoadSubCommand("select",
5417 CommandObjectSP(new CommandObjectTargetSelect(interpreter
)));
5418 LoadSubCommand("show-launch-environment",
5419 CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
5423 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter
)));
5424 LoadSubCommand("modules",
5425 CommandObjectSP(new CommandObjectTargetModules(interpreter
)));
5426 LoadSubCommand("symbols",
5427 CommandObjectSP(new CommandObjectTargetSymbols(interpreter
)));
5428 LoadSubCommand("variable",
5429 CommandObjectSP(new CommandObjectTargetVariable(interpreter
)));
5432 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;