LLDB mainline
CommandObjectThread.cpp
Go to the documentation of this file.
1//===-- CommandObjectThread.cpp -------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include <memory>
12#include <optional>
13#include <sstream>
14
16#include "CommandObjectTrace.h"
30#include "lldb/Target/Process.h"
33#include "lldb/Target/Target.h"
34#include "lldb/Target/Thread.h"
37#include "lldb/Target/Trace.h"
39#include "lldb/Utility/State.h"
40
41using namespace lldb;
42using namespace lldb_private;
43
44// CommandObjectThreadBacktrace
45#define LLDB_OPTIONS_thread_backtrace
46#include "CommandOptions.inc"
47
49public:
50 class CommandOptions : public Options {
51 public:
53 // Keep default values of all options in one place: OptionParsingStarting
54 // ()
55 OptionParsingStarting(nullptr);
56 }
57
58 ~CommandOptions() override = default;
59
60 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
61 ExecutionContext *execution_context) override {
63 const int short_option = m_getopt_table[option_idx].val;
64
65 switch (short_option) {
66 case 'c':
67 if (option_arg.getAsInteger(0, m_count)) {
69 error.SetErrorStringWithFormat(
70 "invalid integer value for option '%c': %s", short_option,
71 option_arg.data());
72 }
73 // A count of 0 means all frames.
74 if (m_count == 0)
76 break;
77 case 's':
78 if (option_arg.getAsInteger(0, m_start))
79 error.SetErrorStringWithFormat(
80 "invalid integer value for option '%c': %s", short_option,
81 option_arg.data());
82 break;
83 case 'e': {
84 bool success;
86 OptionArgParser::ToBoolean(option_arg, false, &success);
87 if (!success)
88 error.SetErrorStringWithFormat(
89 "invalid boolean value for option '%c': %s", short_option,
90 option_arg.data());
91 } break;
92 default:
93 llvm_unreachable("Unimplemented option");
94 }
95 return error;
96 }
97
98 void OptionParsingStarting(ExecutionContext *execution_context) override {
100 m_start = 0;
101 m_extended_backtrace = false;
102 }
103
104 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
105 return llvm::ArrayRef(g_thread_backtrace_options);
106 }
107
108 // Instance variables to hold the values for command options.
109 uint32_t m_count;
110 uint32_t m_start;
112 };
113
116 interpreter, "thread backtrace",
117 "Show backtraces of thread call stacks. Defaults to the current "
118 "thread, thread indexes can be specified as arguments.\n"
119 "Use the thread-index \"all\" to see all threads.\n"
120 "Use the thread-index \"unique\" to see threads grouped by unique "
121 "call stacks.\n"
122 "Use 'settings set frame-format' to customize the printing of "
123 "frames in the backtrace and 'settings set thread-format' to "
124 "customize the thread header.",
125 nullptr,
126 eCommandRequiresProcess | eCommandRequiresThread |
127 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
128 eCommandProcessMustBePaused) {}
129
130 ~CommandObjectThreadBacktrace() override = default;
131
132 Options *GetOptions() override { return &m_options; }
133
134 std::optional<std::string> GetRepeatCommand(Args &current_args,
135 uint32_t index) override {
136 llvm::StringRef count_opt("--count");
137 llvm::StringRef start_opt("--start");
138
139 // If no "count" was provided, we are dumping the entire backtrace, so
140 // there isn't a repeat command. So we search for the count option in
141 // the args, and if we find it, we make a copy and insert or modify the
142 // start option's value to start count indices greater.
143
144 Args copy_args(current_args);
145 size_t num_entries = copy_args.GetArgumentCount();
146 // These two point at the index of the option value if found.
147 size_t count_idx = 0;
148 size_t start_idx = 0;
149 size_t count_val = 0;
150 size_t start_val = 0;
151
152 for (size_t idx = 0; idx < num_entries; idx++) {
153 llvm::StringRef arg_string = copy_args[idx].ref();
154 if (arg_string == "-c" || count_opt.starts_with(arg_string)) {
155 idx++;
156 if (idx == num_entries)
157 return std::nullopt;
158 count_idx = idx;
159 if (copy_args[idx].ref().getAsInteger(0, count_val))
160 return std::nullopt;
161 } else if (arg_string == "-s" || start_opt.starts_with(arg_string)) {
162 idx++;
163 if (idx == num_entries)
164 return std::nullopt;
165 start_idx = idx;
166 if (copy_args[idx].ref().getAsInteger(0, start_val))
167 return std::nullopt;
168 }
169 }
170 if (count_idx == 0)
171 return std::nullopt;
172
173 std::string new_start_val = llvm::formatv("{0}", start_val + count_val);
174 if (start_idx == 0) {
175 copy_args.AppendArgument(start_opt);
176 copy_args.AppendArgument(new_start_val);
177 } else {
178 copy_args.ReplaceArgumentAtIndex(start_idx, new_start_val);
179 }
180 std::string repeat_command;
181 if (!copy_args.GetQuotedCommandString(repeat_command))
182 return std::nullopt;
183 return repeat_command;
184 }
185
186protected:
188 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
189 if (runtime) {
190 Stream &strm = result.GetOutputStream();
191 const std::vector<ConstString> &types =
192 runtime->GetExtendedBacktraceTypes();
193 for (auto type : types) {
194 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread(
195 thread->shared_from_this(), type);
196 if (ext_thread_sp && ext_thread_sp->IsValid()) {
197 const uint32_t num_frames_with_source = 0;
198 const bool stop_format = false;
199 strm.PutChar('\n');
200 if (ext_thread_sp->GetStatus(strm, m_options.m_start,
202 num_frames_with_source, stop_format)) {
203 DoExtendedBacktrace(ext_thread_sp.get(), result);
204 }
205 }
206 }
207 }
208 }
209
210 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
211 ThreadSP thread_sp =
213 if (!thread_sp) {
215 "thread disappeared while computing backtraces: 0x%" PRIx64 "\n",
216 tid);
217 return false;
218 }
219
220 Thread *thread = thread_sp.get();
221
222 Stream &strm = result.GetOutputStream();
223
224 // Only dump stack info if we processing unique stacks.
225 const bool only_stacks = m_unique_stacks;
226
227 // Don't show source context when doing backtraces.
228 const uint32_t num_frames_with_source = 0;
229 const bool stop_format = true;
230 if (!thread->GetStatus(strm, m_options.m_start, m_options.m_count,
231 num_frames_with_source, stop_format, only_stacks)) {
233 "error displaying backtrace for thread: \"0x%4.4x\"\n",
234 thread->GetIndexID());
235 return false;
236 }
239 "Interrupt skipped extended backtrace")) {
240 DoExtendedBacktrace(thread, result);
241 }
242 }
243
244 return true;
245 }
246
248};
249
250#define LLDB_OPTIONS_thread_step_scope
251#include "CommandOptions.inc"
252
254public:
256 // Keep default values of all options in one place: OptionParsingStarting
257 // ()
258 OptionParsingStarting(nullptr);
259 }
260
261 ~ThreadStepScopeOptionGroup() override = default;
262
263 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
264 return llvm::ArrayRef(g_thread_step_scope_options);
265 }
266
267 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
268 ExecutionContext *execution_context) override {
270 const int short_option =
271 g_thread_step_scope_options[option_idx].short_option;
272
273 switch (short_option) {
274 case 'a': {
275 bool success;
276 bool avoid_no_debug =
277 OptionArgParser::ToBoolean(option_arg, true, &success);
278 if (!success)
279 error.SetErrorStringWithFormat(
280 "invalid boolean value for option '%c': %s", short_option,
281 option_arg.data());
282 else {
284 }
285 } break;
286
287 case 'A': {
288 bool success;
289 bool avoid_no_debug =
290 OptionArgParser::ToBoolean(option_arg, true, &success);
291 if (!success)
292 error.SetErrorStringWithFormat(
293 "invalid boolean value for option '%c': %s", short_option,
294 option_arg.data());
295 else {
297 }
298 } break;
299
300 case 'c':
301 if (option_arg.getAsInteger(0, m_step_count))
302 error.SetErrorStringWithFormat(
303 "invalid integer value for option '%c': %s", short_option,
304 option_arg.data());
305 break;
306
307 case 'm': {
308 auto enum_values = GetDefinitions()[option_idx].enum_values;
310 option_arg, enum_values, eOnlyDuringStepping, error);
311 } break;
312
313 case 'e':
314 if (option_arg == "block") {
316 break;
317 }
318 if (option_arg.getAsInteger(0, m_end_line))
319 error.SetErrorStringWithFormat("invalid end line number '%s'",
320 option_arg.str().c_str());
321 break;
322
323 case 'r':
324 m_avoid_regexp.clear();
325 m_avoid_regexp.assign(std::string(option_arg));
326 break;
327
328 case 't':
329 m_step_in_target.clear();
330 m_step_in_target.assign(std::string(option_arg));
331 break;
332
333 default:
334 llvm_unreachable("Unimplemented option");
335 }
336 return error;
337 }
338
339 void OptionParsingStarting(ExecutionContext *execution_context) override {
343
344 // Check if we are in Non-Stop mode
345 TargetSP target_sp =
346 execution_context ? execution_context->GetTargetSP() : TargetSP();
347 ProcessSP process_sp =
348 execution_context ? execution_context->GetProcessSP() : ProcessSP();
349 if (process_sp && process_sp->GetSteppingRunsAllThreads())
351
352 m_avoid_regexp.clear();
353 m_step_in_target.clear();
354 m_step_count = 1;
357 }
358
359 // Instance variables to hold the values for command options.
363 std::string m_avoid_regexp;
364 std::string m_step_in_target;
365 uint32_t m_step_count;
366 uint32_t m_end_line;
368};
369
371public:
373 const char *name, const char *help,
374 const char *syntax,
375 StepType step_type)
376 : CommandObjectParsed(interpreter, name, help, syntax,
377 eCommandRequiresProcess | eCommandRequiresThread |
378 eCommandTryTargetAPILock |
379 eCommandProcessMustBeLaunched |
380 eCommandProcessMustBePaused),
381 m_step_type(step_type), m_class_options("scripted step") {
383
384 if (step_type == eStepTypeScripted) {
387 }
390 }
391
393
394 void
396 OptionElementVector &opt_element_vector) override {
397 if (request.GetCursorIndex())
398 return;
399 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
400 }
401
402 Options *GetOptions() override { return &m_all_options; }
403
404protected:
405 void DoExecute(Args &command, CommandReturnObject &result) override {
406 Process *process = m_exe_ctx.GetProcessPtr();
407 bool synchronous_execution = m_interpreter.GetSynchronous();
408
409 const uint32_t num_threads = process->GetThreadList().GetSize();
410 Thread *thread = nullptr;
411
412 if (command.GetArgumentCount() == 0) {
413 thread = GetDefaultThread();
414
415 if (thread == nullptr) {
416 result.AppendError("no selected thread in process");
417 return;
418 }
419 } else {
420 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
421 uint32_t step_thread_idx;
422
423 if (!llvm::to_integer(thread_idx_cstr, step_thread_idx)) {
424 result.AppendErrorWithFormat("invalid thread index '%s'.\n",
425 thread_idx_cstr);
426 return;
427 }
428 thread =
429 process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
430 if (thread == nullptr) {
432 "Thread index %u is out of range (valid values are 0 - %u).\n",
433 step_thread_idx, num_threads);
434 return;
435 }
436 }
437
439 if (m_class_options.GetName().empty()) {
440 result.AppendErrorWithFormat("empty class name for scripted step.");
441 return;
442 } else if (!GetDebugger().GetScriptInterpreter()->CheckObjectExists(
443 m_class_options.GetName().c_str())) {
445 "class for scripted step: \"%s\" does not exist.",
446 m_class_options.GetName().c_str());
447 return;
448 }
449 }
450
454 "end line option is only valid for step into");
455 return;
456 }
457
458 const bool abort_other_plans = false;
459 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
460
461 // This is a bit unfortunate, but not all the commands in this command
462 // object support only while stepping, so I use the bool for them.
463 bool bool_stop_other_threads;
465 bool_stop_other_threads = false;
467 bool_stop_other_threads = (m_step_type != eStepTypeOut);
468 else
469 bool_stop_other_threads = true;
470
471 ThreadPlanSP new_plan_sp;
472 Status new_plan_status;
473
474 if (m_step_type == eStepTypeInto) {
475 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
476 assert(frame != nullptr);
477
478 if (frame->HasDebugInformation()) {
479 AddressRange range;
480 SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
484 error)) {
485 result.AppendErrorWithFormat("invalid end-line option: %s.",
486 error.AsCString());
487 return;
488 }
491 Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
492 if (!block) {
493 result.AppendErrorWithFormat("Could not find the current block.");
494 return;
495 }
496
497 AddressRange block_range;
498 Address pc_address = frame->GetFrameCodeAddress();
499 block->GetRangeContainingAddress(pc_address, block_range);
500 if (!block_range.GetBaseAddress().IsValid()) {
502 "Could not find the current block address.");
503 return;
504 }
505 lldb::addr_t pc_offset_in_block =
506 pc_address.GetFileAddress() -
507 block_range.GetBaseAddress().GetFileAddress();
508 lldb::addr_t range_length =
509 block_range.GetByteSize() - pc_offset_in_block;
510 range = AddressRange(pc_address, range_length);
511 } else {
512 range = sc.line_entry.range;
513 }
514
515 new_plan_sp = thread->QueueThreadPlanForStepInRange(
516 abort_other_plans, range,
517 frame->GetSymbolContext(eSymbolContextEverything),
518 m_options.m_step_in_target.c_str(), stop_other_threads,
519 new_plan_status, m_options.m_step_in_avoid_no_debug,
521
522 if (new_plan_sp && !m_options.m_avoid_regexp.empty()) {
523 ThreadPlanStepInRange *step_in_range_plan =
524 static_cast<ThreadPlanStepInRange *>(new_plan_sp.get());
525 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
526 }
527 } else
528 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
529 false, abort_other_plans, bool_stop_other_threads, new_plan_status);
530 } else if (m_step_type == eStepTypeOver) {
531 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
532
533 if (frame->HasDebugInformation())
534 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
535 abort_other_plans,
536 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
537 frame->GetSymbolContext(eSymbolContextEverything),
538 stop_other_threads, new_plan_status,
540 else
541 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
542 true, abort_other_plans, bool_stop_other_threads, new_plan_status);
543 } else if (m_step_type == eStepTypeTrace) {
544 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
545 false, abort_other_plans, bool_stop_other_threads, new_plan_status);
546 } else if (m_step_type == eStepTypeTraceOver) {
547 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
548 true, abort_other_plans, bool_stop_other_threads, new_plan_status);
549 } else if (m_step_type == eStepTypeOut) {
550 new_plan_sp = thread->QueueThreadPlanForStepOut(
551 abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes,
554 new_plan_status, m_options.m_step_out_avoid_no_debug);
555 } else if (m_step_type == eStepTypeScripted) {
556 new_plan_sp = thread->QueueThreadPlanForStepScripted(
557 abort_other_plans, m_class_options.GetName().c_str(),
558 m_class_options.GetStructuredData(), bool_stop_other_threads,
559 new_plan_status);
560 } else {
561 result.AppendError("step type is not supported");
562 return;
563 }
564
565 // If we got a new plan, then set it to be a controlling plan (User level
566 // Plans should be controlling plans so that they can be interruptible).
567 // Then resume the process.
568
569 if (new_plan_sp) {
570 new_plan_sp->SetIsControllingPlan(true);
571 new_plan_sp->SetOkayToDiscard(false);
572
573 if (m_options.m_step_count > 1) {
574 if (!new_plan_sp->SetIterationCount(m_options.m_step_count)) {
575 result.AppendWarning(
576 "step operation does not support iteration count.");
577 }
578 }
579
580 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
581
582 const uint32_t iohandler_id = process->GetIOHandlerID();
583
584 StreamString stream;
586 if (synchronous_execution)
587 error = process->ResumeSynchronous(&stream);
588 else
589 error = process->Resume();
590
591 if (!error.Success()) {
592 result.AppendMessage(error.AsCString());
593 return;
594 }
595
596 // There is a race condition where this thread will return up the call
597 // stack to the main command handler and show an (lldb) prompt before
598 // HandlePrivateEvent (from PrivateStateThread) has a chance to call
599 // PushProcessIOHandler().
600 process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
601
602 if (synchronous_execution) {
603 // If any state changed events had anything to say, add that to the
604 // result
605 if (stream.GetSize() > 0)
606 result.AppendMessage(stream.GetString());
607
608 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
609 result.SetDidChangeProcessState(true);
611 } else {
613 }
614 } else {
615 result.SetError(new_plan_status);
616 }
617 }
618
623};
624
625// CommandObjectThreadContinue
626
628public:
631 interpreter, "thread continue",
632 "Continue execution of the current target process. One "
633 "or more threads may be specified, by default all "
634 "threads continue.",
635 nullptr,
636 eCommandRequiresThread | eCommandTryTargetAPILock |
637 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
639 }
640
641 ~CommandObjectThreadContinue() override = default;
642
643 void DoExecute(Args &command, CommandReturnObject &result) override {
644 bool synchronous_execution = m_interpreter.GetSynchronous();
645
646 Process *process = m_exe_ctx.GetProcessPtr();
647 if (process == nullptr) {
648 result.AppendError("no process exists. Cannot continue");
649 return;
650 }
651
652 StateType state = process->GetState();
653 if ((state == eStateCrashed) || (state == eStateStopped) ||
654 (state == eStateSuspended)) {
655 const size_t argc = command.GetArgumentCount();
656 if (argc > 0) {
657 // These two lines appear at the beginning of both blocks in this
658 // if..else, but that is because we need to release the lock before
659 // calling process->Resume below.
660 std::lock_guard<std::recursive_mutex> guard(
661 process->GetThreadList().GetMutex());
662 const uint32_t num_threads = process->GetThreadList().GetSize();
663 std::vector<Thread *> resume_threads;
664 for (auto &entry : command.entries()) {
665 uint32_t thread_idx;
666 if (entry.ref().getAsInteger(0, thread_idx)) {
668 "invalid thread index argument: \"%s\".\n", entry.c_str());
669 return;
670 }
671 Thread *thread =
672 process->GetThreadList().FindThreadByIndexID(thread_idx).get();
673
674 if (thread) {
675 resume_threads.push_back(thread);
676 } else {
677 result.AppendErrorWithFormat("invalid thread index %u.\n",
678 thread_idx);
679 return;
680 }
681 }
682
683 if (resume_threads.empty()) {
684 result.AppendError("no valid thread indexes were specified");
685 return;
686 } else {
687 if (resume_threads.size() == 1)
688 result.AppendMessageWithFormat("Resuming thread: ");
689 else
690 result.AppendMessageWithFormat("Resuming threads: ");
691
692 for (uint32_t idx = 0; idx < num_threads; ++idx) {
693 Thread *thread =
694 process->GetThreadList().GetThreadAtIndex(idx).get();
695 std::vector<Thread *>::iterator this_thread_pos =
696 find(resume_threads.begin(), resume_threads.end(), thread);
697
698 if (this_thread_pos != resume_threads.end()) {
699 resume_threads.erase(this_thread_pos);
700 if (!resume_threads.empty())
701 result.AppendMessageWithFormat("%u, ", thread->GetIndexID());
702 else
703 result.AppendMessageWithFormat("%u ", thread->GetIndexID());
704
705 const bool override_suspend = true;
706 thread->SetResumeState(eStateRunning, override_suspend);
707 } else {
709 }
710 }
711 result.AppendMessageWithFormat("in process %" PRIu64 "\n",
712 process->GetID());
713 }
714 } else {
715 // These two lines appear at the beginning of both blocks in this
716 // if..else, but that is because we need to release the lock before
717 // calling process->Resume below.
718 std::lock_guard<std::recursive_mutex> guard(
719 process->GetThreadList().GetMutex());
720 const uint32_t num_threads = process->GetThreadList().GetSize();
721 Thread *current_thread = GetDefaultThread();
722 if (current_thread == nullptr) {
723 result.AppendError("the process doesn't have a current thread");
724 return;
725 }
726 // Set the actions that the threads should each take when resuming
727 for (uint32_t idx = 0; idx < num_threads; ++idx) {
728 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
729 if (thread == current_thread) {
730 result.AppendMessageWithFormat("Resuming thread 0x%4.4" PRIx64
731 " in process %" PRIu64 "\n",
732 thread->GetID(), process->GetID());
733 const bool override_suspend = true;
734 thread->SetResumeState(eStateRunning, override_suspend);
735 } else {
737 }
738 }
739 }
740
741 StreamString stream;
743 if (synchronous_execution)
744 error = process->ResumeSynchronous(&stream);
745 else
746 error = process->Resume();
747
748 // We should not be holding the thread list lock when we do this.
749 if (error.Success()) {
750 result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
751 process->GetID());
752 if (synchronous_execution) {
753 // If any state changed events had anything to say, add that to the
754 // result
755 if (stream.GetSize() > 0)
756 result.AppendMessage(stream.GetString());
757
758 result.SetDidChangeProcessState(true);
760 } else {
762 }
763 } else {
764 result.AppendErrorWithFormat("Failed to resume process: %s\n",
765 error.AsCString());
766 }
767 } else {
769 "Process cannot be continued from its current state (%s).\n",
770 StateAsCString(state));
771 }
772 }
773};
774
775// CommandObjectThreadUntil
776
777#define LLDB_OPTIONS_thread_until
778#include "CommandOptions.inc"
779
781public:
782 class CommandOptions : public Options {
783 public:
786
788 // Keep default values of all options in one place: OptionParsingStarting
789 // ()
790 OptionParsingStarting(nullptr);
791 }
792
793 ~CommandOptions() override = default;
794
795 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
796 ExecutionContext *execution_context) override {
798 const int short_option = m_getopt_table[option_idx].val;
799
800 switch (short_option) {
801 case 'a': {
803 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
804 if (error.Success())
805 m_until_addrs.push_back(tmp_addr);
806 } break;
807 case 't':
808 if (option_arg.getAsInteger(0, m_thread_idx)) {
810 error.SetErrorStringWithFormat("invalid thread index '%s'",
811 option_arg.str().c_str());
812 }
813 break;
814 case 'f':
815 if (option_arg.getAsInteger(0, m_frame_idx)) {
817 error.SetErrorStringWithFormat("invalid frame index '%s'",
818 option_arg.str().c_str());
819 }
820 break;
821 case 'm': {
822 auto enum_values = GetDefinitions()[option_idx].enum_values;
824 option_arg, enum_values, eOnlyDuringStepping, error);
825
826 if (error.Success()) {
827 if (run_mode == eAllThreads)
828 m_stop_others = false;
829 else
830 m_stop_others = true;
831 }
832 } break;
833 default:
834 llvm_unreachable("Unimplemented option");
835 }
836 return error;
837 }
838
839 void OptionParsingStarting(ExecutionContext *execution_context) override {
841 m_frame_idx = 0;
842 m_stop_others = false;
843 m_until_addrs.clear();
844 }
845
846 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
847 return llvm::ArrayRef(g_thread_until_options);
848 }
849
851 bool m_stop_others = false;
852 std::vector<lldb::addr_t> m_until_addrs;
853
854 // Instance variables to hold the values for command options.
855 };
856
859 interpreter, "thread until",
860 "Continue until a line number or address is reached by the "
861 "current or specified thread. Stops when returning from "
862 "the current function as a safety measure. "
863 "The target line number(s) are given as arguments, and if more "
864 "than one"
865 " is provided, stepping will stop when the first one is hit.",
866 nullptr,
867 eCommandRequiresThread | eCommandTryTargetAPILock |
868 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
870 }
871
872 ~CommandObjectThreadUntil() override = default;
873
874 Options *GetOptions() override { return &m_options; }
875
876protected:
877 void DoExecute(Args &command, CommandReturnObject &result) override {
878 bool synchronous_execution = m_interpreter.GetSynchronous();
879
880 Target *target = &GetTarget();
881
882 Process *process = m_exe_ctx.GetProcessPtr();
883 if (process == nullptr) {
884 result.AppendError("need a valid process to step");
885 } else {
886 Thread *thread = nullptr;
887 std::vector<uint32_t> line_numbers;
888
889 if (command.GetArgumentCount() >= 1) {
890 size_t num_args = command.GetArgumentCount();
891 for (size_t i = 0; i < num_args; i++) {
892 uint32_t line_number;
893 if (!llvm::to_integer(command.GetArgumentAtIndex(i), line_number)) {
894 result.AppendErrorWithFormat("invalid line number: '%s'.\n",
895 command.GetArgumentAtIndex(i));
896 return;
897 } else
898 line_numbers.push_back(line_number);
899 }
900 } else if (m_options.m_until_addrs.empty()) {
901 result.AppendErrorWithFormat("No line number or address provided:\n%s",
902 GetSyntax().str().c_str());
903 return;
904 }
905
907 thread = GetDefaultThread();
908 } else {
909 thread = process->GetThreadList()
911 .get();
912 }
913
914 if (thread == nullptr) {
915 const uint32_t num_threads = process->GetThreadList().GetSize();
917 "Thread index %u is out of range (valid values are 0 - %u).\n",
918 m_options.m_thread_idx, num_threads);
919 return;
920 }
921
922 const bool abort_other_plans = false;
923
924 StackFrame *frame =
926 if (frame == nullptr) {
928 "Frame index %u is out of range for thread id %" PRIu64 ".\n",
929 m_options.m_frame_idx, thread->GetID());
930 return;
931 }
932
933 ThreadPlanSP new_plan_sp;
934 Status new_plan_status;
935
936 if (frame->HasDebugInformation()) {
937 // Finally we got here... Translate the given line number to a bunch
938 // of addresses:
939 SymbolContext sc(frame->GetSymbolContext(eSymbolContextCompUnit));
940 LineTable *line_table = nullptr;
941 if (sc.comp_unit)
942 line_table = sc.comp_unit->GetLineTable();
943
944 if (line_table == nullptr) {
945 result.AppendErrorWithFormat("Failed to resolve the line table for "
946 "frame %u of thread id %" PRIu64 ".\n",
947 m_options.m_frame_idx, thread->GetID());
948 return;
949 }
950
951 LineEntry function_start;
952 uint32_t index_ptr = 0, end_ptr = UINT32_MAX;
953 std::vector<addr_t> address_list;
954
955 // Find the beginning & end index of the function, but first make
956 // sure it is valid:
957 if (!sc.function) {
958 result.AppendErrorWithFormat("Have debug information but no "
959 "function info - can't get until range.");
960 return;
961 }
962
963 AddressRange fun_addr_range = sc.function->GetAddressRange();
964 Address fun_start_addr = fun_addr_range.GetBaseAddress();
965 line_table->FindLineEntryByAddress(fun_start_addr, function_start,
966 &index_ptr);
967
968 Address fun_end_addr(fun_start_addr.GetSection(),
969 fun_start_addr.GetOffset() +
970 fun_addr_range.GetByteSize());
971
972 bool all_in_function = true;
973
974 line_table->FindLineEntryByAddress(fun_end_addr, function_start,
975 &end_ptr);
976
977 // Since not all source lines will contribute code, check if we are
978 // setting the breakpoint on the exact line number or the nearest
979 // subsequent line number and set breakpoints at all the line table
980 // entries of the chosen line number (exact or nearest subsequent).
981 for (uint32_t line_number : line_numbers) {
982 LineEntry line_entry;
983 bool exact = false;
984 uint32_t start_idx_ptr = index_ptr;
985 start_idx_ptr = sc.comp_unit->FindLineEntry(
986 index_ptr, line_number, nullptr, exact, &line_entry);
987 if (start_idx_ptr != UINT32_MAX)
988 line_number = line_entry.line;
989 exact = true;
990 start_idx_ptr = index_ptr;
991 while (start_idx_ptr <= end_ptr) {
992 start_idx_ptr = sc.comp_unit->FindLineEntry(
993 start_idx_ptr, line_number, nullptr, exact, &line_entry);
994 if (start_idx_ptr == UINT32_MAX)
995 break;
996
997 addr_t address =
998 line_entry.range.GetBaseAddress().GetLoadAddress(target);
999 if (address != LLDB_INVALID_ADDRESS) {
1000 if (fun_addr_range.ContainsLoadAddress(address, target))
1001 address_list.push_back(address);
1002 else
1003 all_in_function = false;
1004 }
1005 start_idx_ptr++;
1006 }
1007 }
1008
1009 for (lldb::addr_t address : m_options.m_until_addrs) {
1010 if (fun_addr_range.ContainsLoadAddress(address, target))
1011 address_list.push_back(address);
1012 else
1013 all_in_function = false;
1014 }
1015
1016 if (address_list.empty()) {
1017 if (all_in_function)
1018 result.AppendErrorWithFormat(
1019 "No line entries matching until target.\n");
1020 else
1021 result.AppendErrorWithFormat(
1022 "Until target outside of the current function.\n");
1023
1024 return;
1025 }
1026
1027 new_plan_sp = thread->QueueThreadPlanForStepUntil(
1028 abort_other_plans, &address_list.front(), address_list.size(),
1029 m_options.m_stop_others, m_options.m_frame_idx, new_plan_status);
1030 if (new_plan_sp) {
1031 // User level plans should be controlling plans so they can be
1032 // interrupted
1033 // (e.g. by hitting a breakpoint) and other plans executed by the
1034 // user (stepping around the breakpoint) and then a "continue" will
1035 // resume the original plan.
1036 new_plan_sp->SetIsControllingPlan(true);
1037 new_plan_sp->SetOkayToDiscard(false);
1038 } else {
1039 result.SetError(new_plan_status);
1040 return;
1041 }
1042 } else {
1043 result.AppendErrorWithFormat("Frame index %u of thread id %" PRIu64
1044 " has no debug information.\n",
1045 m_options.m_frame_idx, thread->GetID());
1046 return;
1047 }
1048
1049 if (!process->GetThreadList().SetSelectedThreadByID(thread->GetID())) {
1050 result.AppendErrorWithFormat(
1051 "Failed to set the selected thread to thread id %" PRIu64 ".\n",
1052 thread->GetID());
1053 return;
1054 }
1055
1056 StreamString stream;
1057 Status error;
1058 if (synchronous_execution)
1059 error = process->ResumeSynchronous(&stream);
1060 else
1061 error = process->Resume();
1062
1063 if (error.Success()) {
1064 result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
1065 process->GetID());
1066 if (synchronous_execution) {
1067 // If any state changed events had anything to say, add that to the
1068 // result
1069 if (stream.GetSize() > 0)
1070 result.AppendMessage(stream.GetString());
1071
1072 result.SetDidChangeProcessState(true);
1074 } else {
1076 }
1077 } else {
1078 result.AppendErrorWithFormat("Failed to resume process: %s.\n",
1079 error.AsCString());
1080 }
1081 }
1082 }
1083
1085};
1086
1087// CommandObjectThreadSelect
1088
1089#define LLDB_OPTIONS_thread_select
1090#include "CommandOptions.inc"
1091
1093public:
1095 public:
1097
1098 ~OptionGroupThreadSelect() override = default;
1099
1100 void OptionParsingStarting(ExecutionContext *execution_context) override {
1102 }
1103
1104 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1105 ExecutionContext *execution_context) override {
1106 const int short_option = g_thread_select_options[option_idx].short_option;
1107 switch (short_option) {
1108 case 't': {
1109 if (option_arg.getAsInteger(0, m_thread_id)) {
1111 return Status("Invalid thread ID: '%s'.", option_arg.str().c_str());
1112 }
1113 break;
1114 }
1115
1116 default:
1117 llvm_unreachable("Unimplemented option");
1118 }
1119
1120 return {};
1121 }
1122
1123 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1124 return llvm::ArrayRef(g_thread_select_options);
1125 }
1126
1128 };
1129
1131 : CommandObjectParsed(interpreter, "thread select",
1132 "Change the currently selected thread.",
1133 "thread select <thread-index> (or -t <thread-id>)",
1134 eCommandRequiresProcess | eCommandTryTargetAPILock |
1135 eCommandProcessMustBeLaunched |
1136 eCommandProcessMustBePaused) {
1138 CommandArgumentData thread_idx_arg;
1139
1140 // Define the first (and only) variant of this arg.
1141 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1142 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1143 thread_idx_arg.arg_opt_set_association = LLDB_OPT_SET_1;
1144
1145 // There is only one variant this argument could be; put it into the
1146 // argument entry.
1147 arg.push_back(thread_idx_arg);
1148
1149 // Push the data for the first argument into the m_arguments vector.
1150 m_arguments.push_back(arg);
1151
1154 }
1155
1156 ~CommandObjectThreadSelect() override = default;
1157
1158 void
1160 OptionElementVector &opt_element_vector) override {
1161 if (request.GetCursorIndex())
1162 return;
1163
1166 nullptr);
1167 }
1168
1169 Options *GetOptions() override { return &m_option_group; }
1170
1171protected:
1172 void DoExecute(Args &command, CommandReturnObject &result) override {
1173 Process *process = m_exe_ctx.GetProcessPtr();
1174 if (process == nullptr) {
1175 result.AppendError("no process");
1176 return;
1178 command.GetArgumentCount() != 1) {
1179 result.AppendErrorWithFormat(
1180 "'%s' takes exactly one thread index argument, or a thread ID "
1181 "option:\nUsage: %s\n",
1182 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1183 return;
1185 command.GetArgumentCount() != 0) {
1186 result.AppendErrorWithFormat("'%s' cannot take both a thread ID option "
1187 "and a thread index argument:\nUsage: %s\n",
1188 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1189 return;
1190 }
1191
1192 Thread *new_thread = nullptr;
1193 if (command.GetArgumentCount() == 1) {
1194 uint32_t index_id;
1195 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
1196 result.AppendErrorWithFormat("Invalid thread index '%s'",
1197 command.GetArgumentAtIndex(0));
1198 return;
1199 }
1200 new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1201 if (new_thread == nullptr) {
1202 result.AppendErrorWithFormat("Invalid thread index #%s.\n",
1203 command.GetArgumentAtIndex(0));
1204 return;
1205 }
1206 } else {
1207 new_thread =
1209 if (new_thread == nullptr) {
1210 result.AppendErrorWithFormat("Invalid thread ID %" PRIu64 ".\n",
1212 return;
1213 }
1214 }
1215
1216 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1218 }
1219
1222};
1223
1224// CommandObjectThreadList
1225
1227public:
1230 interpreter, "thread list",
1231 "Show a summary of each thread in the current target process. "
1232 "Use 'settings set thread-format' to customize the individual "
1233 "thread listings.",
1234 "thread list",
1235 eCommandRequiresProcess | eCommandTryTargetAPILock |
1236 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1237
1238 ~CommandObjectThreadList() override = default;
1239
1240protected:
1241 void DoExecute(Args &command, CommandReturnObject &result) override {
1242 Stream &strm = result.GetOutputStream();
1244 Process *process = m_exe_ctx.GetProcessPtr();
1245 const bool only_threads_with_stop_reason = false;
1246 const uint32_t start_frame = 0;
1247 const uint32_t num_frames = 0;
1248 const uint32_t num_frames_with_source = 0;
1249 process->GetStatus(strm);
1250 process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1251 num_frames, num_frames_with_source, false);
1252 }
1253};
1254
1255// CommandObjectThreadInfo
1256#define LLDB_OPTIONS_thread_info
1257#include "CommandOptions.inc"
1258
1260public:
1261 class CommandOptions : public Options {
1262 public:
1264
1265 ~CommandOptions() override = default;
1266
1267 void OptionParsingStarting(ExecutionContext *execution_context) override {
1268 m_json_thread = false;
1269 m_json_stopinfo = false;
1270 }
1271
1272 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1273 ExecutionContext *execution_context) override {
1274 const int short_option = m_getopt_table[option_idx].val;
1275 Status error;
1276
1277 switch (short_option) {
1278 case 'j':
1279 m_json_thread = true;
1280 break;
1281
1282 case 's':
1283 m_json_stopinfo = true;
1284 break;
1285
1286 default:
1287 llvm_unreachable("Unimplemented option");
1288 }
1289 return error;
1290 }
1291
1292 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1293 return llvm::ArrayRef(g_thread_info_options);
1294 }
1295
1298 };
1299
1302 interpreter, "thread info",
1303 "Show an extended summary of one or "
1304 "more threads. Defaults to the "
1305 "current thread.",
1306 "thread info",
1307 eCommandRequiresProcess | eCommandTryTargetAPILock |
1308 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
1309 m_add_return = false;
1310 }
1311
1312 ~CommandObjectThreadInfo() override = default;
1313
1314 void
1316 OptionElementVector &opt_element_vector) override {
1319 nullptr);
1320 }
1321
1322 Options *GetOptions() override { return &m_options; }
1323
1325 ThreadSP thread_sp =
1327 if (!thread_sp) {
1328 result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1329 tid);
1330 return false;
1331 }
1332
1333 Thread *thread = thread_sp.get();
1334
1335 Stream &strm = result.GetOutputStream();
1336 if (!thread->GetDescription(strm, eDescriptionLevelFull,
1339 result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1340 thread->GetIndexID());
1341 return false;
1342 }
1343 return true;
1344 }
1345
1347};
1348
1349// CommandObjectThreadException
1350
1352public:
1355 interpreter, "thread exception",
1356 "Display the current exception object for a thread. Defaults to "
1357 "the current thread.",
1358 "thread exception",
1359 eCommandRequiresProcess | eCommandTryTargetAPILock |
1360 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1361
1362 ~CommandObjectThreadException() override = default;
1363
1364 void
1366 OptionElementVector &opt_element_vector) override {
1369 nullptr);
1370 }
1371
1373 ThreadSP thread_sp =
1375 if (!thread_sp) {
1376 result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1377 tid);
1378 return false;
1379 }
1380
1381 Stream &strm = result.GetOutputStream();
1382 ValueObjectSP exception_object_sp = thread_sp->GetCurrentException();
1383 if (exception_object_sp) {
1384 if (llvm::Error error = exception_object_sp->Dump(strm)) {
1385 result.AppendError(toString(std::move(error)));
1386 return false;
1387 }
1388 }
1389
1390 ThreadSP exception_thread_sp = thread_sp->GetCurrentExceptionBacktrace();
1391 if (exception_thread_sp && exception_thread_sp->IsValid()) {
1392 const uint32_t num_frames_with_source = 0;
1393 const bool stop_format = false;
1394 exception_thread_sp->GetStatus(strm, 0, UINT32_MAX,
1395 num_frames_with_source, stop_format);
1396 }
1397
1398 return true;
1399 }
1400};
1401
1403public:
1406 interpreter, "thread siginfo",
1407 "Display the current siginfo object for a thread. Defaults to "
1408 "the current thread.",
1409 "thread siginfo",
1410 eCommandRequiresProcess | eCommandTryTargetAPILock |
1411 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1412
1413 ~CommandObjectThreadSiginfo() override = default;
1414
1415 void
1417 OptionElementVector &opt_element_vector) override {
1420 nullptr);
1421 }
1422
1424 ThreadSP thread_sp =
1426 if (!thread_sp) {
1427 result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1428 tid);
1429 return false;
1430 }
1431
1432 Stream &strm = result.GetOutputStream();
1433 if (!thread_sp->GetDescription(strm, eDescriptionLevelFull, false, false)) {
1434 result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1435 thread_sp->GetIndexID());
1436 return false;
1437 }
1438 ValueObjectSP exception_object_sp = thread_sp->GetSiginfoValue();
1439 if (exception_object_sp) {
1440 if (llvm::Error error = exception_object_sp->Dump(strm)) {
1441 result.AppendError(toString(std::move(error)));
1442 return false;
1443 }
1444 } else
1445 strm.Printf("(no siginfo)\n");
1446 strm.PutChar('\n');
1447
1448 return true;
1449 }
1450};
1451
1452// CommandObjectThreadReturn
1453#define LLDB_OPTIONS_thread_return
1454#include "CommandOptions.inc"
1455
1457public:
1458 class CommandOptions : public Options {
1459 public:
1461 // Keep default values of all options in one place: OptionParsingStarting
1462 // ()
1463 OptionParsingStarting(nullptr);
1464 }
1465
1466 ~CommandOptions() override = default;
1467
1468 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1469 ExecutionContext *execution_context) override {
1470 Status error;
1471 const int short_option = m_getopt_table[option_idx].val;
1472
1473 switch (short_option) {
1474 case 'x': {
1475 bool success;
1476 bool tmp_value =
1477 OptionArgParser::ToBoolean(option_arg, false, &success);
1478 if (success)
1479 m_from_expression = tmp_value;
1480 else {
1481 error.SetErrorStringWithFormat(
1482 "invalid boolean value '%s' for 'x' option",
1483 option_arg.str().c_str());
1484 }
1485 } break;
1486 default:
1487 llvm_unreachable("Unimplemented option");
1488 }
1489 return error;
1490 }
1491
1492 void OptionParsingStarting(ExecutionContext *execution_context) override {
1493 m_from_expression = false;
1494 }
1495
1496 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1497 return llvm::ArrayRef(g_thread_return_options);
1498 }
1499
1500 bool m_from_expression = false;
1501
1502 // Instance variables to hold the values for command options.
1503 };
1504
1506 : CommandObjectRaw(interpreter, "thread return",
1507 "Prematurely return from a stack frame, "
1508 "short-circuiting execution of newer frames "
1509 "and optionally yielding a specified value. Defaults "
1510 "to the exiting the current stack "
1511 "frame.",
1512 "thread return",
1513 eCommandRequiresFrame | eCommandTryTargetAPILock |
1514 eCommandProcessMustBeLaunched |
1515 eCommandProcessMustBePaused) {
1517 }
1518
1519 ~CommandObjectThreadReturn() override = default;
1520
1521 Options *GetOptions() override { return &m_options; }
1522
1523protected:
1524 void DoExecute(llvm::StringRef command,
1525 CommandReturnObject &result) override {
1526 // I am going to handle this by hand, because I don't want you to have to
1527 // say:
1528 // "thread return -- -5".
1529 if (command.starts_with("-x")) {
1530 if (command.size() != 2U)
1531 result.AppendWarning("Return values ignored when returning from user "
1532 "called expressions");
1533
1534 Thread *thread = m_exe_ctx.GetThreadPtr();
1535 Status error;
1536 error = thread->UnwindInnermostExpression();
1537 if (!error.Success()) {
1538 result.AppendErrorWithFormat("Unwinding expression failed - %s.",
1539 error.AsCString());
1540 } else {
1541 bool success =
1543 if (success) {
1547 } else {
1548 result.AppendErrorWithFormat(
1549 "Could not select 0th frame after unwinding expression.");
1550 }
1551 }
1552 return;
1553 }
1554
1555 ValueObjectSP return_valobj_sp;
1556
1557 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1558 uint32_t frame_idx = frame_sp->GetFrameIndex();
1559
1560 if (frame_sp->IsInlined()) {
1561 result.AppendError("Don't know how to return from inlined frames.");
1562 return;
1563 }
1564
1565 if (!command.empty()) {
1566 Target *target = m_exe_ctx.GetTargetPtr();
1568
1569 options.SetUnwindOnError(true);
1571
1573 exe_results = target->EvaluateExpression(command, frame_sp.get(),
1574 return_valobj_sp, options);
1575 if (exe_results != eExpressionCompleted) {
1576 if (return_valobj_sp)
1577 result.AppendErrorWithFormat(
1578 "Error evaluating result expression: %s",
1579 return_valobj_sp->GetError().AsCString());
1580 else
1581 result.AppendErrorWithFormat(
1582 "Unknown error evaluating result expression.");
1583 return;
1584 }
1585 }
1586
1587 Status error;
1588 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1589 const bool broadcast = true;
1590 error = thread_sp->ReturnFromFrame(frame_sp, return_valobj_sp, broadcast);
1591 if (!error.Success()) {
1592 result.AppendErrorWithFormat(
1593 "Error returning from frame %d of thread %d: %s.", frame_idx,
1594 thread_sp->GetIndexID(), error.AsCString());
1595 return;
1596 }
1597
1599 }
1600
1602};
1603
1604// CommandObjectThreadJump
1605#define LLDB_OPTIONS_thread_jump
1606#include "CommandOptions.inc"
1607
1609public:
1610 class CommandOptions : public Options {
1611 public:
1613
1614 ~CommandOptions() override = default;
1615
1616 void OptionParsingStarting(ExecutionContext *execution_context) override {
1618 m_line_num = 0;
1619 m_line_offset = 0;
1621 m_force = false;
1622 }
1623
1624 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1625 ExecutionContext *execution_context) override {
1626 const int short_option = m_getopt_table[option_idx].val;
1627 Status error;
1628
1629 switch (short_option) {
1630 case 'f':
1631 m_filenames.AppendIfUnique(FileSpec(option_arg));
1632 if (m_filenames.GetSize() > 1)
1633 return Status("only one source file expected.");
1634 break;
1635 case 'l':
1636 if (option_arg.getAsInteger(0, m_line_num))
1637 return Status("invalid line number: '%s'.", option_arg.str().c_str());
1638 break;
1639 case 'b':
1640 if (option_arg.getAsInteger(0, m_line_offset))
1641 return Status("invalid line offset: '%s'.", option_arg.str().c_str());
1642 break;
1643 case 'a':
1644 m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
1646 break;
1647 case 'r':
1648 m_force = true;
1649 break;
1650 default:
1651 llvm_unreachable("Unimplemented option");
1652 }
1653 return error;
1654 }
1655
1656 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1657 return llvm::ArrayRef(g_thread_jump_options);
1658 }
1659
1661 uint32_t m_line_num;
1665 };
1666
1669 interpreter, "thread jump",
1670 "Sets the program counter to a new address.", "thread jump",
1671 eCommandRequiresFrame | eCommandTryTargetAPILock |
1672 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1673
1674 ~CommandObjectThreadJump() override = default;
1675
1676 Options *GetOptions() override { return &m_options; }
1677
1678protected:
1679 void DoExecute(Args &args, CommandReturnObject &result) override {
1681 StackFrame *frame = m_exe_ctx.GetFramePtr();
1682 Thread *thread = m_exe_ctx.GetThreadPtr();
1683 Target *target = m_exe_ctx.GetTargetPtr();
1684 const SymbolContext &sym_ctx =
1685 frame->GetSymbolContext(eSymbolContextLineEntry);
1686
1688 // Use this address directly.
1690
1691 lldb::addr_t callAddr = dest.GetCallableLoadAddress(target);
1692 if (callAddr == LLDB_INVALID_ADDRESS) {
1693 result.AppendErrorWithFormat("Invalid destination address.");
1694 return;
1695 }
1696
1697 if (!reg_ctx->SetPC(callAddr)) {
1698 result.AppendErrorWithFormat("Error changing PC value for thread %d.",
1699 thread->GetIndexID());
1700 return;
1701 }
1702 } else {
1703 // Pick either the absolute line, or work out a relative one.
1704 int32_t line = (int32_t)m_options.m_line_num;
1705 if (line == 0)
1706 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1707
1708 // Try the current file, but override if asked.
1709 FileSpec file = sym_ctx.line_entry.GetFile();
1710 if (m_options.m_filenames.GetSize() == 1)
1712
1713 if (!file) {
1714 result.AppendErrorWithFormat(
1715 "No source file available for the current location.");
1716 return;
1717 }
1718
1719 std::string warnings;
1720 Status err = thread->JumpToLine(file, line, m_options.m_force, &warnings);
1721
1722 if (err.Fail()) {
1723 result.SetError(err);
1724 return;
1725 }
1726
1727 if (!warnings.empty())
1728 result.AppendWarning(warnings.c_str());
1729 }
1730
1732 }
1733
1735};
1736
1737// Next are the subcommands of CommandObjectMultiwordThreadPlan
1738
1739// CommandObjectThreadPlanList
1740#define LLDB_OPTIONS_thread_plan_list
1741#include "CommandOptions.inc"
1742
1744public:
1745 class CommandOptions : public Options {
1746 public:
1748 // Keep default values of all options in one place: OptionParsingStarting
1749 // ()
1750 OptionParsingStarting(nullptr);
1751 }
1752
1753 ~CommandOptions() override = default;
1754
1755 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1756 ExecutionContext *execution_context) override {
1757 const int short_option = m_getopt_table[option_idx].val;
1758
1759 switch (short_option) {
1760 case 'i':
1761 m_internal = true;
1762 break;
1763 case 't':
1764 lldb::tid_t tid;
1765 if (option_arg.getAsInteger(0, tid))
1766 return Status("invalid tid: '%s'.", option_arg.str().c_str());
1767 m_tids.push_back(tid);
1768 break;
1769 case 'u':
1770 m_unreported = false;
1771 break;
1772 case 'v':
1773 m_verbose = true;
1774 break;
1775 default:
1776 llvm_unreachable("Unimplemented option");
1777 }
1778 return {};
1779 }
1780
1781 void OptionParsingStarting(ExecutionContext *execution_context) override {
1782 m_verbose = false;
1783 m_internal = false;
1784 m_unreported = true; // The variable is "skip unreported" and we want to
1785 // skip unreported by default.
1786 m_tids.clear();
1787 }
1788
1789 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1790 return llvm::ArrayRef(g_thread_plan_list_options);
1791 }
1792
1793 // Instance variables to hold the values for command options.
1797 std::vector<lldb::tid_t> m_tids;
1798 };
1799
1802 interpreter, "thread plan list",
1803 "Show thread plans for one or more threads. If no threads are "
1804 "specified, show the "
1805 "current thread. Use the thread-index \"all\" to see all threads.",
1806 nullptr,
1807 eCommandRequiresProcess | eCommandRequiresThread |
1808 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
1809 eCommandProcessMustBePaused) {}
1810
1811 ~CommandObjectThreadPlanList() override = default;
1812
1813 Options *GetOptions() override { return &m_options; }
1814
1815 void DoExecute(Args &command, CommandReturnObject &result) override {
1816 // If we are reporting all threads, dispatch to the Process to do that:
1817 if (command.GetArgumentCount() == 0 && m_options.m_tids.empty()) {
1818 Stream &strm = result.GetOutputStream();
1823 strm, desc_level, m_options.m_internal, true, m_options.m_unreported);
1825 return;
1826 } else {
1827 // Do any TID's that the user may have specified as TID, then do any
1828 // Thread Indexes...
1829 if (!m_options.m_tids.empty()) {
1830 Process *process = m_exe_ctx.GetProcessPtr();
1831 StreamString tmp_strm;
1832 for (lldb::tid_t tid : m_options.m_tids) {
1833 bool success = process->DumpThreadPlansForTID(
1835 true /* condense_trivial */, m_options.m_unreported);
1836 // If we didn't find a TID, stop here and return an error.
1837 if (!success) {
1838 result.AppendError("Error dumping plans:");
1839 result.AppendError(tmp_strm.GetString());
1840 return;
1841 }
1842 // Otherwise, add our data to the output:
1843 result.GetOutputStream() << tmp_strm.GetString();
1844 }
1845 }
1846 return CommandObjectIterateOverThreads::DoExecute(command, result);
1847 }
1848 }
1849
1850protected:
1852 // If we have already handled this from a -t option, skip it here.
1853 if (llvm::is_contained(m_options.m_tids, tid))
1854 return true;
1855
1856 Process *process = m_exe_ctx.GetProcessPtr();
1857
1858 Stream &strm = result.GetOutputStream();
1860 if (m_options.m_verbose)
1861 desc_level = eDescriptionLevelVerbose;
1862
1863 process->DumpThreadPlansForTID(strm, tid, desc_level, m_options.m_internal,
1864 true /* condense_trivial */,
1866 return true;
1867 }
1868
1870};
1871
1873public:
1875 : CommandObjectParsed(interpreter, "thread plan discard",
1876 "Discards thread plans up to and including the "
1877 "specified index (see 'thread plan list'.) "
1878 "Only user visible plans can be discarded.",
1879 nullptr,
1880 eCommandRequiresProcess | eCommandRequiresThread |
1881 eCommandTryTargetAPILock |
1882 eCommandProcessMustBeLaunched |
1883 eCommandProcessMustBePaused) {
1885 }
1886
1888
1889 void
1891 OptionElementVector &opt_element_vector) override {
1892 if (!m_exe_ctx.HasThreadScope() || request.GetCursorIndex())
1893 return;
1894
1896 }
1897
1898 void DoExecute(Args &args, CommandReturnObject &result) override {
1899 Thread *thread = m_exe_ctx.GetThreadPtr();
1900 if (args.GetArgumentCount() != 1) {
1901 result.AppendErrorWithFormat("Too many arguments, expected one - the "
1902 "thread plan index - but got %zu.",
1903 args.GetArgumentCount());
1904 return;
1905 }
1906
1907 uint32_t thread_plan_idx;
1908 if (!llvm::to_integer(args.GetArgumentAtIndex(0), thread_plan_idx)) {
1909 result.AppendErrorWithFormat(
1910 "Invalid thread index: \"%s\" - should be unsigned int.",
1911 args.GetArgumentAtIndex(0));
1912 return;
1913 }
1914
1915 if (thread_plan_idx == 0) {
1916 result.AppendErrorWithFormat(
1917 "You wouldn't really want me to discard the base thread plan.");
1918 return;
1919 }
1920
1921 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) {
1923 } else {
1924 result.AppendErrorWithFormat(
1925 "Could not find User thread plan with index %s.",
1926 args.GetArgumentAtIndex(0));
1927 }
1928 }
1929};
1930
1932public:
1934 : CommandObjectParsed(interpreter, "thread plan prune",
1935 "Removes any thread plans associated with "
1936 "currently unreported threads. "
1937 "Specify one or more TID's to remove, or if no "
1938 "TID's are provides, remove threads for all "
1939 "unreported threads",
1940 nullptr,
1941 eCommandRequiresProcess |
1942 eCommandTryTargetAPILock |
1943 eCommandProcessMustBeLaunched |
1944 eCommandProcessMustBePaused) {
1946 }
1947
1948 ~CommandObjectThreadPlanPrune() override = default;
1949
1950 void DoExecute(Args &args, CommandReturnObject &result) override {
1951 Process *process = m_exe_ctx.GetProcessPtr();
1952
1953 if (args.GetArgumentCount() == 0) {
1954 process->PruneThreadPlans();
1956 return;
1957 }
1958
1959 const size_t num_args = args.GetArgumentCount();
1960
1961 std::lock_guard<std::recursive_mutex> guard(
1962 process->GetThreadList().GetMutex());
1963
1964 for (size_t i = 0; i < num_args; i++) {
1965 lldb::tid_t tid;
1966 if (!llvm::to_integer(args.GetArgumentAtIndex(i), tid)) {
1967 result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
1968 args.GetArgumentAtIndex(i));
1969 return;
1970 }
1971 if (!process->PruneThreadPlansForTID(tid)) {
1972 result.AppendErrorWithFormat("Could not find unreported tid: \"%s\"\n",
1973 args.GetArgumentAtIndex(i));
1974 return;
1975 }
1976 }
1978 }
1979};
1980
1981// CommandObjectMultiwordThreadPlan
1982
1984public:
1987 interpreter, "plan",
1988 "Commands for managing thread plans that control execution.",
1989 "thread plan <subcommand> [<subcommand objects]") {
1991 "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter)));
1993 "discard",
1996 "prune",
1998 }
1999
2001};
2002
2003// Next are the subcommands of CommandObjectMultiwordTrace
2004
2005// CommandObjectTraceExport
2006
2008public:
2011 interpreter, "trace thread export",
2012 "Commands for exporting traces of the threads in the current "
2013 "process to different formats.",
2014 "thread trace export <export-plugin> [<subcommand objects>]") {
2015
2016 unsigned i = 0;
2017 for (llvm::StringRef plugin_name =
2019 !plugin_name.empty();
2021 if (ThreadTraceExportCommandCreator command_creator =
2023 LoadSubCommand(plugin_name, command_creator(interpreter));
2024 }
2025 }
2026 }
2027};
2028
2029// CommandObjectTraceStart
2030
2032public:
2035 /*live_debug_session_only=*/true, interpreter, "thread trace start",
2036 "Start tracing threads with the corresponding trace "
2037 "plug-in for the current process.",
2038 "thread trace start [<trace-options>]") {}
2039
2040protected:
2043 }
2044};
2045
2046// CommandObjectTraceStop
2047
2049public:
2052 interpreter, "thread trace stop",
2053 "Stop tracing threads, including the ones traced with the "
2054 "\"process trace start\" command."
2055 "Defaults to the current thread. Thread indices can be "
2056 "specified as arguments.\n Use the thread-index \"all\" to stop "
2057 "tracing "
2058 "for all existing threads.",
2059 "thread trace stop [<thread-index> <thread-index> ...]",
2060 eCommandRequiresProcess | eCommandTryTargetAPILock |
2061 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
2062 eCommandProcessMustBeTraced) {}
2063
2064 ~CommandObjectTraceStop() override = default;
2065
2067 llvm::ArrayRef<lldb::tid_t> tids) override {
2068 ProcessSP process_sp = m_exe_ctx.GetProcessSP();
2069
2070 TraceSP trace_sp = process_sp->GetTarget().GetTrace();
2071
2072 if (llvm::Error err = trace_sp->Stop(tids))
2073 result.AppendError(toString(std::move(err)));
2074 else
2076
2077 return result.Succeeded();
2078 }
2079};
2080
2082 CommandReturnObject &result) {
2083 if (args.GetArgumentCount() == 0)
2084 return exe_ctx.GetThreadSP();
2085
2086 const char *arg = args.GetArgumentAtIndex(0);
2087 uint32_t thread_idx;
2088
2089 if (!llvm::to_integer(arg, thread_idx)) {
2090 result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", arg);
2091 return nullptr;
2092 }
2093 ThreadSP thread_sp =
2094 exe_ctx.GetProcessRef().GetThreadList().FindThreadByIndexID(thread_idx);
2095 if (!thread_sp)
2096 result.AppendErrorWithFormat("no thread with index: \"%s\"\n", arg);
2097 return thread_sp;
2098}
2099
2100// CommandObjectTraceDumpFunctionCalls
2101#define LLDB_OPTIONS_thread_trace_dump_function_calls
2102#include "CommandOptions.inc"
2103
2105public:
2106 class CommandOptions : public Options {
2107 public:
2109
2110 ~CommandOptions() override = default;
2111
2112 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2113 ExecutionContext *execution_context) override {
2114 Status error;
2115 const int short_option = m_getopt_table[option_idx].val;
2116
2117 switch (short_option) {
2118 case 'j': {
2119 m_dumper_options.json = true;
2120 break;
2121 }
2122 case 'J': {
2123 m_dumper_options.json = true;
2125 break;
2126 }
2127 case 'F': {
2128 m_output_file.emplace(option_arg);
2129 break;
2130 }
2131 default:
2132 llvm_unreachable("Unimplemented option");
2133 }
2134 return error;
2135 }
2136
2137 void OptionParsingStarting(ExecutionContext *execution_context) override {
2138 m_dumper_options = {};
2139 m_output_file = std::nullopt;
2140 }
2141
2142 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2143 return llvm::ArrayRef(g_thread_trace_dump_function_calls_options);
2144 }
2145
2146 static const size_t kDefaultCount = 20;
2147
2148 // Instance variables to hold the values for command options.
2150 std::optional<FileSpec> m_output_file;
2151 };
2152
2155 interpreter, "thread trace dump function-calls",
2156 "Dump the traced function-calls for one thread. If no "
2157 "thread is specified, the current thread is used.",
2158 nullptr,
2159 eCommandRequiresProcess | eCommandRequiresThread |
2160 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
2161 eCommandProcessMustBePaused | eCommandProcessMustBeTraced) {
2163 }
2164
2166
2167 Options *GetOptions() override { return &m_options; }
2168
2169protected:
2170 void DoExecute(Args &args, CommandReturnObject &result) override {
2171 ThreadSP thread_sp = GetSingleThreadFromArgs(m_exe_ctx, args, result);
2172 if (!thread_sp) {
2173 result.AppendError("invalid thread\n");
2174 return;
2175 }
2176
2177 llvm::Expected<TraceCursorSP> cursor_or_error =
2178 m_exe_ctx.GetTargetSP()->GetTrace()->CreateNewCursor(*thread_sp);
2179
2180 if (!cursor_or_error) {
2181 result.AppendError(llvm::toString(cursor_or_error.takeError()));
2182 return;
2183 }
2184 TraceCursorSP &cursor_sp = *cursor_or_error;
2185
2186 std::optional<StreamFile> out_file;
2188 out_file.emplace(m_options.m_output_file->GetPath().c_str(),
2191 }
2192
2194
2195 TraceDumper dumper(std::move(cursor_sp),
2196 out_file ? *out_file : result.GetOutputStream(),
2198
2199 dumper.DumpFunctionCalls();
2200 }
2201
2203};
2204
2205// CommandObjectTraceDumpInstructions
2206#define LLDB_OPTIONS_thread_trace_dump_instructions
2207#include "CommandOptions.inc"
2208
2210public:
2211 class CommandOptions : public Options {
2212 public:
2214
2215 ~CommandOptions() override = default;
2216
2217 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2218 ExecutionContext *execution_context) override {
2219 Status error;
2220 const int short_option = m_getopt_table[option_idx].val;
2221
2222 switch (short_option) {
2223 case 'c': {
2224 int32_t count;
2225 if (option_arg.empty() || option_arg.getAsInteger(0, count) ||
2226 count < 0)
2227 error.SetErrorStringWithFormat(
2228 "invalid integer value for option '%s'",
2229 option_arg.str().c_str());
2230 else
2231 m_count = count;
2232 break;
2233 }
2234 case 'a': {
2235 m_count = std::numeric_limits<decltype(m_count)>::max();
2236 break;
2237 }
2238 case 's': {
2239 int32_t skip;
2240 if (option_arg.empty() || option_arg.getAsInteger(0, skip) || skip < 0)
2241 error.SetErrorStringWithFormat(
2242 "invalid integer value for option '%s'",
2243 option_arg.str().c_str());
2244 else
2245 m_dumper_options.skip = skip;
2246 break;
2247 }
2248 case 'i': {
2249 uint64_t id;
2250 if (option_arg.empty() || option_arg.getAsInteger(0, id))
2251 error.SetErrorStringWithFormat(
2252 "invalid integer value for option '%s'",
2253 option_arg.str().c_str());
2254 else
2256 break;
2257 }
2258 case 'F': {
2259 m_output_file.emplace(option_arg);
2260 break;
2261 }
2262 case 'r': {
2263 m_dumper_options.raw = true;
2264 break;
2265 }
2266 case 'f': {
2268 break;
2269 }
2270 case 'k': {
2272 break;
2273 }
2274 case 't': {
2276 break;
2277 }
2278 case 'e': {
2280 break;
2281 }
2282 case 'j': {
2283 m_dumper_options.json = true;
2284 break;
2285 }
2286 case 'J': {
2288 m_dumper_options.json = true;
2289 break;
2290 }
2291 case 'E': {
2294 break;
2295 }
2296 case 'C': {
2297 m_continue = true;
2298 break;
2299 }
2300 default:
2301 llvm_unreachable("Unimplemented option");
2302 }
2303 return error;
2304 }
2305
2306 void OptionParsingStarting(ExecutionContext *execution_context) override {
2308 m_continue = false;
2309 m_output_file = std::nullopt;
2310 m_dumper_options = {};
2311 }
2312
2313 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2314 return llvm::ArrayRef(g_thread_trace_dump_instructions_options);
2315 }
2316
2317 static const size_t kDefaultCount = 20;
2318
2319 // Instance variables to hold the values for command options.
2320 size_t m_count;
2322 std::optional<FileSpec> m_output_file;
2324 };
2325
2328 interpreter, "thread trace dump instructions",
2329 "Dump the traced instructions for one thread. If no "
2330 "thread is specified, show the current thread.",
2331 nullptr,
2332 eCommandRequiresProcess | eCommandRequiresThread |
2333 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
2334 eCommandProcessMustBePaused | eCommandProcessMustBeTraced) {
2336 }
2337
2339
2340 Options *GetOptions() override { return &m_options; }
2341
2342 std::optional<std::string> GetRepeatCommand(Args &current_command_args,
2343 uint32_t index) override {
2344 std::string cmd;
2345 current_command_args.GetCommandString(cmd);
2346 if (cmd.find(" --continue") == std::string::npos)
2347 cmd += " --continue";
2348 return cmd;
2349 }
2350
2351protected:
2352 void DoExecute(Args &args, CommandReturnObject &result) override {
2353 ThreadSP thread_sp = GetSingleThreadFromArgs(m_exe_ctx, args, result);
2354 if (!thread_sp) {
2355 result.AppendError("invalid thread\n");
2356 return;
2357 }
2358
2360 // We set up the options to continue one instruction past where
2361 // the previous iteration stopped.
2364 }
2365
2366 llvm::Expected<TraceCursorSP> cursor_or_error =
2367 m_exe_ctx.GetTargetSP()->GetTrace()->CreateNewCursor(*thread_sp);
2368
2369 if (!cursor_or_error) {
2370 result.AppendError(llvm::toString(cursor_or_error.takeError()));
2371 return;
2372 }
2373 TraceCursorSP &cursor_sp = *cursor_or_error;
2374
2376 !cursor_sp->HasId(*m_options.m_dumper_options.id)) {
2377 result.AppendError("invalid instruction id\n");
2378 return;
2379 }
2380
2381 std::optional<StreamFile> out_file;
2383 out_file.emplace(m_options.m_output_file->GetPath().c_str(),
2386 }
2387
2388 if (m_options.m_continue && !m_last_id) {
2389 // We need to stop processing data when we already ran out of instructions
2390 // in a previous command. We can fake this by setting the cursor past the
2391 // end of the trace.
2392 cursor_sp->Seek(1, lldb::eTraceCursorSeekTypeEnd);
2393 }
2394
2395 TraceDumper dumper(std::move(cursor_sp),
2396 out_file ? *out_file : result.GetOutputStream(),
2398
2400 }
2401
2403 // Last traversed id used to continue a repeat command. std::nullopt means
2404 // that all the trace has been consumed.
2405 std::optional<lldb::user_id_t> m_last_id;
2406};
2407
2408// CommandObjectTraceDumpInfo
2409#define LLDB_OPTIONS_thread_trace_dump_info
2410#include "CommandOptions.inc"
2411
2413public:
2414 class CommandOptions : public Options {
2415 public:
2417
2418 ~CommandOptions() override = default;
2419
2420 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2421 ExecutionContext *execution_context) override {
2422 Status error;
2423 const int short_option = m_getopt_table[option_idx].val;
2424
2425 switch (short_option) {
2426 case 'v': {
2427 m_verbose = true;
2428 break;
2429 }
2430 case 'j': {
2431 m_json = true;
2432 break;
2433 }
2434 default:
2435 llvm_unreachable("Unimplemented option");
2436 }
2437 return error;
2438 }
2439
2440 void OptionParsingStarting(ExecutionContext *execution_context) override {
2441 m_verbose = false;
2442 m_json = false;
2443 }
2444
2445 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2446 return llvm::ArrayRef(g_thread_trace_dump_info_options);
2447 }
2448
2449 // Instance variables to hold the values for command options.
2452 };
2453
2456 interpreter, "thread trace dump info",
2457 "Dump the traced information for one or more threads. If no "
2458 "threads are specified, show the current thread. Use the "
2459 "thread-index \"all\" to see all threads.",
2460 nullptr,
2461 eCommandRequiresProcess | eCommandTryTargetAPILock |
2462 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
2463 eCommandProcessMustBeTraced) {}
2464
2465 ~CommandObjectTraceDumpInfo() override = default;
2466
2467 Options *GetOptions() override { return &m_options; }
2468
2469protected:
2471 const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
2472 ThreadSP thread_sp =
2474 trace_sp->DumpTraceInfo(*thread_sp, result.GetOutputStream(),
2476 return true;
2477 }
2478
2480};
2481
2482// CommandObjectMultiwordTraceDump
2484public:
2487 interpreter, "dump",
2488 "Commands for displaying trace information of the threads "
2489 "in the current process.",
2490 "thread trace dump <subcommand> [<subcommand objects>]") {
2492 "instructions",
2495 "function-calls",
2498 "info", CommandObjectSP(new CommandObjectTraceDumpInfo(interpreter)));
2499 }
2501};
2502
2503// CommandObjectMultiwordTrace
2505public:
2508 interpreter, "trace",
2509 "Commands for operating on traces of the threads in the current "
2510 "process.",
2511 "thread trace <subcommand> [<subcommand objects>]") {
2513 interpreter)));
2514 LoadSubCommand("start",
2515 CommandObjectSP(new CommandObjectTraceStart(interpreter)));
2516 LoadSubCommand("stop",
2517 CommandObjectSP(new CommandObjectTraceStop(interpreter)));
2518 LoadSubCommand("export",
2519 CommandObjectSP(new CommandObjectTraceExport(interpreter)));
2520 }
2521
2522 ~CommandObjectMultiwordTrace() override = default;
2523};
2524
2525// CommandObjectMultiwordThread
2526
2528 CommandInterpreter &interpreter)
2529 : CommandObjectMultiword(interpreter, "thread",
2530 "Commands for operating on "
2531 "one or more threads in "
2532 "the current process.",
2533 "thread <subcommand> [<subcommand-options>]") {
2535 interpreter)));
2536 LoadSubCommand("continue",
2538 LoadSubCommand("list",
2539 CommandObjectSP(new CommandObjectThreadList(interpreter)));
2540 LoadSubCommand("return",
2541 CommandObjectSP(new CommandObjectThreadReturn(interpreter)));
2542 LoadSubCommand("jump",
2543 CommandObjectSP(new CommandObjectThreadJump(interpreter)));
2544 LoadSubCommand("select",
2545 CommandObjectSP(new CommandObjectThreadSelect(interpreter)));
2546 LoadSubCommand("until",
2547 CommandObjectSP(new CommandObjectThreadUntil(interpreter)));
2548 LoadSubCommand("info",
2549 CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
2551 interpreter)));
2552 LoadSubCommand("siginfo",
2554 LoadSubCommand("step-in",
2556 interpreter, "thread step-in",
2557 "Source level single step, stepping into calls. Defaults "
2558 "to current thread unless specified.",
2559 nullptr, eStepTypeInto)));
2560
2561 LoadSubCommand("step-out",
2563 interpreter, "thread step-out",
2564 "Finish executing the current stack frame and stop after "
2565 "returning. Defaults to current thread unless specified.",
2566 nullptr, eStepTypeOut)));
2567
2568 LoadSubCommand("step-over",
2570 interpreter, "thread step-over",
2571 "Source level single step, stepping over calls. Defaults "
2572 "to current thread unless specified.",
2573 nullptr, eStepTypeOver)));
2574
2575 LoadSubCommand("step-inst",
2577 interpreter, "thread step-inst",
2578 "Instruction level single step, stepping into calls. "
2579 "Defaults to current thread unless specified.",
2580 nullptr, eStepTypeTrace)));
2581
2582 LoadSubCommand("step-inst-over",
2584 interpreter, "thread step-inst-over",
2585 "Instruction level single step, stepping over calls. "
2586 "Defaults to current thread unless specified.",
2587 nullptr, eStepTypeTraceOver)));
2588
2590 "step-scripted",
2592 interpreter, "thread step-scripted",
2593 "Step as instructed by the script class passed in the -C option. "
2594 "You can also specify a dictionary of key (-k) and value (-v) pairs "
2595 "that will be used to populate an SBStructuredData Dictionary, which "
2596 "will be passed to the constructor of the class implementing the "
2597 "scripted step. See the Python Reference for more details.",
2598 nullptr, eStepTypeScripted)));
2599
2601 interpreter)));
2602 LoadSubCommand("trace",
2604}
2605
static ThreadSP GetSingleThreadFromArgs(ExecutionContext &exe_ctx, Args &args, CommandReturnObject &result)
static llvm::raw_ostream & error(Stream &strm)
#define INTERRUPT_REQUESTED(debugger,...)
This handy define will keep you from having to generate a report for the interruption by hand.
Definition: Debugger.h:446
~CommandObjectMultiwordThreadPlan() override=default
CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
~CommandObjectMultiwordTraceDump() override=default
CommandObjectMultiwordTraceDump(CommandInterpreter &interpreter)
CommandObjectMultiwordTrace(CommandInterpreter &interpreter)
~CommandObjectMultiwordTrace() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectThreadBacktrace(CommandInterpreter &interpreter)
std::optional< std::string > GetRepeatCommand(Args &current_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
void DoExtendedBacktrace(Thread *thread, CommandReturnObject &result)
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override
~CommandObjectThreadBacktrace() override=default
~CommandObjectThreadContinue() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectThreadContinue(CommandInterpreter &interpreter)
CommandObjectThreadException(CommandInterpreter &interpreter)
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override
~CommandObjectThreadException() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectThreadInfo(CommandInterpreter &interpreter)
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override
~CommandObjectThreadInfo() override=default
Options * GetOptions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectThreadJump(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectThreadJump() override=default
Options * GetOptions() override
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectThreadList() override=default
CommandObjectThreadList(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
~CommandObjectThreadPlanDiscard() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectThreadPlanList(CommandInterpreter &interpreter)
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override
~CommandObjectThreadPlanList() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectThreadPlanPrune(CommandInterpreter &interpreter)
~CommandObjectThreadPlanPrune() override=default
void DoExecute(Args &args, CommandReturnObject &result) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectThreadReturn(CommandInterpreter &interpreter)
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
~CommandObjectThreadReturn() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectThreadSelect(CommandInterpreter &interpreter)
~CommandObjectThreadSelect() override=default
OptionGroupThreadSelect m_options
~CommandObjectThreadSiginfo() override=default
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override
CommandObjectThreadSiginfo(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
OptionGroupPythonClassWithDict m_class_options
~CommandObjectThreadStepWithTypeAndScope() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectThreadStepWithTypeAndScope(CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, StepType step_type)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
Options * GetOptions() override
CommandObjectThreadUntil(CommandInterpreter &interpreter)
~CommandObjectThreadUntil() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTraceDumpFunctionCalls(CommandInterpreter &interpreter)
~CommandObjectTraceDumpFunctionCalls() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
~CommandObjectTraceDumpInfo() override=default
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override
CommandObjectTraceDumpInfo(CommandInterpreter &interpreter)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter)
~CommandObjectTraceDumpInstructions() override=default
std::optional< std::string > GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
void DoExecute(Args &args, CommandReturnObject &result) override
std::optional< lldb::user_id_t > m_last_id
CommandObjectTraceExport(CommandInterpreter &interpreter)
lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override
CommandObjectTraceStart(CommandInterpreter &interpreter)
~CommandObjectTraceStop() override=default
bool DoExecuteOnThreads(Args &command, CommandReturnObject &result, llvm::ArrayRef< lldb::tid_t > tids) override
CommandObjectTraceStop(CommandInterpreter &interpreter)
void OptionParsingStarting(ExecutionContext *execution_context) override
~ThreadStepScopeOptionGroup() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
A section + offset based address range class.
Definition: AddressRange.h:25
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:211
bool ContainsLoadAddress(const Address &so_addr, Target *target) const
Check if a section offset so_addr when represented as a load address is contained within this object'...
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
Definition: AddressRange.h:223
A section + offset based address class.
Definition: Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:313
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition: Address.cpp:338
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition: Address.h:439
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:293
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition: Address.h:329
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:355
A command line argument class.
Definition: Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.h:116
void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Replaces the argument value at index idx to arg_str if idx is a valid argument index.
Definition: Args.cpp:337
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
Definition: Args.cpp:322
llvm::ArrayRef< ArgEntry > entries() const
Definition: Args.h:128
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition: Args.cpp:263
bool GetCommandString(std::string &command) const
Definition: Args.cpp:211
bool GetQuotedCommandString(std::string &command) const
Definition: Args.cpp:228
A class that describes a single lexical block.
Definition: Block.h:41
bool GetRangeContainingAddress(const Address &addr, AddressRange &range)
Definition: Block.cpp:250
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
void DoExecute(Args &command, CommandReturnObject &result) override
Class similar to CommandObjectIterateOverThreads, but which performs an action on multiple threads at...
CommandObjectMultiwordThread(CommandInterpreter &interpreter)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
This class works by delegating the logic to the actual trace plug-in that can support the current pro...
std::vector< CommandArgumentData > CommandArgumentEntry
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
ExecutionContext m_exe_ctx
std::vector< CommandArgumentEntry > m_arguments
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
virtual void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector)
The default version handles argument definitions that have only one argument type,...
virtual llvm::StringRef GetSyntax()
void AppendMessage(llvm::StringRef in_string)
void void AppendError(llvm::StringRef in_string)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
void void AppendWarning(llvm::StringRef in_string)
void SetError(const Status &error, const char *fallback_error_cstr=nullptr)
uint32_t FindLineEntry(uint32_t start_idx, uint32_t line, const FileSpec *file_spec_ptr, bool exact, LineEntry *line_entry)
Find the line entry by line and optional inlined file spec.
LineTable * GetLineTable()
Get the line table for the compile unit.
"lldb/Utility/ArgCompletionRequest.h"
void SetUnwindOnError(bool unwind=false)
Definition: Target.h:348
void SetUseDynamic(lldb::DynamicValueType dynamic=lldb::eDynamicCanRunTarget)
Definition: Target.h:363
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void SetFrameSP(const lldb::StackFrameSP &frame_sp)
Set accessor to set only the frame shared pointer.
bool HasThreadScope() const
Returns true the ExecutionContext object contains a valid target, process, and thread.
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
const lldb::StackFrameSP & GetFrameSP() const
Get accessor to get the frame shared pointer.
Process & GetProcessRef() const
Returns a reference to the process object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
Process * GetProcessPtr() const
Returns a pointer to the process object.
RegisterContext * GetRegisterContext() const
Thread * GetThreadPtr() const
Returns a pointer to the thread object.
A file collection class.
Definition: FileSpecList.h:91
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
void Clear()
Clears the file list.
size_t GetSize() const
Get the number of files in the file list.
bool AppendIfUnique(const FileSpec &file)
Append a FileSpec object if unique.
A file utility class.
Definition: FileSpec.h:56
@ eOpenOptionWriteOnly
Definition: File.h:52
@ eOpenOptionCanCreate
Definition: File.h:56
@ eOpenOptionTruncate
Definition: File.h:57
const AddressRange & GetAddressRange()
Definition: Function.h:447
A line table class.
Definition: LineTable.h:40
bool FindLineEntryByAddress(const Address &so_addr, LineEntry &line_entry, uint32_t *index_ptr=nullptr)
Find a line entry that contains the section offset address so_addr.
Definition: LineTable.cpp:188
void Append(OptionGroup *group)
Append options from a OptionGroup class.
Definition: Options.cpp:755
const StructuredData::DictionarySP GetStructuredData()
A command line option parsing protocol class.
Definition: Options.h:58
std::vector< Option > m_getopt_table
Definition: Options.h:198
static llvm::StringRef GetTraceExporterPluginNameAtIndex(uint32_t index)
static ThreadTraceExportCommandCreator GetThreadTraceExportCommandCreatorAtIndex(uint32_t index)
Return the callback used to create the CommandObject that will be listed under "thread trace export".
A plug-in interface definition class for debugging a process.
Definition: Process.h:341
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Definition: Process.h:540
ThreadList & GetThreadList()
Definition: Process.h:2227
Status Resume()
Resumes all of a process's threads as configured using the Thread run control functions.
Definition: Process.cpp:1382
void PruneThreadPlans()
Prune ThreadPlanStacks for all unreported threads.
Definition: Process.cpp:1274
bool PruneThreadPlansForTID(lldb::tid_t tid)
Prune ThreadPlanStacks for unreported threads.
Definition: Process.cpp:1270
bool DumpThreadPlansForTID(Stream &strm, lldb::tid_t tid, lldb::DescriptionLevel desc_level, bool internal, bool condense_trivial, bool skip_unreported_plans)
Dump the thread plans associated with thread with tid.
Definition: Process.cpp:1278
Status ResumeSynchronous(Stream *stream)
Resume a process, and wait for it to stop.
Definition: Process.cpp:1399
size_t GetThreadStatus(Stream &ostrm, bool only_threads_with_stop_reason, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source, bool stop_format)
Definition: Process.cpp:5788
lldb::StateType GetState()
Get accessor for the current process state.
Definition: Process.cpp:1335
void GetStatus(Stream &ostrm)
Definition: Process.cpp:5768
uint32_t GetIOHandlerID() const
Definition: Process.h:2289
void DumpThreadPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal, bool condense_trivial, bool skip_unreported_plans)
Dump all the thread plans for this process.
Definition: Process.cpp:1285
void SyncIOHandler(uint32_t iohandler_id, const Timeout< std::micro > &timeout)
Waits for the process state to be running within a given msec timeout.
Definition: Process.cpp:663
This base class provides an interface to stack frames.
Definition: StackFrame.h:43
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Definition: StackFrame.cpp:300
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
const Address & GetFrameCodeAddress()
Get an Address for the current pc value in this StackFrame.
Definition: StackFrame.cpp:190
An error handling class.
Definition: Status.h:44
bool Fail() const
Test for error condition.
Definition: Status.cpp:180
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
size_t PutChar(char ch)
Definition: Stream.cpp:131
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
Function * function
The Function for a given query.
Block * block
The Block for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
LineEntry line_entry
The LineEntry for a given query.
bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Status &error)
A plug-in interface definition class for system runtimes.
Definition: SystemRuntime.h:43
virtual lldb::ThreadSP GetExtendedBacktraceThread(lldb::ThreadSP thread, ConstString type)
Return a Thread which shows the origin of this thread's creation.
virtual const std::vector< ConstString > & GetExtendedBacktraceTypes()
Return a list of thread origin extended backtraces that may be available.
lldb::ExpressionResults EvaluateExpression(llvm::StringRef expression, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, const EvaluateExpressionOptions &options=EvaluateExpressionOptions(), std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Definition: Target.cpp:2660
uint32_t GetSize(bool can_update=true)
Definition: ThreadList.cpp:82
bool SetSelectedThreadByID(lldb::tid_t tid, bool notify=false)
Definition: ThreadList.cpp:695
lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update=true)
Definition: ThreadList.cpp:208
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
Definition: ThreadList.cpp:90
std::recursive_mutex & GetMutex() const override
Definition: ThreadList.cpp:787
lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update=true)
Definition: ThreadList.cpp:102
virtual lldb::ThreadPlanSP QueueThreadPlanForStepOut(bool abort_other_plans, SymbolContext *addr_context, bool first_insn, bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, uint32_t frame_idx, Status &status, LazyBool step_out_avoids_code_without_debug_info=eLazyBoolCalculate)
Queue the plan used to step out of the function at the current PC of thread.
Definition: Thread.cpp:1321
Status UnwindInnermostExpression()
Unwinds the thread stack for the innermost expression plan currently on the thread plan stack.
Definition: Thread.cpp:1238
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:408
virtual lldb::ThreadPlanSP QueueThreadPlanForStepUntil(bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses, bool stop_others, uint32_t frame_idx, Status &status)
Definition: Thread.cpp:1377
void AutoCompleteThreadPlans(CompletionRequest &request) const
Format the thread plan information for auto completion.
Definition: Thread.cpp:1119
uint32_t GetIndexID() const
Definition: Thread.cpp:1399
bool GetDescription(Stream &s, lldb::DescriptionLevel level, bool print_json_thread, bool print_json_stopinfo)
Definition: Thread.cpp:1806
void SetResumeState(lldb::StateType state, bool override_suspend=false)
Sets the USER resume state for this thread.
Definition: Thread.h:187
lldb::StackFrameSP GetSelectedFrame(SelectMostRelevant select_most_relevant)
Definition: Thread.cpp:271
bool DiscardUserThreadPlansUpToIndex(uint32_t thread_index)
Discards the plans queued on the plan stack of the current thread up to and including the plan in tha...
Definition: Thread.cpp:1197
uint32_t GetSelectedFrameIndex(SelectMostRelevant select_most_relevant)
Definition: Thread.h:444
lldb::ProcessSP GetProcess() const
Definition: Thread.h:157
virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRange(bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, const char *step_in_target, lldb::RunMode stop_other_threads, Status &status, LazyBool step_in_avoids_code_without_debug_info=eLazyBoolCalculate, LazyBool step_out_avoids_code_without_debug_info=eLazyBoolCalculate)
Queues the plan used to step through an address range, stepping into functions.
Definition: Thread.cpp:1291
virtual lldb::ThreadPlanSP QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name, StructuredData::ObjectSP extra_args_sp, bool stop_other_threads, Status &status)
Definition: Thread.cpp:1387
virtual lldb::ThreadPlanSP QueueThreadPlanForStepSingleInstruction(bool step_over, bool abort_other_plans, bool stop_other_threads, Status &status)
Queues the plan used to step one instruction from the current PC of thread.
Definition: Thread.cpp:1255
Status JumpToLine(const FileSpec &file, uint32_t line, bool can_leave_function, std::string *warnings=nullptr)
Definition: Thread.cpp:1562
virtual lldb::ThreadPlanSP QueueThreadPlanForStepOverRange(bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_other_threads, Status &status, LazyBool step_out_avoids_code_without_debug_info=eLazyBoolCalculate)
Queues the plan used to step through an address range, stepping over function calls.
Definition: Thread.cpp:1264
size_t GetStatus(Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source, bool stop_format, bool only_stacks=false)
Definition: Thread.cpp:1749
bool SetSelectedFrameByIndexNoisily(uint32_t frame_idx, Stream &output_stream)
Definition: Thread.cpp:300
Class used to dump the instructions of a TraceCursor using its current state and granularity.
Definition: TraceDumper.h:51
std::optional< lldb::user_id_t > DumpInstructions(size_t count)
Dump count instructions of the thread trace starting at the current cursor position.
void DumpFunctionCalls()
Dump all function calls forwards chronologically and hierarchically.
A plug-in interface definition class for trace information.
Definition: Trace.h:48
virtual lldb::CommandObjectSP GetThreadTraceStartCommand(CommandInterpreter &interpreter)=0
Get the command handle for the "thread trace start" command.
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
#define LLDB_INVALID_LINE_NUMBER
Definition: lldb-defines.h:94
#define LLDB_INVALID_THREAD_ID
Definition: lldb-defines.h:90
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:83
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:110
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
#define UINT32_MAX
Definition: lldb-defines.h:19
#define LLDB_INVALID_FRAME_ID
Definition: lldb-defines.h:91
@ DoNoSelectMostRelevantFrame
A class that represents a running process on the host machine.
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:43
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition: State.cpp:14
const char * toString(AppleArm64ExceptionClass EC)
lldb::CommandObjectSP(* ThreadTraceExportCommandCreator)(CommandInterpreter &interpreter)
@ eStepTypeTraceOver
Single step one instruction, stepping over.
@ eStepTypeOut
Single step out a specified context.
@ eStepTypeScripted
A step type implemented by the script interpreter.
@ eStepTypeInto
Single step into a specified context.
@ eStepTypeOver
Single step over a specified context.
@ eStepTypeTrace
Single step one instruction.
Definition: SBAddress.h:15
@ eThreadIndexCompletion
std::shared_ptr< lldb_private::Trace > TraceSP
Definition: lldb-forward.h:454
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
Definition: lldb-forward.h:449
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
Definition: lldb-forward.h:420
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
@ eDescriptionLevelFull
@ eDescriptionLevelVerbose
std::shared_ptr< lldb_private::Thread > ThreadSP
Definition: lldb-forward.h:446
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
Definition: lldb-forward.h:331
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:480
StateType
Process and Thread States.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
ExpressionResults
The results of expression evaluation.
@ eExpressionCompleted
@ eExpressionSetupError
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:387
@ eReturnStatusSuccessContinuingNoResult
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeThreadID
@ eArgTypeThreadIndex
@ eArgTypeExpression
@ eArgTypeUnsignedInteger
@ eTraceCursorSeekTypeEnd
The end of the trace, i.e the most recent item.
std::shared_ptr< lldb_private::TraceCursor > TraceCursorSP
Definition: lldb-forward.h:456
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:444
@ eNoDynamicValues
RunMode
Thread Run Modes.
@ eOnlyDuringStepping
uint64_t tid_t
Definition: lldb-types.h:84
Used to build individual command argument lists.
Definition: CommandObject.h:93
uint32_t arg_opt_set_association
This arg might be associated only with some particular option set(s).
Definition: CommandObject.h:98
A line table entry class.
Definition: LineEntry.h:21
AddressRange range
The section offset address range for this line entry.
Definition: LineEntry.h:137
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
Definition: LineEntry.h:147
const FileSpec & GetFile() const
Helper to access the file.
Definition: LineEntry.h:134
static int64_t ToOptionEnum(llvm::StringRef s, const OptionEnumValues &enum_values, int32_t fail_value, Status &error)
static lldb::addr_t ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error_ptr)
Try to parse an address.
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)
Class that holds the configuration used by TraceDumper for traversing and dumping instructions.
Definition: TraceDumper.h:21
bool show_control_flow_kind
For each instruction, print the instruction kind.
Definition: TraceDumper.h:41
bool only_events
Dump events and none of the instructions.
Definition: TraceDumper.h:39
bool show_timestamps
For each trace item, print the corresponding timestamp in nanoseconds if available.
Definition: TraceDumper.h:35
std::optional< uint64_t > id
Optional custom id to start traversing from.
Definition: TraceDumper.h:43
bool pretty_print_json
When dumping in JSON format, pretty print the output.
Definition: TraceDumper.h:32
std::optional< size_t > skip
Optional number of instructions to skip from the starting position of the cursor.
Definition: TraceDumper.h:46
bool json
Dump in json format.
Definition: TraceDumper.h:30
bool show_events
Dump the events that happened between instructions.
Definition: TraceDumper.h:37
bool raw
Dump only instruction addresses without disassembly nor symbol information.
Definition: TraceDumper.h:28
bool forwards
If true, the cursor will be iterated forwards starting from the oldest instruction.
Definition: TraceDumper.h:25
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47