1 //===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===//
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 "CommandObjectThread.h"
11 #include "lldb/Core/ValueObject.h"
12 #include "lldb/Host/OptionParser.h"
13 #include "lldb/Host/StringConvert.h"
14 #include "lldb/Interpreter/CommandInterpreter.h"
15 #include "lldb/Interpreter/CommandReturnObject.h"
16 #include "lldb/Interpreter/OptionArgParser.h"
17 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
18 #include "lldb/Interpreter/Options.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/Function.h"
21 #include "lldb/Symbol/LineEntry.h"
22 #include "lldb/Symbol/LineTable.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/RegisterContext.h"
25 #include "lldb/Target/SystemRuntime.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/Thread.h"
28 #include "lldb/Target/ThreadPlan.h"
29 #include "lldb/Target/ThreadPlanStepInRange.h"
30 #include "lldb/Utility/State.h"
33 using namespace lldb_private
;
35 // CommandObjectIterateOverThreads
37 class CommandObjectIterateOverThreads
: public CommandObjectParsed
{
42 UniqueStack(std::stack
<lldb::addr_t
> stack_frames
, uint32_t thread_index_id
)
43 : m_stack_frames(stack_frames
) {
44 m_thread_index_ids
.push_back(thread_index_id
);
47 void AddThread(uint32_t thread_index_id
) const {
48 m_thread_index_ids
.push_back(thread_index_id
);
51 const std::vector
<uint32_t> &GetUniqueThreadIndexIDs() const {
52 return m_thread_index_ids
;
55 lldb::tid_t
GetRepresentativeThread() const {
56 return m_thread_index_ids
.front();
59 friend bool inline operator<(const UniqueStack
&lhs
,
60 const UniqueStack
&rhs
) {
61 return lhs
.m_stack_frames
< rhs
.m_stack_frames
;
65 // Mark the thread index as mutable, as we don't care about it from a const
66 // perspective, we only care about m_stack_frames so we keep our std::set
68 mutable std::vector
<uint32_t> m_thread_index_ids
;
69 std::stack
<lldb::addr_t
> m_stack_frames
;
73 CommandObjectIterateOverThreads(CommandInterpreter
&interpreter
,
74 const char *name
, const char *help
,
75 const char *syntax
, uint32_t flags
)
76 : CommandObjectParsed(interpreter
, name
, help
, syntax
, flags
) {}
78 ~CommandObjectIterateOverThreads() override
= default;
80 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
81 result
.SetStatus(m_success_return
);
83 bool all_threads
= false;
84 if (command
.GetArgumentCount() == 0) {
85 Thread
*thread
= m_exe_ctx
.GetThreadPtr();
86 if (!thread
|| !HandleOneThread(thread
->GetID(), result
))
88 return result
.Succeeded();
89 } else if (command
.GetArgumentCount() == 1) {
90 all_threads
= ::strcmp(command
.GetArgumentAtIndex(0), "all") == 0;
91 m_unique_stacks
= ::strcmp(command
.GetArgumentAtIndex(0), "unique") == 0;
94 // Use tids instead of ThreadSPs to prevent deadlocking problems which
95 // result from JIT-ing code while iterating over the (locked) ThreadSP
97 std::vector
<lldb::tid_t
> tids
;
99 if (all_threads
|| m_unique_stacks
) {
100 Process
*process
= m_exe_ctx
.GetProcessPtr();
102 for (ThreadSP thread_sp
: process
->Threads())
103 tids
.push_back(thread_sp
->GetID());
105 const size_t num_args
= command
.GetArgumentCount();
106 Process
*process
= m_exe_ctx
.GetProcessPtr();
108 std::lock_guard
<std::recursive_mutex
> guard(
109 process
->GetThreadList().GetMutex());
111 for (size_t i
= 0; i
< num_args
; i
++) {
114 uint32_t thread_idx
= StringConvert::ToUInt32(
115 command
.GetArgumentAtIndex(i
), 0, 0, &success
);
117 result
.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
118 command
.GetArgumentAtIndex(i
));
119 result
.SetStatus(eReturnStatusFailed
);
124 process
->GetThreadList().FindThreadByIndexID(thread_idx
);
127 result
.AppendErrorWithFormat("no thread with index: \"%s\"\n",
128 command
.GetArgumentAtIndex(i
));
129 result
.SetStatus(eReturnStatusFailed
);
133 tids
.push_back(thread
->GetID());
137 if (m_unique_stacks
) {
138 // Iterate over threads, finding unique stack buckets.
139 std::set
<UniqueStack
> unique_stacks
;
140 for (const lldb::tid_t
&tid
: tids
) {
141 if (!BucketThread(tid
, unique_stacks
, result
)) {
146 // Write the thread id's and unique call stacks to the output stream
147 Stream
&strm
= result
.GetOutputStream();
148 Process
*process
= m_exe_ctx
.GetProcessPtr();
149 for (const UniqueStack
&stack
: unique_stacks
) {
150 // List the common thread ID's
151 const std::vector
<uint32_t> &thread_index_ids
=
152 stack
.GetUniqueThreadIndexIDs();
153 strm
.Format("{0} thread(s) ", thread_index_ids
.size());
154 for (const uint32_t &thread_index_id
: thread_index_ids
) {
155 strm
.Format("#{0} ", thread_index_id
);
159 // List the shared call stack for this set of threads
160 uint32_t representative_thread_id
= stack
.GetRepresentativeThread();
161 ThreadSP thread
= process
->GetThreadList().FindThreadByIndexID(
162 representative_thread_id
);
163 if (!HandleOneThread(thread
->GetID(), result
)) {
169 for (const lldb::tid_t
&tid
: tids
) {
170 if (idx
!= 0 && m_add_return
)
171 result
.AppendMessage("");
173 if (!HandleOneThread(tid
, result
))
179 return result
.Succeeded();
183 // Override this to do whatever you need to do for one thread.
185 // If you return false, the iteration will stop, otherwise it will proceed.
186 // The result is set to m_success_return (defaults to
187 // eReturnStatusSuccessFinishResult) before the iteration, so you only need
188 // to set the return status in HandleOneThread if you want to indicate an
189 // error. If m_add_return is true, a blank line will be inserted between each
190 // of the listings (except the last one.)
192 virtual bool HandleOneThread(lldb::tid_t
, CommandReturnObject
&result
) = 0;
194 bool BucketThread(lldb::tid_t tid
, std::set
<UniqueStack
> &unique_stacks
,
195 CommandReturnObject
&result
) {
196 // Grab the corresponding thread for the given thread id.
197 Process
*process
= m_exe_ctx
.GetProcessPtr();
198 Thread
*thread
= process
->GetThreadList().FindThreadByID(tid
).get();
199 if (thread
== nullptr) {
200 result
.AppendErrorWithFormatv("Failed to process thread #{0}.\n", tid
);
201 result
.SetStatus(eReturnStatusFailed
);
205 // Collect the each frame's address for this call-stack
206 std::stack
<lldb::addr_t
> stack_frames
;
207 const uint32_t frame_count
= thread
->GetStackFrameCount();
208 for (uint32_t frame_index
= 0; frame_index
< frame_count
; frame_index
++) {
209 const lldb::StackFrameSP frame_sp
=
210 thread
->GetStackFrameAtIndex(frame_index
);
211 const lldb::addr_t pc
= frame_sp
->GetStackID().GetPC();
212 stack_frames
.push(pc
);
215 uint32_t thread_index_id
= thread
->GetIndexID();
216 UniqueStack
new_unique_stack(stack_frames
, thread_index_id
);
218 // Try to match the threads stack to and existing entry.
219 std::set
<UniqueStack
>::iterator matching_stack
=
220 unique_stacks
.find(new_unique_stack
);
221 if (matching_stack
!= unique_stacks
.end()) {
222 matching_stack
->AddThread(thread_index_id
);
224 unique_stacks
.insert(new_unique_stack
);
229 ReturnStatus m_success_return
= eReturnStatusSuccessFinishResult
;
230 bool m_unique_stacks
= false;
231 bool m_add_return
= true;
234 // CommandObjectThreadBacktrace
235 #define LLDB_OPTIONS_thread_backtrace
236 #include "CommandOptions.inc"
238 class CommandObjectThreadBacktrace
: public CommandObjectIterateOverThreads
{
240 class CommandOptions
: public Options
{
242 CommandOptions() : Options() {
243 // Keep default values of all options in one place: OptionParsingStarting
245 OptionParsingStarting(nullptr);
248 ~CommandOptions() override
= default;
250 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
251 ExecutionContext
*execution_context
) override
{
253 const int short_option
= m_getopt_table
[option_idx
].val
;
255 switch (short_option
) {
257 int32_t input_count
= 0;
258 if (option_arg
.getAsInteger(0, m_count
)) {
259 m_count
= UINT32_MAX
;
260 error
.SetErrorStringWithFormat(
261 "invalid integer value for option '%c'", short_option
);
262 } else if (input_count
< 0)
263 m_count
= UINT32_MAX
;
266 if (option_arg
.getAsInteger(0, m_start
))
267 error
.SetErrorStringWithFormat(
268 "invalid integer value for option '%c'", short_option
);
272 m_extended_backtrace
=
273 OptionArgParser::ToBoolean(option_arg
, false, &success
);
275 error
.SetErrorStringWithFormat(
276 "invalid boolean value for option '%c'", short_option
);
279 llvm_unreachable("Unimplemented option");
284 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
285 m_count
= UINT32_MAX
;
287 m_extended_backtrace
= false;
290 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
291 return llvm::makeArrayRef(g_thread_backtrace_options
);
294 // Instance variables to hold the values for command options.
297 bool m_extended_backtrace
;
300 CommandObjectThreadBacktrace(CommandInterpreter
&interpreter
)
301 : CommandObjectIterateOverThreads(
302 interpreter
, "thread backtrace",
303 "Show thread call stacks. Defaults to the current thread, thread "
304 "indexes can be specified as arguments.\n"
305 "Use the thread-index \"all\" to see all threads.\n"
306 "Use the thread-index \"unique\" to see threads grouped by unique "
308 "Use 'settings set frame-format' to customize the printing of "
309 "frames in the backtrace and 'settings set thread-format' to "
310 "customize the thread header.",
312 eCommandRequiresProcess
| eCommandRequiresThread
|
313 eCommandTryTargetAPILock
| eCommandProcessMustBeLaunched
|
314 eCommandProcessMustBePaused
),
317 ~CommandObjectThreadBacktrace() override
= default;
319 Options
*GetOptions() override
{ return &m_options
; }
322 void DoExtendedBacktrace(Thread
*thread
, CommandReturnObject
&result
) {
323 SystemRuntime
*runtime
= thread
->GetProcess()->GetSystemRuntime();
325 Stream
&strm
= result
.GetOutputStream();
326 const std::vector
<ConstString
> &types
=
327 runtime
->GetExtendedBacktraceTypes();
328 for (auto type
: types
) {
329 ThreadSP ext_thread_sp
= runtime
->GetExtendedBacktraceThread(
330 thread
->shared_from_this(), type
);
331 if (ext_thread_sp
&& ext_thread_sp
->IsValid()) {
332 const uint32_t num_frames_with_source
= 0;
333 const bool stop_format
= false;
334 if (ext_thread_sp
->GetStatus(strm
, m_options
.m_start
,
336 num_frames_with_source
, stop_format
)) {
337 DoExtendedBacktrace(ext_thread_sp
.get(), result
);
344 bool HandleOneThread(lldb::tid_t tid
, CommandReturnObject
&result
) override
{
346 m_exe_ctx
.GetProcessPtr()->GetThreadList().FindThreadByID(tid
);
348 result
.AppendErrorWithFormat(
349 "thread disappeared while computing backtraces: 0x%" PRIx64
"\n",
351 result
.SetStatus(eReturnStatusFailed
);
355 Thread
*thread
= thread_sp
.get();
357 Stream
&strm
= result
.GetOutputStream();
359 // Only dump stack info if we processing unique stacks.
360 const bool only_stacks
= m_unique_stacks
;
362 // Don't show source context when doing backtraces.
363 const uint32_t num_frames_with_source
= 0;
364 const bool stop_format
= true;
365 if (!thread
->GetStatus(strm
, m_options
.m_start
, m_options
.m_count
,
366 num_frames_with_source
, stop_format
, only_stacks
)) {
367 result
.AppendErrorWithFormat(
368 "error displaying backtrace for thread: \"0x%4.4x\"\n",
369 thread
->GetIndexID());
370 result
.SetStatus(eReturnStatusFailed
);
373 if (m_options
.m_extended_backtrace
) {
374 DoExtendedBacktrace(thread
, result
);
380 CommandOptions m_options
;
383 enum StepScope
{ eStepScopeSource
, eStepScopeInstruction
};
385 static constexpr OptionEnumValueElement g_tri_running_mode
[] = {
386 {eOnlyThisThread
, "this-thread", "Run only this thread"},
387 {eAllThreads
, "all-threads", "Run all threads"},
388 {eOnlyDuringStepping
, "while-stepping",
389 "Run only this thread while stepping"}};
391 static constexpr OptionEnumValues
TriRunningModes() {
392 return OptionEnumValues(g_tri_running_mode
);
395 #define LLDB_OPTIONS_thread_step_scope
396 #include "CommandOptions.inc"
398 class ThreadStepScopeOptionGroup
: public OptionGroup
{
400 ThreadStepScopeOptionGroup() : OptionGroup() {
401 // Keep default values of all options in one place: OptionParsingStarting
403 OptionParsingStarting(nullptr);
406 ~ThreadStepScopeOptionGroup() override
= default;
408 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
409 return llvm::makeArrayRef(g_thread_step_scope_options
);
412 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
413 ExecutionContext
*execution_context
) override
{
415 const int short_option
=
416 g_thread_step_scope_options
[option_idx
].short_option
;
418 switch (short_option
) {
421 bool avoid_no_debug
=
422 OptionArgParser::ToBoolean(option_arg
, true, &success
);
424 error
.SetErrorStringWithFormat("invalid boolean value for option '%c'",
427 m_step_in_avoid_no_debug
= avoid_no_debug
? eLazyBoolYes
: eLazyBoolNo
;
433 bool avoid_no_debug
=
434 OptionArgParser::ToBoolean(option_arg
, true, &success
);
436 error
.SetErrorStringWithFormat("invalid boolean value for option '%c'",
439 m_step_out_avoid_no_debug
= avoid_no_debug
? eLazyBoolYes
: eLazyBoolNo
;
444 if (option_arg
.getAsInteger(0, m_step_count
))
445 error
.SetErrorStringWithFormat("invalid step count '%s'",
446 option_arg
.str().c_str());
450 auto enum_values
= GetDefinitions()[option_idx
].enum_values
;
451 m_run_mode
= (lldb::RunMode
)OptionArgParser::ToOptionEnum(
452 option_arg
, enum_values
, eOnlyDuringStepping
, error
);
456 if (option_arg
== "block") {
457 m_end_line_is_block_end
= true;
460 if (option_arg
.getAsInteger(0, m_end_line
))
461 error
.SetErrorStringWithFormat("invalid end line number '%s'",
462 option_arg
.str().c_str());
466 m_avoid_regexp
.clear();
467 m_avoid_regexp
.assign(option_arg
);
471 m_step_in_target
.clear();
472 m_step_in_target
.assign(option_arg
);
476 llvm_unreachable("Unimplemented option");
481 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
482 m_step_in_avoid_no_debug
= eLazyBoolCalculate
;
483 m_step_out_avoid_no_debug
= eLazyBoolCalculate
;
484 m_run_mode
= eOnlyDuringStepping
;
486 // Check if we are in Non-Stop mode
488 execution_context
? execution_context
->GetTargetSP() : TargetSP();
489 if (target_sp
&& target_sp
->GetNonStopModeEnabled())
490 m_run_mode
= eOnlyThisThread
;
492 m_avoid_regexp
.clear();
493 m_step_in_target
.clear();
495 m_end_line
= LLDB_INVALID_LINE_NUMBER
;
496 m_end_line_is_block_end
= false;
499 // Instance variables to hold the values for command options.
500 LazyBool m_step_in_avoid_no_debug
;
501 LazyBool m_step_out_avoid_no_debug
;
503 std::string m_avoid_regexp
;
504 std::string m_step_in_target
;
505 uint32_t m_step_count
;
507 bool m_end_line_is_block_end
;
510 class CommandObjectThreadStepWithTypeAndScope
: public CommandObjectParsed
{
512 CommandObjectThreadStepWithTypeAndScope(CommandInterpreter
&interpreter
,
513 const char *name
, const char *help
,
516 StepScope step_scope
)
517 : CommandObjectParsed(interpreter
, name
, help
, syntax
,
518 eCommandRequiresProcess
| eCommandRequiresThread
|
519 eCommandTryTargetAPILock
|
520 eCommandProcessMustBeLaunched
|
521 eCommandProcessMustBePaused
),
522 m_step_type(step_type
), m_step_scope(step_scope
), m_options(),
523 m_class_options("scripted step") {
524 CommandArgumentEntry arg
;
525 CommandArgumentData thread_id_arg
;
527 // Define the first (and only) variant of this arg.
528 thread_id_arg
.arg_type
= eArgTypeThreadID
;
529 thread_id_arg
.arg_repetition
= eArgRepeatOptional
;
531 // There is only one variant this argument could be; put it into the
533 arg
.push_back(thread_id_arg
);
535 // Push the data for the first argument into the m_arguments vector.
536 m_arguments
.push_back(arg
);
538 if (step_type
== eStepTypeScripted
) {
539 m_all_options
.Append(&m_class_options
, LLDB_OPT_SET_1
| LLDB_OPT_SET_2
,
542 m_all_options
.Append(&m_options
);
543 m_all_options
.Finalize();
546 ~CommandObjectThreadStepWithTypeAndScope() override
= default;
548 Options
*GetOptions() override
{ return &m_all_options
; }
551 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
552 Process
*process
= m_exe_ctx
.GetProcessPtr();
553 bool synchronous_execution
= m_interpreter
.GetSynchronous();
555 const uint32_t num_threads
= process
->GetThreadList().GetSize();
556 Thread
*thread
= nullptr;
558 if (command
.GetArgumentCount() == 0) {
559 thread
= GetDefaultThread();
561 if (thread
== nullptr) {
562 result
.AppendError("no selected thread in process");
563 result
.SetStatus(eReturnStatusFailed
);
567 const char *thread_idx_cstr
= command
.GetArgumentAtIndex(0);
568 uint32_t step_thread_idx
=
569 StringConvert::ToUInt32(thread_idx_cstr
, LLDB_INVALID_INDEX32
);
570 if (step_thread_idx
== LLDB_INVALID_INDEX32
) {
571 result
.AppendErrorWithFormat("invalid thread index '%s'.\n",
573 result
.SetStatus(eReturnStatusFailed
);
577 process
->GetThreadList().FindThreadByIndexID(step_thread_idx
).get();
578 if (thread
== nullptr) {
579 result
.AppendErrorWithFormat(
580 "Thread index %u is out of range (valid values are 0 - %u).\n",
581 step_thread_idx
, num_threads
);
582 result
.SetStatus(eReturnStatusFailed
);
587 if (m_step_type
== eStepTypeScripted
) {
588 if (m_class_options
.GetName().empty()) {
589 result
.AppendErrorWithFormat("empty class name for scripted step.");
590 result
.SetStatus(eReturnStatusFailed
);
592 } else if (!GetDebugger().GetScriptInterpreter()->CheckObjectExists(
593 m_class_options
.GetName().c_str())) {
594 result
.AppendErrorWithFormat(
595 "class for scripted step: \"%s\" does not exist.",
596 m_class_options
.GetName().c_str());
597 result
.SetStatus(eReturnStatusFailed
);
602 if (m_options
.m_end_line
!= LLDB_INVALID_LINE_NUMBER
&&
603 m_step_type
!= eStepTypeInto
) {
604 result
.AppendErrorWithFormat(
605 "end line option is only valid for step into");
606 result
.SetStatus(eReturnStatusFailed
);
610 const bool abort_other_plans
= false;
611 const lldb::RunMode stop_other_threads
= m_options
.m_run_mode
;
613 // This is a bit unfortunate, but not all the commands in this command
614 // object support only while stepping, so I use the bool for them.
615 bool bool_stop_other_threads
;
616 if (m_options
.m_run_mode
== eAllThreads
)
617 bool_stop_other_threads
= false;
618 else if (m_options
.m_run_mode
== eOnlyDuringStepping
)
619 bool_stop_other_threads
=
620 (m_step_type
!= eStepTypeOut
&& m_step_type
!= eStepTypeScripted
);
622 bool_stop_other_threads
= true;
624 ThreadPlanSP new_plan_sp
;
625 Status new_plan_status
;
627 if (m_step_type
== eStepTypeInto
) {
628 StackFrame
*frame
= thread
->GetStackFrameAtIndex(0).get();
629 assert(frame
!= nullptr);
631 if (frame
->HasDebugInformation()) {
633 SymbolContext sc
= frame
->GetSymbolContext(eSymbolContextEverything
);
634 if (m_options
.m_end_line
!= LLDB_INVALID_LINE_NUMBER
) {
636 if (!sc
.GetAddressRangeFromHereToEndLine(m_options
.m_end_line
, range
,
638 result
.AppendErrorWithFormat("invalid end-line option: %s.",
640 result
.SetStatus(eReturnStatusFailed
);
643 } else if (m_options
.m_end_line_is_block_end
) {
645 Block
*block
= frame
->GetSymbolContext(eSymbolContextBlock
).block
;
647 result
.AppendErrorWithFormat("Could not find the current block.");
648 result
.SetStatus(eReturnStatusFailed
);
652 AddressRange block_range
;
653 Address pc_address
= frame
->GetFrameCodeAddress();
654 block
->GetRangeContainingAddress(pc_address
, block_range
);
655 if (!block_range
.GetBaseAddress().IsValid()) {
656 result
.AppendErrorWithFormat(
657 "Could not find the current block address.");
658 result
.SetStatus(eReturnStatusFailed
);
661 lldb::addr_t pc_offset_in_block
=
662 pc_address
.GetFileAddress() -
663 block_range
.GetBaseAddress().GetFileAddress();
664 lldb::addr_t range_length
=
665 block_range
.GetByteSize() - pc_offset_in_block
;
666 range
= AddressRange(pc_address
, range_length
);
668 range
= sc
.line_entry
.range
;
671 new_plan_sp
= thread
->QueueThreadPlanForStepInRange(
672 abort_other_plans
, range
,
673 frame
->GetSymbolContext(eSymbolContextEverything
),
674 m_options
.m_step_in_target
.c_str(), stop_other_threads
,
675 new_plan_status
, m_options
.m_step_in_avoid_no_debug
,
676 m_options
.m_step_out_avoid_no_debug
);
678 if (new_plan_sp
&& !m_options
.m_avoid_regexp
.empty()) {
679 ThreadPlanStepInRange
*step_in_range_plan
=
680 static_cast<ThreadPlanStepInRange
*>(new_plan_sp
.get());
681 step_in_range_plan
->SetAvoidRegexp(m_options
.m_avoid_regexp
.c_str());
684 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
685 false, abort_other_plans
, bool_stop_other_threads
, new_plan_status
);
686 } else if (m_step_type
== eStepTypeOver
) {
687 StackFrame
*frame
= thread
->GetStackFrameAtIndex(0).get();
689 if (frame
->HasDebugInformation())
690 new_plan_sp
= thread
->QueueThreadPlanForStepOverRange(
692 frame
->GetSymbolContext(eSymbolContextEverything
).line_entry
,
693 frame
->GetSymbolContext(eSymbolContextEverything
),
694 stop_other_threads
, new_plan_status
,
695 m_options
.m_step_out_avoid_no_debug
);
697 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
698 true, abort_other_plans
, bool_stop_other_threads
, new_plan_status
);
699 } else if (m_step_type
== eStepTypeTrace
) {
700 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
701 false, abort_other_plans
, bool_stop_other_threads
, new_plan_status
);
702 } else if (m_step_type
== eStepTypeTraceOver
) {
703 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
704 true, abort_other_plans
, bool_stop_other_threads
, new_plan_status
);
705 } else if (m_step_type
== eStepTypeOut
) {
706 new_plan_sp
= thread
->QueueThreadPlanForStepOut(
707 abort_other_plans
, nullptr, false, bool_stop_other_threads
, eVoteYes
,
708 eVoteNoOpinion
, thread
->GetSelectedFrameIndex(), new_plan_status
,
709 m_options
.m_step_out_avoid_no_debug
);
710 } else if (m_step_type
== eStepTypeScripted
) {
711 new_plan_sp
= thread
->QueueThreadPlanForStepScripted(
712 abort_other_plans
, m_class_options
.GetName().c_str(),
713 m_class_options
.GetStructuredData(), bool_stop_other_threads
,
716 result
.AppendError("step type is not supported");
717 result
.SetStatus(eReturnStatusFailed
);
721 // If we got a new plan, then set it to be a master plan (User level Plans
722 // should be master plans so that they can be interruptible). Then resume
726 new_plan_sp
->SetIsMasterPlan(true);
727 new_plan_sp
->SetOkayToDiscard(false);
729 if (m_options
.m_step_count
> 1) {
730 if (!new_plan_sp
->SetIterationCount(m_options
.m_step_count
)) {
731 result
.AppendWarning(
732 "step operation does not support iteration count.");
736 process
->GetThreadList().SetSelectedThreadByID(thread
->GetID());
738 const uint32_t iohandler_id
= process
->GetIOHandlerID();
742 if (synchronous_execution
)
743 error
= process
->ResumeSynchronous(&stream
);
745 error
= process
->Resume();
747 if (!error
.Success()) {
748 result
.AppendMessage(error
.AsCString());
749 result
.SetStatus(eReturnStatusFailed
);
753 // There is a race condition where this thread will return up the call
754 // stack to the main command handler and show an (lldb) prompt before
755 // HandlePrivateEvent (from PrivateStateThread) has a chance to call
756 // PushProcessIOHandler().
757 process
->SyncIOHandler(iohandler_id
, std::chrono::seconds(2));
759 if (synchronous_execution
) {
760 // If any state changed events had anything to say, add that to the
762 if (stream
.GetSize() > 0)
763 result
.AppendMessage(stream
.GetString());
765 process
->GetThreadList().SetSelectedThreadByID(thread
->GetID());
766 result
.SetDidChangeProcessState(true);
767 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
769 result
.SetStatus(eReturnStatusSuccessContinuingNoResult
);
772 result
.SetError(new_plan_status
);
773 result
.SetStatus(eReturnStatusFailed
);
775 return result
.Succeeded();
779 StepType m_step_type
;
780 StepScope m_step_scope
;
781 ThreadStepScopeOptionGroup m_options
;
782 OptionGroupPythonClassWithDict m_class_options
;
783 OptionGroupOptions m_all_options
;
786 // CommandObjectThreadContinue
788 class CommandObjectThreadContinue
: public CommandObjectParsed
{
790 CommandObjectThreadContinue(CommandInterpreter
&interpreter
)
791 : CommandObjectParsed(
792 interpreter
, "thread continue",
793 "Continue execution of the current target process. One "
794 "or more threads may be specified, by default all "
797 eCommandRequiresThread
| eCommandTryTargetAPILock
|
798 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
) {
799 CommandArgumentEntry arg
;
800 CommandArgumentData thread_idx_arg
;
802 // Define the first (and only) variant of this arg.
803 thread_idx_arg
.arg_type
= eArgTypeThreadIndex
;
804 thread_idx_arg
.arg_repetition
= eArgRepeatPlus
;
806 // There is only one variant this argument could be; put it into the
808 arg
.push_back(thread_idx_arg
);
810 // Push the data for the first argument into the m_arguments vector.
811 m_arguments
.push_back(arg
);
814 ~CommandObjectThreadContinue() override
= default;
816 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
817 bool synchronous_execution
= m_interpreter
.GetSynchronous();
819 Process
*process
= m_exe_ctx
.GetProcessPtr();
820 if (process
== nullptr) {
821 result
.AppendError("no process exists. Cannot continue");
822 result
.SetStatus(eReturnStatusFailed
);
826 StateType state
= process
->GetState();
827 if ((state
== eStateCrashed
) || (state
== eStateStopped
) ||
828 (state
== eStateSuspended
)) {
829 const size_t argc
= command
.GetArgumentCount();
831 // These two lines appear at the beginning of both blocks in this
832 // if..else, but that is because we need to release the lock before
833 // calling process->Resume below.
834 std::lock_guard
<std::recursive_mutex
> guard(
835 process
->GetThreadList().GetMutex());
836 const uint32_t num_threads
= process
->GetThreadList().GetSize();
837 std::vector
<Thread
*> resume_threads
;
838 for (auto &entry
: command
.entries()) {
840 if (entry
.ref().getAsInteger(0, thread_idx
)) {
841 result
.AppendErrorWithFormat(
842 "invalid thread index argument: \"%s\".\n", entry
.c_str());
843 result
.SetStatus(eReturnStatusFailed
);
847 process
->GetThreadList().FindThreadByIndexID(thread_idx
).get();
850 resume_threads
.push_back(thread
);
852 result
.AppendErrorWithFormat("invalid thread index %u.\n",
854 result
.SetStatus(eReturnStatusFailed
);
859 if (resume_threads
.empty()) {
860 result
.AppendError("no valid thread indexes were specified");
861 result
.SetStatus(eReturnStatusFailed
);
864 if (resume_threads
.size() == 1)
865 result
.AppendMessageWithFormat("Resuming thread: ");
867 result
.AppendMessageWithFormat("Resuming threads: ");
869 for (uint32_t idx
= 0; idx
< num_threads
; ++idx
) {
871 process
->GetThreadList().GetThreadAtIndex(idx
).get();
872 std::vector
<Thread
*>::iterator this_thread_pos
=
873 find(resume_threads
.begin(), resume_threads
.end(), thread
);
875 if (this_thread_pos
!= resume_threads
.end()) {
876 resume_threads
.erase(this_thread_pos
);
877 if (!resume_threads
.empty())
878 result
.AppendMessageWithFormat("%u, ", thread
->GetIndexID());
880 result
.AppendMessageWithFormat("%u ", thread
->GetIndexID());
882 const bool override_suspend
= true;
883 thread
->SetResumeState(eStateRunning
, override_suspend
);
885 thread
->SetResumeState(eStateSuspended
);
888 result
.AppendMessageWithFormat("in process %" PRIu64
"\n",
892 // These two lines appear at the beginning of both blocks in this
893 // if..else, but that is because we need to release the lock before
894 // calling process->Resume below.
895 std::lock_guard
<std::recursive_mutex
> guard(
896 process
->GetThreadList().GetMutex());
897 const uint32_t num_threads
= process
->GetThreadList().GetSize();
898 Thread
*current_thread
= GetDefaultThread();
899 if (current_thread
== nullptr) {
900 result
.AppendError("the process doesn't have a current thread");
901 result
.SetStatus(eReturnStatusFailed
);
904 // Set the actions that the threads should each take when resuming
905 for (uint32_t idx
= 0; idx
< num_threads
; ++idx
) {
906 Thread
*thread
= process
->GetThreadList().GetThreadAtIndex(idx
).get();
907 if (thread
== current_thread
) {
908 result
.AppendMessageWithFormat("Resuming thread 0x%4.4" PRIx64
909 " in process %" PRIu64
"\n",
910 thread
->GetID(), process
->GetID());
911 const bool override_suspend
= true;
912 thread
->SetResumeState(eStateRunning
, override_suspend
);
914 thread
->SetResumeState(eStateSuspended
);
921 if (synchronous_execution
)
922 error
= process
->ResumeSynchronous(&stream
);
924 error
= process
->Resume();
926 // We should not be holding the thread list lock when we do this.
927 if (error
.Success()) {
928 result
.AppendMessageWithFormat("Process %" PRIu64
" resuming\n",
930 if (synchronous_execution
) {
931 // If any state changed events had anything to say, add that to the
933 if (stream
.GetSize() > 0)
934 result
.AppendMessage(stream
.GetString());
936 result
.SetDidChangeProcessState(true);
937 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
939 result
.SetStatus(eReturnStatusSuccessContinuingNoResult
);
942 result
.AppendErrorWithFormat("Failed to resume process: %s\n",
944 result
.SetStatus(eReturnStatusFailed
);
947 result
.AppendErrorWithFormat(
948 "Process cannot be continued from its current state (%s).\n",
949 StateAsCString(state
));
950 result
.SetStatus(eReturnStatusFailed
);
953 return result
.Succeeded();
957 // CommandObjectThreadUntil
959 static constexpr OptionEnumValueElement g_duo_running_mode
[] = {
960 {eOnlyThisThread
, "this-thread", "Run only this thread"},
961 {eAllThreads
, "all-threads", "Run all threads"}};
963 static constexpr OptionEnumValues
DuoRunningModes() {
964 return OptionEnumValues(g_duo_running_mode
);
967 #define LLDB_OPTIONS_thread_until
968 #include "CommandOptions.inc"
970 class CommandObjectThreadUntil
: public CommandObjectParsed
{
972 class CommandOptions
: public Options
{
974 uint32_t m_thread_idx
;
975 uint32_t m_frame_idx
;
978 : Options(), m_thread_idx(LLDB_INVALID_THREAD_ID
),
979 m_frame_idx(LLDB_INVALID_FRAME_ID
) {
980 // Keep default values of all options in one place: OptionParsingStarting
982 OptionParsingStarting(nullptr);
985 ~CommandOptions() override
= default;
987 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
988 ExecutionContext
*execution_context
) override
{
990 const int short_option
= m_getopt_table
[option_idx
].val
;
992 switch (short_option
) {
994 lldb::addr_t tmp_addr
= OptionArgParser::ToAddress(
995 execution_context
, option_arg
, LLDB_INVALID_ADDRESS
, &error
);
997 m_until_addrs
.push_back(tmp_addr
);
1000 if (option_arg
.getAsInteger(0, m_thread_idx
)) {
1001 m_thread_idx
= LLDB_INVALID_INDEX32
;
1002 error
.SetErrorStringWithFormat("invalid thread index '%s'",
1003 option_arg
.str().c_str());
1007 if (option_arg
.getAsInteger(0, m_frame_idx
)) {
1008 m_frame_idx
= LLDB_INVALID_FRAME_ID
;
1009 error
.SetErrorStringWithFormat("invalid frame index '%s'",
1010 option_arg
.str().c_str());
1014 auto enum_values
= GetDefinitions()[option_idx
].enum_values
;
1015 lldb::RunMode run_mode
= (lldb::RunMode
)OptionArgParser::ToOptionEnum(
1016 option_arg
, enum_values
, eOnlyDuringStepping
, error
);
1018 if (error
.Success()) {
1019 if (run_mode
== eAllThreads
)
1020 m_stop_others
= false;
1022 m_stop_others
= true;
1026 llvm_unreachable("Unimplemented option");
1031 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1032 m_thread_idx
= LLDB_INVALID_THREAD_ID
;
1034 m_stop_others
= false;
1035 m_until_addrs
.clear();
1038 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1039 return llvm::makeArrayRef(g_thread_until_options
);
1042 uint32_t m_step_thread_idx
;
1044 std::vector
<lldb::addr_t
> m_until_addrs
;
1046 // Instance variables to hold the values for command options.
1049 CommandObjectThreadUntil(CommandInterpreter
&interpreter
)
1050 : CommandObjectParsed(
1051 interpreter
, "thread until",
1052 "Continue until a line number or address is reached by the "
1053 "current or specified thread. Stops when returning from "
1054 "the current function as a safety measure. "
1055 "The target line number(s) are given as arguments, and if more "
1057 " is provided, stepping will stop when the first one is hit.",
1059 eCommandRequiresThread
| eCommandTryTargetAPILock
|
1060 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
),
1062 CommandArgumentEntry arg
;
1063 CommandArgumentData line_num_arg
;
1065 // Define the first (and only) variant of this arg.
1066 line_num_arg
.arg_type
= eArgTypeLineNum
;
1067 line_num_arg
.arg_repetition
= eArgRepeatPlain
;
1069 // There is only one variant this argument could be; put it into the
1071 arg
.push_back(line_num_arg
);
1073 // Push the data for the first argument into the m_arguments vector.
1074 m_arguments
.push_back(arg
);
1077 ~CommandObjectThreadUntil() override
= default;
1079 Options
*GetOptions() override
{ return &m_options
; }
1082 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1083 bool synchronous_execution
= m_interpreter
.GetSynchronous();
1085 Target
*target
= &GetSelectedTarget();
1087 Process
*process
= m_exe_ctx
.GetProcessPtr();
1088 if (process
== nullptr) {
1089 result
.AppendError("need a valid process to step");
1090 result
.SetStatus(eReturnStatusFailed
);
1092 Thread
*thread
= nullptr;
1093 std::vector
<uint32_t> line_numbers
;
1095 if (command
.GetArgumentCount() >= 1) {
1096 size_t num_args
= command
.GetArgumentCount();
1097 for (size_t i
= 0; i
< num_args
; i
++) {
1098 uint32_t line_number
;
1099 line_number
= StringConvert::ToUInt32(command
.GetArgumentAtIndex(i
),
1101 if (line_number
== UINT32_MAX
) {
1102 result
.AppendErrorWithFormat("invalid line number: '%s'.\n",
1103 command
.GetArgumentAtIndex(i
));
1104 result
.SetStatus(eReturnStatusFailed
);
1107 line_numbers
.push_back(line_number
);
1109 } else if (m_options
.m_until_addrs
.empty()) {
1110 result
.AppendErrorWithFormat("No line number or address provided:\n%s",
1111 GetSyntax().str().c_str());
1112 result
.SetStatus(eReturnStatusFailed
);
1116 if (m_options
.m_thread_idx
== LLDB_INVALID_THREAD_ID
) {
1117 thread
= GetDefaultThread();
1119 thread
= process
->GetThreadList()
1120 .FindThreadByIndexID(m_options
.m_thread_idx
)
1124 if (thread
== nullptr) {
1125 const uint32_t num_threads
= process
->GetThreadList().GetSize();
1126 result
.AppendErrorWithFormat(
1127 "Thread index %u is out of range (valid values are 0 - %u).\n",
1128 m_options
.m_thread_idx
, num_threads
);
1129 result
.SetStatus(eReturnStatusFailed
);
1133 const bool abort_other_plans
= false;
1136 thread
->GetStackFrameAtIndex(m_options
.m_frame_idx
).get();
1137 if (frame
== nullptr) {
1138 result
.AppendErrorWithFormat(
1139 "Frame index %u is out of range for thread %u.\n",
1140 m_options
.m_frame_idx
, m_options
.m_thread_idx
);
1141 result
.SetStatus(eReturnStatusFailed
);
1145 ThreadPlanSP new_plan_sp
;
1146 Status new_plan_status
;
1148 if (frame
->HasDebugInformation()) {
1149 // Finally we got here... Translate the given line number to a bunch
1151 SymbolContext
sc(frame
->GetSymbolContext(eSymbolContextCompUnit
));
1152 LineTable
*line_table
= nullptr;
1154 line_table
= sc
.comp_unit
->GetLineTable();
1156 if (line_table
== nullptr) {
1157 result
.AppendErrorWithFormat("Failed to resolve the line table for "
1158 "frame %u of thread index %u.\n",
1159 m_options
.m_frame_idx
,
1160 m_options
.m_thread_idx
);
1161 result
.SetStatus(eReturnStatusFailed
);
1165 LineEntry function_start
;
1166 uint32_t index_ptr
= 0, end_ptr
;
1167 std::vector
<addr_t
> address_list
;
1169 // Find the beginning & end index of the
1170 AddressRange fun_addr_range
= sc
.function
->GetAddressRange();
1171 Address fun_start_addr
= fun_addr_range
.GetBaseAddress();
1172 line_table
->FindLineEntryByAddress(fun_start_addr
, function_start
,
1175 Address
fun_end_addr(fun_start_addr
.GetSection(),
1176 fun_start_addr
.GetOffset() +
1177 fun_addr_range
.GetByteSize());
1179 bool all_in_function
= true;
1181 line_table
->FindLineEntryByAddress(fun_end_addr
, function_start
,
1184 for (uint32_t line_number
: line_numbers
) {
1185 uint32_t start_idx_ptr
= index_ptr
;
1186 while (start_idx_ptr
<= end_ptr
) {
1187 LineEntry line_entry
;
1188 const bool exact
= false;
1189 start_idx_ptr
= sc
.comp_unit
->FindLineEntry(
1190 start_idx_ptr
, line_number
, nullptr, exact
, &line_entry
);
1191 if (start_idx_ptr
== UINT32_MAX
)
1195 line_entry
.range
.GetBaseAddress().GetLoadAddress(target
);
1196 if (address
!= LLDB_INVALID_ADDRESS
) {
1197 if (fun_addr_range
.ContainsLoadAddress(address
, target
))
1198 address_list
.push_back(address
);
1200 all_in_function
= false;
1206 for (lldb::addr_t address
: m_options
.m_until_addrs
) {
1207 if (fun_addr_range
.ContainsLoadAddress(address
, target
))
1208 address_list
.push_back(address
);
1210 all_in_function
= false;
1213 if (address_list
.empty()) {
1214 if (all_in_function
)
1215 result
.AppendErrorWithFormat(
1216 "No line entries matching until target.\n");
1218 result
.AppendErrorWithFormat(
1219 "Until target outside of the current function.\n");
1221 result
.SetStatus(eReturnStatusFailed
);
1225 new_plan_sp
= thread
->QueueThreadPlanForStepUntil(
1226 abort_other_plans
, &address_list
.front(), address_list
.size(),
1227 m_options
.m_stop_others
, m_options
.m_frame_idx
, new_plan_status
);
1229 // User level plans should be master plans so they can be interrupted
1230 // (e.g. by hitting a breakpoint) and other plans executed by the
1231 // user (stepping around the breakpoint) and then a "continue" will
1232 // resume the original plan.
1233 new_plan_sp
->SetIsMasterPlan(true);
1234 new_plan_sp
->SetOkayToDiscard(false);
1236 result
.SetError(new_plan_status
);
1237 result
.SetStatus(eReturnStatusFailed
);
1241 result
.AppendErrorWithFormat(
1242 "Frame index %u of thread %u has no debug information.\n",
1243 m_options
.m_frame_idx
, m_options
.m_thread_idx
);
1244 result
.SetStatus(eReturnStatusFailed
);
1248 process
->GetThreadList().SetSelectedThreadByID(m_options
.m_thread_idx
);
1250 StreamString stream
;
1252 if (synchronous_execution
)
1253 error
= process
->ResumeSynchronous(&stream
);
1255 error
= process
->Resume();
1257 if (error
.Success()) {
1258 result
.AppendMessageWithFormat("Process %" PRIu64
" resuming\n",
1260 if (synchronous_execution
) {
1261 // If any state changed events had anything to say, add that to the
1263 if (stream
.GetSize() > 0)
1264 result
.AppendMessage(stream
.GetString());
1266 result
.SetDidChangeProcessState(true);
1267 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1269 result
.SetStatus(eReturnStatusSuccessContinuingNoResult
);
1272 result
.AppendErrorWithFormat("Failed to resume process: %s.\n",
1274 result
.SetStatus(eReturnStatusFailed
);
1277 return result
.Succeeded();
1280 CommandOptions m_options
;
1283 // CommandObjectThreadSelect
1285 class CommandObjectThreadSelect
: public CommandObjectParsed
{
1287 CommandObjectThreadSelect(CommandInterpreter
&interpreter
)
1288 : CommandObjectParsed(interpreter
, "thread select",
1289 "Change the currently selected thread.", nullptr,
1290 eCommandRequiresProcess
| eCommandTryTargetAPILock
|
1291 eCommandProcessMustBeLaunched
|
1292 eCommandProcessMustBePaused
) {
1293 CommandArgumentEntry arg
;
1294 CommandArgumentData thread_idx_arg
;
1296 // Define the first (and only) variant of this arg.
1297 thread_idx_arg
.arg_type
= eArgTypeThreadIndex
;
1298 thread_idx_arg
.arg_repetition
= eArgRepeatPlain
;
1300 // There is only one variant this argument could be; put it into the
1302 arg
.push_back(thread_idx_arg
);
1304 // Push the data for the first argument into the m_arguments vector.
1305 m_arguments
.push_back(arg
);
1308 ~CommandObjectThreadSelect() override
= default;
1311 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1312 Process
*process
= m_exe_ctx
.GetProcessPtr();
1313 if (process
== nullptr) {
1314 result
.AppendError("no process");
1315 result
.SetStatus(eReturnStatusFailed
);
1317 } else if (command
.GetArgumentCount() != 1) {
1318 result
.AppendErrorWithFormat(
1319 "'%s' takes exactly one thread index argument:\nUsage: %s\n",
1320 m_cmd_name
.c_str(), m_cmd_syntax
.c_str());
1321 result
.SetStatus(eReturnStatusFailed
);
1326 StringConvert::ToUInt32(command
.GetArgumentAtIndex(0), 0, 0);
1328 Thread
*new_thread
=
1329 process
->GetThreadList().FindThreadByIndexID(index_id
).get();
1330 if (new_thread
== nullptr) {
1331 result
.AppendErrorWithFormat("invalid thread #%s.\n",
1332 command
.GetArgumentAtIndex(0));
1333 result
.SetStatus(eReturnStatusFailed
);
1337 process
->GetThreadList().SetSelectedThreadByID(new_thread
->GetID(), true);
1338 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1340 return result
.Succeeded();
1344 // CommandObjectThreadList
1346 class CommandObjectThreadList
: public CommandObjectParsed
{
1348 CommandObjectThreadList(CommandInterpreter
&interpreter
)
1349 : CommandObjectParsed(
1350 interpreter
, "thread list",
1351 "Show a summary of each thread in the current target process. "
1352 "Use 'settings set thread-format' to customize the individual "
1355 eCommandRequiresProcess
| eCommandTryTargetAPILock
|
1356 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
) {}
1358 ~CommandObjectThreadList() override
= default;
1361 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1362 Stream
&strm
= result
.GetOutputStream();
1363 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1364 Process
*process
= m_exe_ctx
.GetProcessPtr();
1365 const bool only_threads_with_stop_reason
= false;
1366 const uint32_t start_frame
= 0;
1367 const uint32_t num_frames
= 0;
1368 const uint32_t num_frames_with_source
= 0;
1369 process
->GetStatus(strm
);
1370 process
->GetThreadStatus(strm
, only_threads_with_stop_reason
, start_frame
,
1371 num_frames
, num_frames_with_source
, false);
1372 return result
.Succeeded();
1376 // CommandObjectThreadInfo
1377 #define LLDB_OPTIONS_thread_info
1378 #include "CommandOptions.inc"
1380 class CommandObjectThreadInfo
: public CommandObjectIterateOverThreads
{
1382 class CommandOptions
: public Options
{
1384 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1386 ~CommandOptions() override
= default;
1388 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1389 m_json_thread
= false;
1390 m_json_stopinfo
= false;
1393 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1394 ExecutionContext
*execution_context
) override
{
1395 const int short_option
= m_getopt_table
[option_idx
].val
;
1398 switch (short_option
) {
1400 m_json_thread
= true;
1404 m_json_stopinfo
= true;
1408 llvm_unreachable("Unimplemented option");
1413 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1414 return llvm::makeArrayRef(g_thread_info_options
);
1418 bool m_json_stopinfo
;
1421 CommandObjectThreadInfo(CommandInterpreter
&interpreter
)
1422 : CommandObjectIterateOverThreads(
1423 interpreter
, "thread info",
1424 "Show an extended summary of one or "
1425 "more threads. Defaults to the "
1428 eCommandRequiresProcess
| eCommandTryTargetAPILock
|
1429 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
),
1431 m_add_return
= false;
1434 ~CommandObjectThreadInfo() override
= default;
1436 Options
*GetOptions() override
{ return &m_options
; }
1438 bool HandleOneThread(lldb::tid_t tid
, CommandReturnObject
&result
) override
{
1439 ThreadSP thread_sp
=
1440 m_exe_ctx
.GetProcessPtr()->GetThreadList().FindThreadByID(tid
);
1442 result
.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64
"\n",
1444 result
.SetStatus(eReturnStatusFailed
);
1448 Thread
*thread
= thread_sp
.get();
1450 Stream
&strm
= result
.GetOutputStream();
1451 if (!thread
->GetDescription(strm
, eDescriptionLevelFull
,
1452 m_options
.m_json_thread
,
1453 m_options
.m_json_stopinfo
)) {
1454 result
.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1455 thread
->GetIndexID());
1456 result
.SetStatus(eReturnStatusFailed
);
1462 CommandOptions m_options
;
1465 // CommandObjectThreadException
1467 class CommandObjectThreadException
: public CommandObjectIterateOverThreads
{
1469 CommandObjectThreadException(CommandInterpreter
&interpreter
)
1470 : CommandObjectIterateOverThreads(
1471 interpreter
, "thread exception",
1472 "Display the current exception object for a thread. Defaults to "
1473 "the current thread.",
1475 eCommandRequiresProcess
| eCommandTryTargetAPILock
|
1476 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
) {}
1478 ~CommandObjectThreadException() override
= default;
1480 bool HandleOneThread(lldb::tid_t tid
, CommandReturnObject
&result
) override
{
1481 ThreadSP thread_sp
=
1482 m_exe_ctx
.GetProcessPtr()->GetThreadList().FindThreadByID(tid
);
1484 result
.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64
"\n",
1486 result
.SetStatus(eReturnStatusFailed
);
1490 Stream
&strm
= result
.GetOutputStream();
1491 ValueObjectSP exception_object_sp
= thread_sp
->GetCurrentException();
1492 if (exception_object_sp
) {
1493 exception_object_sp
->Dump(strm
);
1496 ThreadSP exception_thread_sp
= thread_sp
->GetCurrentExceptionBacktrace();
1497 if (exception_thread_sp
&& exception_thread_sp
->IsValid()) {
1498 const uint32_t num_frames_with_source
= 0;
1499 const bool stop_format
= false;
1500 exception_thread_sp
->GetStatus(strm
, 0, UINT32_MAX
,
1501 num_frames_with_source
, stop_format
);
1508 // CommandObjectThreadReturn
1509 #define LLDB_OPTIONS_thread_return
1510 #include "CommandOptions.inc"
1512 class CommandObjectThreadReturn
: public CommandObjectRaw
{
1514 class CommandOptions
: public Options
{
1516 CommandOptions() : Options(), m_from_expression(false) {
1517 // Keep default values of all options in one place: OptionParsingStarting
1519 OptionParsingStarting(nullptr);
1522 ~CommandOptions() override
= default;
1524 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1525 ExecutionContext
*execution_context
) override
{
1527 const int short_option
= m_getopt_table
[option_idx
].val
;
1529 switch (short_option
) {
1533 OptionArgParser::ToBoolean(option_arg
, false, &success
);
1535 m_from_expression
= tmp_value
;
1537 error
.SetErrorStringWithFormat(
1538 "invalid boolean value '%s' for 'x' option",
1539 option_arg
.str().c_str());
1543 llvm_unreachable("Unimplemented option");
1548 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1549 m_from_expression
= false;
1552 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1553 return llvm::makeArrayRef(g_thread_return_options
);
1556 bool m_from_expression
;
1558 // Instance variables to hold the values for command options.
1561 CommandObjectThreadReturn(CommandInterpreter
&interpreter
)
1562 : CommandObjectRaw(interpreter
, "thread return",
1563 "Prematurely return from a stack frame, "
1564 "short-circuiting execution of newer frames "
1565 "and optionally yielding a specified value. Defaults "
1566 "to the exiting the current stack "
1569 eCommandRequiresFrame
| eCommandTryTargetAPILock
|
1570 eCommandProcessMustBeLaunched
|
1571 eCommandProcessMustBePaused
),
1573 CommandArgumentEntry arg
;
1574 CommandArgumentData expression_arg
;
1576 // Define the first (and only) variant of this arg.
1577 expression_arg
.arg_type
= eArgTypeExpression
;
1578 expression_arg
.arg_repetition
= eArgRepeatOptional
;
1580 // There is only one variant this argument could be; put it into the
1582 arg
.push_back(expression_arg
);
1584 // Push the data for the first argument into the m_arguments vector.
1585 m_arguments
.push_back(arg
);
1588 ~CommandObjectThreadReturn() override
= default;
1590 Options
*GetOptions() override
{ return &m_options
; }
1593 bool DoExecute(llvm::StringRef command
,
1594 CommandReturnObject
&result
) override
{
1595 // I am going to handle this by hand, because I don't want you to have to
1597 // "thread return -- -5".
1598 if (command
.startswith("-x")) {
1599 if (command
.size() != 2U)
1600 result
.AppendWarning("Return values ignored when returning from user "
1601 "called expressions");
1603 Thread
*thread
= m_exe_ctx
.GetThreadPtr();
1605 error
= thread
->UnwindInnermostExpression();
1606 if (!error
.Success()) {
1607 result
.AppendErrorWithFormat("Unwinding expression failed - %s.",
1609 result
.SetStatus(eReturnStatusFailed
);
1612 thread
->SetSelectedFrameByIndexNoisily(0, result
.GetOutputStream());
1614 m_exe_ctx
.SetFrameSP(thread
->GetSelectedFrame());
1615 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1617 result
.AppendErrorWithFormat(
1618 "Could not select 0th frame after unwinding expression.");
1619 result
.SetStatus(eReturnStatusFailed
);
1622 return result
.Succeeded();
1625 ValueObjectSP return_valobj_sp
;
1627 StackFrameSP frame_sp
= m_exe_ctx
.GetFrameSP();
1628 uint32_t frame_idx
= frame_sp
->GetFrameIndex();
1630 if (frame_sp
->IsInlined()) {
1631 result
.AppendError("Don't know how to return from inlined frames.");
1632 result
.SetStatus(eReturnStatusFailed
);
1636 if (!command
.empty()) {
1637 Target
*target
= m_exe_ctx
.GetTargetPtr();
1638 EvaluateExpressionOptions options
;
1640 options
.SetUnwindOnError(true);
1641 options
.SetUseDynamic(eNoDynamicValues
);
1643 ExpressionResults exe_results
= eExpressionSetupError
;
1644 exe_results
= target
->EvaluateExpression(command
, frame_sp
.get(),
1645 return_valobj_sp
, options
);
1646 if (exe_results
!= eExpressionCompleted
) {
1647 if (return_valobj_sp
)
1648 result
.AppendErrorWithFormat(
1649 "Error evaluating result expression: %s",
1650 return_valobj_sp
->GetError().AsCString());
1652 result
.AppendErrorWithFormat(
1653 "Unknown error evaluating result expression.");
1654 result
.SetStatus(eReturnStatusFailed
);
1660 ThreadSP thread_sp
= m_exe_ctx
.GetThreadSP();
1661 const bool broadcast
= true;
1662 error
= thread_sp
->ReturnFromFrame(frame_sp
, return_valobj_sp
, broadcast
);
1663 if (!error
.Success()) {
1664 result
.AppendErrorWithFormat(
1665 "Error returning from frame %d of thread %d: %s.", frame_idx
,
1666 thread_sp
->GetIndexID(), error
.AsCString());
1667 result
.SetStatus(eReturnStatusFailed
);
1671 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1675 CommandOptions m_options
;
1678 // CommandObjectThreadJump
1679 #define LLDB_OPTIONS_thread_jump
1680 #include "CommandOptions.inc"
1682 class CommandObjectThreadJump
: public CommandObjectParsed
{
1684 class CommandOptions
: public Options
{
1686 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1688 ~CommandOptions() override
= default;
1690 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1691 m_filenames
.Clear();
1694 m_load_addr
= LLDB_INVALID_ADDRESS
;
1698 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1699 ExecutionContext
*execution_context
) override
{
1700 const int short_option
= m_getopt_table
[option_idx
].val
;
1703 switch (short_option
) {
1705 m_filenames
.AppendIfUnique(FileSpec(option_arg
));
1706 if (m_filenames
.GetSize() > 1)
1707 return Status("only one source file expected.");
1710 if (option_arg
.getAsInteger(0, m_line_num
))
1711 return Status("invalid line number: '%s'.", option_arg
.str().c_str());
1714 if (option_arg
.getAsInteger(0, m_line_offset
))
1715 return Status("invalid line offset: '%s'.", option_arg
.str().c_str());
1718 m_load_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
1719 LLDB_INVALID_ADDRESS
, &error
);
1725 llvm_unreachable("Unimplemented option");
1730 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1731 return llvm::makeArrayRef(g_thread_jump_options
);
1734 FileSpecList m_filenames
;
1735 uint32_t m_line_num
;
1736 int32_t m_line_offset
;
1737 lldb::addr_t m_load_addr
;
1741 CommandObjectThreadJump(CommandInterpreter
&interpreter
)
1742 : CommandObjectParsed(
1743 interpreter
, "thread jump",
1744 "Sets the program counter to a new address.", "thread jump",
1745 eCommandRequiresFrame
| eCommandTryTargetAPILock
|
1746 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
),
1749 ~CommandObjectThreadJump() override
= default;
1751 Options
*GetOptions() override
{ return &m_options
; }
1754 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
1755 RegisterContext
*reg_ctx
= m_exe_ctx
.GetRegisterContext();
1756 StackFrame
*frame
= m_exe_ctx
.GetFramePtr();
1757 Thread
*thread
= m_exe_ctx
.GetThreadPtr();
1758 Target
*target
= m_exe_ctx
.GetTargetPtr();
1759 const SymbolContext
&sym_ctx
=
1760 frame
->GetSymbolContext(eSymbolContextLineEntry
);
1762 if (m_options
.m_load_addr
!= LLDB_INVALID_ADDRESS
) {
1763 // Use this address directly.
1764 Address dest
= Address(m_options
.m_load_addr
);
1766 lldb::addr_t callAddr
= dest
.GetCallableLoadAddress(target
);
1767 if (callAddr
== LLDB_INVALID_ADDRESS
) {
1768 result
.AppendErrorWithFormat("Invalid destination address.");
1769 result
.SetStatus(eReturnStatusFailed
);
1773 if (!reg_ctx
->SetPC(callAddr
)) {
1774 result
.AppendErrorWithFormat("Error changing PC value for thread %d.",
1775 thread
->GetIndexID());
1776 result
.SetStatus(eReturnStatusFailed
);
1780 // Pick either the absolute line, or work out a relative one.
1781 int32_t line
= (int32_t)m_options
.m_line_num
;
1783 line
= sym_ctx
.line_entry
.line
+ m_options
.m_line_offset
;
1785 // Try the current file, but override if asked.
1786 FileSpec file
= sym_ctx
.line_entry
.file
;
1787 if (m_options
.m_filenames
.GetSize() == 1)
1788 file
= m_options
.m_filenames
.GetFileSpecAtIndex(0);
1791 result
.AppendErrorWithFormat(
1792 "No source file available for the current location.");
1793 result
.SetStatus(eReturnStatusFailed
);
1797 std::string warnings
;
1798 Status err
= thread
->JumpToLine(file
, line
, m_options
.m_force
, &warnings
);
1801 result
.SetError(err
);
1805 if (!warnings
.empty())
1806 result
.AppendWarning(warnings
.c_str());
1809 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1813 CommandOptions m_options
;
1816 // Next are the subcommands of CommandObjectMultiwordThreadPlan
1818 // CommandObjectThreadPlanList
1819 #define LLDB_OPTIONS_thread_plan_list
1820 #include "CommandOptions.inc"
1822 class CommandObjectThreadPlanList
: public CommandObjectIterateOverThreads
{
1824 class CommandOptions
: public Options
{
1826 CommandOptions() : Options() {
1827 // Keep default values of all options in one place: OptionParsingStarting
1829 OptionParsingStarting(nullptr);
1832 ~CommandOptions() override
= default;
1834 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1835 ExecutionContext
*execution_context
) override
{
1837 const int short_option
= m_getopt_table
[option_idx
].val
;
1839 switch (short_option
) {
1847 llvm_unreachable("Unimplemented option");
1852 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1857 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1858 return llvm::makeArrayRef(g_thread_plan_list_options
);
1861 // Instance variables to hold the values for command options.
1866 CommandObjectThreadPlanList(CommandInterpreter
&interpreter
)
1867 : CommandObjectIterateOverThreads(
1868 interpreter
, "thread plan list",
1869 "Show thread plans for one or more threads. If no threads are "
1870 "specified, show the "
1871 "current thread. Use the thread-index \"all\" to see all threads.",
1873 eCommandRequiresProcess
| eCommandRequiresThread
|
1874 eCommandTryTargetAPILock
| eCommandProcessMustBeLaunched
|
1875 eCommandProcessMustBePaused
),
1878 ~CommandObjectThreadPlanList() override
= default;
1880 Options
*GetOptions() override
{ return &m_options
; }
1883 bool HandleOneThread(lldb::tid_t tid
, CommandReturnObject
&result
) override
{
1884 ThreadSP thread_sp
=
1885 m_exe_ctx
.GetProcessPtr()->GetThreadList().FindThreadByID(tid
);
1887 result
.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64
"\n",
1889 result
.SetStatus(eReturnStatusFailed
);
1893 Thread
*thread
= thread_sp
.get();
1895 Stream
&strm
= result
.GetOutputStream();
1896 DescriptionLevel desc_level
= eDescriptionLevelFull
;
1897 if (m_options
.m_verbose
)
1898 desc_level
= eDescriptionLevelVerbose
;
1900 thread
->DumpThreadPlans(&strm
, desc_level
, m_options
.m_internal
, true);
1904 CommandOptions m_options
;
1907 class CommandObjectThreadPlanDiscard
: public CommandObjectParsed
{
1909 CommandObjectThreadPlanDiscard(CommandInterpreter
&interpreter
)
1910 : CommandObjectParsed(interpreter
, "thread plan discard",
1911 "Discards thread plans up to and including the "
1912 "specified index (see 'thread plan list'.) "
1913 "Only user visible plans can be discarded.",
1915 eCommandRequiresProcess
| eCommandRequiresThread
|
1916 eCommandTryTargetAPILock
|
1917 eCommandProcessMustBeLaunched
|
1918 eCommandProcessMustBePaused
) {
1919 CommandArgumentEntry arg
;
1920 CommandArgumentData plan_index_arg
;
1922 // Define the first (and only) variant of this arg.
1923 plan_index_arg
.arg_type
= eArgTypeUnsignedInteger
;
1924 plan_index_arg
.arg_repetition
= eArgRepeatPlain
;
1926 // There is only one variant this argument could be; put it into the
1928 arg
.push_back(plan_index_arg
);
1930 // Push the data for the first argument into the m_arguments vector.
1931 m_arguments
.push_back(arg
);
1934 ~CommandObjectThreadPlanDiscard() override
= default;
1936 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
1937 Thread
*thread
= m_exe_ctx
.GetThreadPtr();
1938 if (args
.GetArgumentCount() != 1) {
1939 result
.AppendErrorWithFormat("Too many arguments, expected one - the "
1940 "thread plan index - but got %zu.",
1941 args
.GetArgumentCount());
1942 result
.SetStatus(eReturnStatusFailed
);
1947 uint32_t thread_plan_idx
=
1948 StringConvert::ToUInt32(args
.GetArgumentAtIndex(0), 0, 0, &success
);
1950 result
.AppendErrorWithFormat(
1951 "Invalid thread index: \"%s\" - should be unsigned int.",
1952 args
.GetArgumentAtIndex(0));
1953 result
.SetStatus(eReturnStatusFailed
);
1957 if (thread_plan_idx
== 0) {
1958 result
.AppendErrorWithFormat(
1959 "You wouldn't really want me to discard the base thread plan.");
1960 result
.SetStatus(eReturnStatusFailed
);
1964 if (thread
->DiscardUserThreadPlansUpToIndex(thread_plan_idx
)) {
1965 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1968 result
.AppendErrorWithFormat(
1969 "Could not find User thread plan with index %s.",
1970 args
.GetArgumentAtIndex(0));
1971 result
.SetStatus(eReturnStatusFailed
);
1977 // CommandObjectMultiwordThreadPlan
1979 class CommandObjectMultiwordThreadPlan
: public CommandObjectMultiword
{
1981 CommandObjectMultiwordThreadPlan(CommandInterpreter
&interpreter
)
1982 : CommandObjectMultiword(
1983 interpreter
, "plan",
1984 "Commands for managing thread plans that control execution.",
1985 "thread plan <subcommand> [<subcommand objects]") {
1987 "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter
)));
1990 CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter
)));
1993 ~CommandObjectMultiwordThreadPlan() override
= default;
1996 // CommandObjectMultiwordThread
1998 CommandObjectMultiwordThread::CommandObjectMultiwordThread(
1999 CommandInterpreter
&interpreter
)
2000 : CommandObjectMultiword(interpreter
, "thread",
2001 "Commands for operating on "
2002 "one or more threads in "
2003 "the current process.",
2004 "thread <subcommand> [<subcommand-options>]") {
2005 LoadSubCommand("backtrace", CommandObjectSP(new CommandObjectThreadBacktrace(
2007 LoadSubCommand("continue",
2008 CommandObjectSP(new CommandObjectThreadContinue(interpreter
)));
2009 LoadSubCommand("list",
2010 CommandObjectSP(new CommandObjectThreadList(interpreter
)));
2011 LoadSubCommand("return",
2012 CommandObjectSP(new CommandObjectThreadReturn(interpreter
)));
2013 LoadSubCommand("jump",
2014 CommandObjectSP(new CommandObjectThreadJump(interpreter
)));
2015 LoadSubCommand("select",
2016 CommandObjectSP(new CommandObjectThreadSelect(interpreter
)));
2017 LoadSubCommand("until",
2018 CommandObjectSP(new CommandObjectThreadUntil(interpreter
)));
2019 LoadSubCommand("info",
2020 CommandObjectSP(new CommandObjectThreadInfo(interpreter
)));
2021 LoadSubCommand("exception", CommandObjectSP(new CommandObjectThreadException(
2023 LoadSubCommand("step-in",
2024 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2025 interpreter
, "thread step-in",
2026 "Source level single step, stepping into calls. Defaults "
2027 "to current thread unless specified.",
2028 nullptr, eStepTypeInto
, eStepScopeSource
)));
2030 LoadSubCommand("step-out",
2031 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2032 interpreter
, "thread step-out",
2033 "Finish executing the current stack frame and stop after "
2034 "returning. Defaults to current thread unless specified.",
2035 nullptr, eStepTypeOut
, eStepScopeSource
)));
2037 LoadSubCommand("step-over",
2038 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2039 interpreter
, "thread step-over",
2040 "Source level single step, stepping over calls. Defaults "
2041 "to current thread unless specified.",
2042 nullptr, eStepTypeOver
, eStepScopeSource
)));
2044 LoadSubCommand("step-inst",
2045 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2046 interpreter
, "thread step-inst",
2047 "Instruction level single step, stepping into calls. "
2048 "Defaults to current thread unless specified.",
2049 nullptr, eStepTypeTrace
, eStepScopeInstruction
)));
2051 LoadSubCommand("step-inst-over",
2052 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2053 interpreter
, "thread step-inst-over",
2054 "Instruction level single step, stepping over calls. "
2055 "Defaults to current thread unless specified.",
2056 nullptr, eStepTypeTraceOver
, eStepScopeInstruction
)));
2060 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2061 interpreter
, "thread step-scripted",
2062 "Step as instructed by the script class passed in the -C option. "
2063 "You can also specify a dictionary of key (-k) and value (-v) pairs "
2064 "that will be used to populate an SBStructuredData Dictionary, which "
2065 "will be passed to the constructor of the class implementing the "
2066 "scripted step. See the Python Reference for more details.",
2067 nullptr, eStepTypeScripted
, eStepScopeSource
)));
2069 LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
2073 CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;