1 //===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "CommandObjectThread.h"
16 // Other libraries and framework includes
18 #include "lldb/lldb-private.h"
19 #include "lldb/Core/State.h"
20 #include "lldb/Core/SourceManager.h"
21 #include "lldb/Host/Host.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/CommandReturnObject.h"
24 #include "lldb/Interpreter/Options.h"
25 #include "lldb/Symbol/CompileUnit.h"
26 #include "lldb/Symbol/Function.h"
27 #include "lldb/Symbol/LineTable.h"
28 #include "lldb/Symbol/LineEntry.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/RegisterContext.h"
31 #include "lldb/Target/SystemRuntime.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/Thread.h"
34 #include "lldb/Target/ThreadPlan.h"
35 #include "lldb/Target/ThreadPlanStepInstruction.h"
36 #include "lldb/Target/ThreadPlanStepOut.h"
37 #include "lldb/Target/ThreadPlanStepRange.h"
38 #include "lldb/Target/ThreadPlanStepInRange.h"
42 using namespace lldb_private;
45 //-------------------------------------------------------------------------
46 // CommandObjectThreadBacktrace
47 //-------------------------------------------------------------------------
49 class CommandObjectIterateOverThreads : public CommandObjectParsed
52 CommandObjectIterateOverThreads (CommandInterpreter &interpreter,
57 CommandObjectParsed (interpreter, name, help, syntax, flags)
61 virtual ~CommandObjectIterateOverThreads() {}
63 DoExecute (Args& command, CommandReturnObject &result)
65 result.SetStatus (m_success_return);
67 if (command.GetArgumentCount() == 0)
69 Thread *thread = m_exe_ctx.GetThreadPtr();
70 if (!HandleOneThread (*thread, result))
73 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
75 Process *process = m_exe_ctx.GetProcessPtr();
77 for (ThreadSP thread_sp : process->Threads())
79 if (idx != 0 && m_add_return)
80 result.AppendMessage("");
82 if (!HandleOneThread(*(thread_sp.get()), result))
89 const size_t num_args = command.GetArgumentCount();
90 Process *process = m_exe_ctx.GetProcessPtr();
91 Mutex::Locker locker (process->GetThreadList().GetMutex());
92 std::vector<ThreadSP> thread_sps;
94 for (size_t i = 0; i < num_args; i++)
98 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
101 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
102 result.SetStatus (eReturnStatusFailed);
106 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
110 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
111 result.SetStatus (eReturnStatusFailed);
117 for (uint32_t i = 0; i < num_args; i++)
119 if (!HandleOneThread (*(thread_sps[i].get()), result))
122 if (i < num_args - 1 && m_add_return)
123 result.AppendMessage("");
126 return result.Succeeded();
131 // Override this to do whatever you need to do for one thread.
133 // If you return false, the iteration will stop, otherwise it will proceed.
134 // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
135 // so you only need to set the return status in HandleOneThread if you want to indicate an error.
136 // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
139 HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
141 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
142 bool m_add_return = true;
146 //-------------------------------------------------------------------------
147 // CommandObjectThreadBacktrace
148 //-------------------------------------------------------------------------
150 class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
154 class CommandOptions : public Options
158 CommandOptions (CommandInterpreter &interpreter) :
161 // Keep default values of all options in one place: OptionParsingStarting ()
162 OptionParsingStarting ();
171 SetOptionValue (uint32_t option_idx, const char *option_arg)
174 const int short_option = m_getopt_table[option_idx].val;
176 switch (short_option)
181 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
183 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
184 if (input_count < -1)
185 m_count = UINT32_MAX;
187 m_count = input_count;
193 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
195 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
200 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
202 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
206 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
214 OptionParsingStarting ()
216 m_count = UINT32_MAX;
218 m_extended_backtrace = false;
221 const OptionDefinition*
224 return g_option_table;
227 // Options table: Required for subclasses of Options.
229 static OptionDefinition g_option_table[];
231 // Instance variables to hold the values for command options.
234 bool m_extended_backtrace;
237 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
238 CommandObjectIterateOverThreads (interpreter,
240 "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.",
242 eFlagRequiresProcess |
243 eFlagRequiresThread |
244 eFlagTryTargetAPILock |
245 eFlagProcessMustBeLaunched |
246 eFlagProcessMustBePaused ),
247 m_options(interpreter)
251 ~CommandObjectThreadBacktrace()
263 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
265 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
268 Stream &strm = result.GetOutputStream();
269 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
270 for (auto type : types)
272 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
273 if (ext_thread_sp && ext_thread_sp->IsValid ())
275 const uint32_t num_frames_with_source = 0;
276 if (ext_thread_sp->GetStatus (strm,
279 num_frames_with_source))
281 DoExtendedBacktrace (ext_thread_sp.get(), result);
289 HandleOneThread (Thread &thread, CommandReturnObject &result)
291 Stream &strm = result.GetOutputStream();
293 // Don't show source context when doing backtraces.
294 const uint32_t num_frames_with_source = 0;
296 if (!thread.GetStatus (strm,
299 num_frames_with_source))
301 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID());
302 result.SetStatus (eReturnStatusFailed);
305 if (m_options.m_extended_backtrace)
307 DoExtendedBacktrace (&thread, result);
313 CommandOptions m_options;
317 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
319 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
320 { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
321 { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
322 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
328 eStepScopeInstruction
331 class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
335 class CommandOptions : public Options
339 CommandOptions (CommandInterpreter &interpreter) :
340 Options (interpreter)
342 // Keep default values of all options in one place: OptionParsingStarting ()
343 OptionParsingStarting ();
352 SetOptionValue (uint32_t option_idx, const char *option_arg)
355 const int short_option = m_getopt_table[option_idx].val;
357 switch (short_option)
362 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
364 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
367 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
375 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
377 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
380 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
387 m_step_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
388 if (m_step_count == UINT32_MAX)
389 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
395 m_class_name.clear();
396 m_class_name.assign(option_arg);
401 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
402 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
408 m_avoid_regexp.clear();
409 m_avoid_regexp.assign(option_arg);
415 m_step_in_target.clear();
416 m_step_in_target.assign(option_arg);
421 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
429 OptionParsingStarting ()
431 m_step_in_avoid_no_debug = eLazyBoolCalculate;
432 m_step_out_avoid_no_debug = eLazyBoolCalculate;
433 m_run_mode = eOnlyDuringStepping;
434 m_avoid_regexp.clear();
435 m_step_in_target.clear();
436 m_class_name.clear();
440 const OptionDefinition*
443 return g_option_table;
446 // Options table: Required for subclasses of Options.
448 static OptionDefinition g_option_table[];
450 // Instance variables to hold the values for command options.
451 LazyBool m_step_in_avoid_no_debug;
452 LazyBool m_step_out_avoid_no_debug;
454 std::string m_avoid_regexp;
455 std::string m_step_in_target;
456 std::string m_class_name;
457 uint32_t m_step_count;
460 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
465 StepScope step_scope) :
466 CommandObjectParsed (interpreter, name, help, syntax,
467 eFlagRequiresProcess |
468 eFlagRequiresThread |
469 eFlagTryTargetAPILock |
470 eFlagProcessMustBeLaunched |
471 eFlagProcessMustBePaused ),
472 m_step_type (step_type),
473 m_step_scope (step_scope),
474 m_options (interpreter)
476 CommandArgumentEntry arg;
477 CommandArgumentData thread_id_arg;
479 // Define the first (and only) variant of this arg.
480 thread_id_arg.arg_type = eArgTypeThreadID;
481 thread_id_arg.arg_repetition = eArgRepeatOptional;
483 // There is only one variant this argument could be; put it into the argument entry.
484 arg.push_back (thread_id_arg);
486 // Push the data for the first argument into the m_arguments vector.
487 m_arguments.push_back (arg);
491 ~CommandObjectThreadStepWithTypeAndScope ()
504 DoExecute (Args& command, CommandReturnObject &result)
506 Process *process = m_exe_ctx.GetProcessPtr();
507 bool synchronous_execution = m_interpreter.GetSynchronous();
509 const uint32_t num_threads = process->GetThreadList().GetSize();
510 Thread *thread = NULL;
512 if (command.GetArgumentCount() == 0)
514 thread = process->GetThreadList().GetSelectedThread().get();
517 result.AppendError ("no selected thread in process");
518 result.SetStatus (eReturnStatusFailed);
524 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
525 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
526 if (step_thread_idx == LLDB_INVALID_INDEX32)
528 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
529 result.SetStatus (eReturnStatusFailed);
532 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
535 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
536 step_thread_idx, num_threads);
537 result.SetStatus (eReturnStatusFailed);
542 if (m_step_type == eStepTypeScripted)
544 if (m_options.m_class_name.empty())
546 result.AppendErrorWithFormat ("empty class name for scripted step.");
547 result.SetStatus(eReturnStatusFailed);
550 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
552 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
553 result.SetStatus(eReturnStatusFailed);
558 const bool abort_other_plans = false;
559 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
561 // This is a bit unfortunate, but not all the commands in this command object support
562 // only while stepping, so I use the bool for them.
563 bool bool_stop_other_threads;
564 if (m_options.m_run_mode == eAllThreads)
565 bool_stop_other_threads = false;
566 else if (m_options.m_run_mode == eOnlyDuringStepping)
568 if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted)
569 bool_stop_other_threads = false;
571 bool_stop_other_threads = true;
574 bool_stop_other_threads = true;
576 ThreadPlanSP new_plan_sp;
578 if (m_step_type == eStepTypeInto)
580 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
582 if (frame->HasDebugInformation ())
584 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
585 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
586 frame->GetSymbolContext(eSymbolContextEverything),
587 m_options.m_step_in_target.c_str(),
589 m_options.m_step_in_avoid_no_debug,
590 m_options.m_step_out_avoid_no_debug);
592 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
594 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
595 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
599 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
602 else if (m_step_type == eStepTypeOver)
604 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
606 if (frame->HasDebugInformation())
607 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
608 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
609 frame->GetSymbolContext(eSymbolContextEverything),
611 m_options.m_step_out_avoid_no_debug);
613 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
615 bool_stop_other_threads);
618 else if (m_step_type == eStepTypeTrace)
620 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
622 else if (m_step_type == eStepTypeTraceOver)
624 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
626 else if (m_step_type == eStepTypeOut)
628 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
631 bool_stop_other_threads,
634 thread->GetSelectedFrameIndex(),
635 m_options.m_step_out_avoid_no_debug);
637 else if (m_step_type == eStepTypeScripted)
639 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
640 m_options.m_class_name.c_str(),
641 bool_stop_other_threads);
645 result.AppendError ("step type is not supported");
646 result.SetStatus (eReturnStatusFailed);
650 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
651 // so that they can be interruptible). Then resume the process.
655 new_plan_sp->SetIsMasterPlan (true);
656 new_plan_sp->SetOkayToDiscard (false);
658 if (m_options.m_step_count > 1)
660 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
662 result.AppendWarning ("step operation does not support iteration count.");
667 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
671 if (synchronous_execution)
672 error = process->ResumeSynchronous (&stream);
674 error = process->Resume ();
676 // There is a race condition where this thread will return up the call stack to the main command handler
677 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
678 // a chance to call PushProcessIOHandler().
679 process->SyncIOHandler(2000);
681 if (synchronous_execution)
683 // If any state changed events had anything to say, add that to the result
684 if (stream.GetData())
685 result.AppendMessage(stream.GetData());
687 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
688 result.SetDidChangeProcessState (true);
689 result.SetStatus (eReturnStatusSuccessFinishNoResult);
693 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
698 result.AppendError ("Couldn't find thread plan to implement step type.");
699 result.SetStatus (eReturnStatusFailed);
701 return result.Succeeded();
705 StepType m_step_type;
706 StepScope m_step_scope;
707 CommandOptions m_options;
710 static OptionEnumValueElement
711 g_tri_running_mode[] =
713 { eOnlyThisThread, "this-thread", "Run only this thread"},
714 { eAllThreads, "all-threads", "Run all threads"},
715 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
719 static OptionEnumValueElement
720 g_duo_running_mode[] =
722 { eOnlyThisThread, "this-thread", "Run only this thread"},
723 { eAllThreads, "all-threads", "Run all threads"},
728 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
730 { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
731 { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
732 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
733 { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
734 { LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
735 { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
736 { LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
737 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
741 //-------------------------------------------------------------------------
742 // CommandObjectThreadContinue
743 //-------------------------------------------------------------------------
745 class CommandObjectThreadContinue : public CommandObjectParsed
749 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
750 CommandObjectParsed (interpreter,
752 "Continue execution of one or more threads in an active process.",
754 eFlagRequiresThread |
755 eFlagTryTargetAPILock |
756 eFlagProcessMustBeLaunched |
757 eFlagProcessMustBePaused)
759 CommandArgumentEntry arg;
760 CommandArgumentData thread_idx_arg;
762 // Define the first (and only) variant of this arg.
763 thread_idx_arg.arg_type = eArgTypeThreadIndex;
764 thread_idx_arg.arg_repetition = eArgRepeatPlus;
766 // There is only one variant this argument could be; put it into the argument entry.
767 arg.push_back (thread_idx_arg);
769 // Push the data for the first argument into the m_arguments vector.
770 m_arguments.push_back (arg);
775 ~CommandObjectThreadContinue ()
780 DoExecute (Args& command, CommandReturnObject &result)
782 bool synchronous_execution = m_interpreter.GetSynchronous ();
784 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
786 result.AppendError ("invalid target, create a debug target using the 'target create' command");
787 result.SetStatus (eReturnStatusFailed);
791 Process *process = m_exe_ctx.GetProcessPtr();
794 result.AppendError ("no process exists. Cannot continue");
795 result.SetStatus (eReturnStatusFailed);
799 StateType state = process->GetState();
800 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
802 const size_t argc = command.GetArgumentCount();
805 // These two lines appear at the beginning of both blocks in
806 // this if..else, but that is because we need to release the
807 // lock before calling process->Resume below.
808 Mutex::Locker locker (process->GetThreadList().GetMutex());
809 const uint32_t num_threads = process->GetThreadList().GetSize();
810 std::vector<Thread *> resume_threads;
811 for (uint32_t i=0; i<argc; ++i)
815 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
818 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
822 resume_threads.push_back(thread);
826 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
827 result.SetStatus (eReturnStatusFailed);
833 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
834 result.SetStatus (eReturnStatusFailed);
839 if (resume_threads.empty())
841 result.AppendError ("no valid thread indexes were specified");
842 result.SetStatus (eReturnStatusFailed);
847 if (resume_threads.size() == 1)
848 result.AppendMessageWithFormat ("Resuming thread: ");
850 result.AppendMessageWithFormat ("Resuming threads: ");
852 for (uint32_t idx=0; idx<num_threads; ++idx)
854 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
855 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
857 if (this_thread_pos != resume_threads.end())
859 resume_threads.erase(this_thread_pos);
860 if (resume_threads.size() > 0)
861 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
863 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
865 const bool override_suspend = true;
866 thread->SetResumeState (eStateRunning, override_suspend);
870 thread->SetResumeState (eStateSuspended);
873 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
878 // These two lines appear at the beginning of both blocks in
879 // this if..else, but that is because we need to release the
880 // lock before calling process->Resume below.
881 Mutex::Locker locker (process->GetThreadList().GetMutex());
882 const uint32_t num_threads = process->GetThreadList().GetSize();
883 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
884 if (current_thread == NULL)
886 result.AppendError ("the process doesn't have a current thread");
887 result.SetStatus (eReturnStatusFailed);
890 // Set the actions that the threads should each take when resuming
891 for (uint32_t idx=0; idx<num_threads; ++idx)
893 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
894 if (thread == current_thread)
896 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
897 const bool override_suspend = true;
898 thread->SetResumeState (eStateRunning, override_suspend);
902 thread->SetResumeState (eStateSuspended);
910 if (synchronous_execution)
911 error = process->ResumeSynchronous (&stream);
913 error = process->Resume ();
915 // We should not be holding the thread list lock when we do this.
918 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
919 if (synchronous_execution)
921 // If any state changed events had anything to say, add that to the result
922 if (stream.GetData())
923 result.AppendMessage(stream.GetData());
925 result.SetDidChangeProcessState (true);
926 result.SetStatus (eReturnStatusSuccessFinishNoResult);
930 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
935 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
936 result.SetStatus (eReturnStatusFailed);
941 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
942 StateAsCString(state));
943 result.SetStatus (eReturnStatusFailed);
946 return result.Succeeded();
951 //-------------------------------------------------------------------------
952 // CommandObjectThreadUntil
953 //-------------------------------------------------------------------------
955 class CommandObjectThreadUntil : public CommandObjectParsed
959 class CommandOptions : public Options
962 uint32_t m_thread_idx;
963 uint32_t m_frame_idx;
965 CommandOptions (CommandInterpreter &interpreter) :
966 Options (interpreter),
967 m_thread_idx(LLDB_INVALID_THREAD_ID),
968 m_frame_idx(LLDB_INVALID_FRAME_ID)
970 // Keep default values of all options in one place: OptionParsingStarting ()
971 OptionParsingStarting ();
980 SetOptionValue (uint32_t option_idx, const char *option_arg)
983 const int short_option = m_getopt_table[option_idx].val;
985 switch (short_option)
989 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
990 if (m_thread_idx == LLDB_INVALID_INDEX32)
992 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
998 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
999 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1001 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
1007 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
1008 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
1010 if (error.Success())
1012 if (run_mode == eAllThreads)
1013 m_stop_others = false;
1015 m_stop_others = true;
1020 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1028 OptionParsingStarting ()
1030 m_thread_idx = LLDB_INVALID_THREAD_ID;
1032 m_stop_others = false;
1035 const OptionDefinition*
1038 return g_option_table;
1041 uint32_t m_step_thread_idx;
1044 // Options table: Required for subclasses of Options.
1046 static OptionDefinition g_option_table[];
1048 // Instance variables to hold the values for command options.
1051 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
1052 CommandObjectParsed (interpreter,
1054 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
1056 eFlagRequiresThread |
1057 eFlagTryTargetAPILock |
1058 eFlagProcessMustBeLaunched |
1059 eFlagProcessMustBePaused ),
1060 m_options (interpreter)
1062 CommandArgumentEntry arg;
1063 CommandArgumentData line_num_arg;
1065 // Define the first (and only) variant of this arg.
1066 line_num_arg.arg_type = eArgTypeLineNum;
1067 line_num_arg.arg_repetition = eArgRepeatPlain;
1069 // There is only one variant this argument could be; put it into the argument entry.
1070 arg.push_back (line_num_arg);
1072 // Push the data for the first argument into the m_arguments vector.
1073 m_arguments.push_back (arg);
1078 ~CommandObjectThreadUntil ()
1091 DoExecute (Args& command, CommandReturnObject &result)
1093 bool synchronous_execution = m_interpreter.GetSynchronous ();
1095 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1098 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1099 result.SetStatus (eReturnStatusFailed);
1103 Process *process = m_exe_ctx.GetProcessPtr();
1104 if (process == NULL)
1106 result.AppendError ("need a valid process to step");
1107 result.SetStatus (eReturnStatusFailed);
1112 Thread *thread = NULL;
1113 uint32_t line_number;
1115 if (command.GetArgumentCount() != 1)
1117 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1118 result.SetStatus (eReturnStatusFailed);
1122 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1123 if (line_number == UINT32_MAX)
1125 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1126 result.SetStatus (eReturnStatusFailed);
1130 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1132 thread = process->GetThreadList().GetSelectedThread().get();
1136 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
1141 const uint32_t num_threads = process->GetThreadList().GetSize();
1142 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1143 m_options.m_thread_idx,
1145 result.SetStatus (eReturnStatusFailed);
1149 const bool abort_other_plans = false;
1151 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
1155 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1156 m_options.m_frame_idx,
1157 m_options.m_thread_idx);
1158 result.SetStatus (eReturnStatusFailed);
1162 ThreadPlanSP new_plan_sp;
1164 if (frame->HasDebugInformation ())
1166 // Finally we got here... Translate the given line number to a bunch of addresses:
1167 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1168 LineTable *line_table = NULL;
1170 line_table = sc.comp_unit->GetLineTable();
1172 if (line_table == NULL)
1174 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1175 m_options.m_frame_idx, m_options.m_thread_idx);
1176 result.SetStatus (eReturnStatusFailed);
1180 LineEntry function_start;
1181 uint32_t index_ptr = 0, end_ptr;
1182 std::vector<addr_t> address_list;
1184 // Find the beginning & end index of the
1185 AddressRange fun_addr_range = sc.function->GetAddressRange();
1186 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1187 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1189 Address fun_end_addr(fun_start_addr.GetSection(),
1190 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1191 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1193 bool all_in_function = true;
1195 while (index_ptr <= end_ptr)
1197 LineEntry line_entry;
1198 const bool exact = false;
1199 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
1200 if (index_ptr == UINT32_MAX)
1203 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1204 if (address != LLDB_INVALID_ADDRESS)
1206 if (fun_addr_range.ContainsLoadAddress (address, target))
1207 address_list.push_back (address);
1209 all_in_function = false;
1214 if (address_list.size() == 0)
1216 if (all_in_function)
1217 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1219 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1221 result.SetStatus (eReturnStatusFailed);
1225 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1226 &address_list.front(),
1227 address_list.size(),
1228 m_options.m_stop_others,
1229 m_options.m_frame_idx);
1230 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1231 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1232 // will resume the original plan.
1233 new_plan_sp->SetIsMasterPlan (true);
1234 new_plan_sp->SetOkayToDiscard(false);
1238 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1239 m_options.m_frame_idx,
1240 m_options.m_thread_idx);
1241 result.SetStatus (eReturnStatusFailed);
1248 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1250 StreamString stream;
1252 if (synchronous_execution)
1253 error = process->ResumeSynchronous (&stream);
1255 error = process->Resume ();
1257 if (error.Success())
1259 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
1260 if (synchronous_execution)
1262 // If any state changed events had anything to say, add that to the result
1263 if (stream.GetData())
1264 result.AppendMessage(stream.GetData());
1266 result.SetDidChangeProcessState (true);
1267 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1271 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1276 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1277 result.SetStatus (eReturnStatusFailed);
1281 return result.Succeeded();
1284 CommandOptions m_options;
1289 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1291 { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1292 { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1293 { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
1294 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1298 //-------------------------------------------------------------------------
1299 // CommandObjectThreadSelect
1300 //-------------------------------------------------------------------------
1302 class CommandObjectThreadSelect : public CommandObjectParsed
1306 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1307 CommandObjectParsed (interpreter,
1309 "Select a thread as the currently active thread.",
1311 eFlagRequiresProcess |
1312 eFlagTryTargetAPILock |
1313 eFlagProcessMustBeLaunched |
1314 eFlagProcessMustBePaused )
1316 CommandArgumentEntry arg;
1317 CommandArgumentData thread_idx_arg;
1319 // Define the first (and only) variant of this arg.
1320 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1321 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1323 // There is only one variant this argument could be; put it into the argument entry.
1324 arg.push_back (thread_idx_arg);
1326 // Push the data for the first argument into the m_arguments vector.
1327 m_arguments.push_back (arg);
1332 ~CommandObjectThreadSelect ()
1338 DoExecute (Args& command, CommandReturnObject &result)
1340 Process *process = m_exe_ctx.GetProcessPtr();
1341 if (process == NULL)
1343 result.AppendError ("no process");
1344 result.SetStatus (eReturnStatusFailed);
1347 else if (command.GetArgumentCount() != 1)
1349 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1350 result.SetStatus (eReturnStatusFailed);
1354 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1356 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1357 if (new_thread == NULL)
1359 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1360 result.SetStatus (eReturnStatusFailed);
1364 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1365 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1367 return result.Succeeded();
1373 //-------------------------------------------------------------------------
1374 // CommandObjectThreadList
1375 //-------------------------------------------------------------------------
1377 class CommandObjectThreadList : public CommandObjectParsed
1382 CommandObjectThreadList (CommandInterpreter &interpreter):
1383 CommandObjectParsed (interpreter,
1385 "Show a summary of all current threads in a process.",
1387 eFlagRequiresProcess |
1388 eFlagTryTargetAPILock |
1389 eFlagProcessMustBeLaunched |
1390 eFlagProcessMustBePaused )
1394 ~CommandObjectThreadList()
1400 DoExecute (Args& command, CommandReturnObject &result)
1402 Stream &strm = result.GetOutputStream();
1403 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1404 Process *process = m_exe_ctx.GetProcessPtr();
1405 const bool only_threads_with_stop_reason = false;
1406 const uint32_t start_frame = 0;
1407 const uint32_t num_frames = 0;
1408 const uint32_t num_frames_with_source = 0;
1409 process->GetStatus(strm);
1410 process->GetThreadStatus (strm,
1411 only_threads_with_stop_reason,
1414 num_frames_with_source);
1415 return result.Succeeded();
1419 //-------------------------------------------------------------------------
1420 // CommandObjectThreadInfo
1421 //-------------------------------------------------------------------------
1423 class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
1427 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
1428 CommandObjectIterateOverThreads (interpreter,
1430 "Show an extended summary of information about thread(s) in a process.",
1432 eFlagRequiresProcess |
1433 eFlagTryTargetAPILock |
1434 eFlagProcessMustBeLaunched |
1435 eFlagProcessMustBePaused),
1436 m_options (interpreter)
1438 m_add_return = false;
1441 class CommandOptions : public Options
1445 CommandOptions (CommandInterpreter &interpreter) :
1446 Options (interpreter)
1448 OptionParsingStarting ();
1452 OptionParsingStarting ()
1454 m_json_thread = false;
1455 m_json_stopinfo = false;
1464 SetOptionValue (uint32_t option_idx, const char *option_arg)
1466 const int short_option = m_getopt_table[option_idx].val;
1469 switch (short_option)
1472 m_json_thread = true;
1476 m_json_stopinfo = true;
1480 return Error("invalid short option character '%c'", short_option);
1486 const OptionDefinition*
1489 return g_option_table;
1493 bool m_json_stopinfo;
1495 static OptionDefinition g_option_table[];
1507 ~CommandObjectThreadInfo ()
1512 HandleOneThread (Thread &thread, CommandReturnObject &result)
1514 Stream &strm = result.GetOutputStream();
1515 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
1517 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1518 result.SetStatus (eReturnStatusFailed);
1524 CommandOptions m_options;
1529 CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1531 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."},
1532 { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
1534 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1538 //-------------------------------------------------------------------------
1539 // CommandObjectThreadReturn
1540 //-------------------------------------------------------------------------
1542 class CommandObjectThreadReturn : public CommandObjectRaw
1545 class CommandOptions : public Options
1549 CommandOptions (CommandInterpreter &interpreter) :
1550 Options (interpreter),
1551 m_from_expression (false)
1553 // Keep default values of all options in one place: OptionParsingStarting ()
1554 OptionParsingStarting ();
1563 SetOptionValue (uint32_t option_idx, const char *option_arg)
1566 const int short_option = m_getopt_table[option_idx].val;
1568 switch (short_option)
1573 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1575 m_from_expression = tmp_value;
1578 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1583 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1591 OptionParsingStarting ()
1593 m_from_expression = false;
1596 const OptionDefinition*
1599 return g_option_table;
1602 bool m_from_expression;
1604 // Options table: Required for subclasses of Options.
1606 static OptionDefinition g_option_table[];
1608 // Instance variables to hold the values for command options.
1618 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1619 CommandObjectRaw (interpreter,
1621 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1622 " or with the -x option from the innermost function evaluation.",
1624 eFlagRequiresFrame |
1625 eFlagTryTargetAPILock |
1626 eFlagProcessMustBeLaunched |
1627 eFlagProcessMustBePaused ),
1628 m_options (interpreter)
1630 CommandArgumentEntry arg;
1631 CommandArgumentData expression_arg;
1633 // Define the first (and only) variant of this arg.
1634 expression_arg.arg_type = eArgTypeExpression;
1635 expression_arg.arg_repetition = eArgRepeatOptional;
1637 // There is only one variant this argument could be; put it into the argument entry.
1638 arg.push_back (expression_arg);
1640 // Push the data for the first argument into the m_arguments vector.
1641 m_arguments.push_back (arg);
1646 ~CommandObjectThreadReturn()
1654 const char *command,
1655 CommandReturnObject &result
1658 // I am going to handle this by hand, because I don't want you to have to say:
1659 // "thread return -- -5".
1660 if (command[0] == '-' && command[1] == 'x')
1662 if (command && command[2] != '\0')
1663 result.AppendWarning("Return values ignored when returning from user called expressions");
1665 Thread *thread = m_exe_ctx.GetThreadPtr();
1667 error = thread->UnwindInnermostExpression();
1668 if (!error.Success())
1670 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1671 result.SetStatus (eReturnStatusFailed);
1675 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1678 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1679 result.SetStatus (eReturnStatusSuccessFinishResult);
1683 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1684 result.SetStatus (eReturnStatusFailed);
1687 return result.Succeeded();
1690 ValueObjectSP return_valobj_sp;
1692 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1693 uint32_t frame_idx = frame_sp->GetFrameIndex();
1695 if (frame_sp->IsInlined())
1697 result.AppendError("Don't know how to return from inlined frames.");
1698 result.SetStatus (eReturnStatusFailed);
1702 if (command && command[0] != '\0')
1704 Target *target = m_exe_ctx.GetTargetPtr();
1705 EvaluateExpressionOptions options;
1707 options.SetUnwindOnError(true);
1708 options.SetUseDynamic(eNoDynamicValues);
1710 ExpressionResults exe_results = eExpressionSetupError;
1711 exe_results = target->EvaluateExpression (command,
1715 if (exe_results != eExpressionCompleted)
1717 if (return_valobj_sp)
1718 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1720 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1721 result.SetStatus (eReturnStatusFailed);
1728 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1729 const bool broadcast = true;
1730 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
1731 if (!error.Success())
1733 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1734 result.SetStatus (eReturnStatusFailed);
1738 result.SetStatus (eReturnStatusSuccessFinishResult);
1742 CommandOptions m_options;
1746 CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1748 { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1749 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1752 //-------------------------------------------------------------------------
1753 // CommandObjectThreadJump
1754 //-------------------------------------------------------------------------
1756 class CommandObjectThreadJump : public CommandObjectParsed
1759 class CommandOptions : public Options
1763 CommandOptions (CommandInterpreter &interpreter) :
1764 Options (interpreter)
1766 OptionParsingStarting ();
1770 OptionParsingStarting ()
1772 m_filenames.Clear();
1775 m_load_addr = LLDB_INVALID_ADDRESS;
1785 SetOptionValue (uint32_t option_idx, const char *option_arg)
1788 const int short_option = m_getopt_table[option_idx].val;
1791 switch (short_option)
1794 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1795 if (m_filenames.GetSize() > 1)
1796 return Error("only one source file expected.");
1799 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1800 if (!success || m_line_num == 0)
1801 return Error("invalid line number: '%s'.", option_arg);
1804 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1806 return Error("invalid line offset: '%s'.", option_arg);
1810 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1811 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1819 return Error("invalid short option character '%c'", short_option);
1825 const OptionDefinition*
1828 return g_option_table;
1831 FileSpecList m_filenames;
1832 uint32_t m_line_num;
1833 int32_t m_line_offset;
1834 lldb::addr_t m_load_addr;
1837 static OptionDefinition g_option_table[];
1847 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1848 CommandObjectParsed (interpreter,
1850 "Sets the program counter to a new address.",
1852 eFlagRequiresFrame |
1853 eFlagTryTargetAPILock |
1854 eFlagProcessMustBeLaunched |
1855 eFlagProcessMustBePaused ),
1856 m_options (interpreter)
1860 ~CommandObjectThreadJump()
1866 bool DoExecute (Args& args, CommandReturnObject &result)
1868 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1869 StackFrame *frame = m_exe_ctx.GetFramePtr();
1870 Thread *thread = m_exe_ctx.GetThreadPtr();
1871 Target *target = m_exe_ctx.GetTargetPtr();
1872 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1874 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1876 // Use this address directly.
1877 Address dest = Address(m_options.m_load_addr);
1879 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1880 if (callAddr == LLDB_INVALID_ADDRESS)
1882 result.AppendErrorWithFormat ("Invalid destination address.");
1883 result.SetStatus (eReturnStatusFailed);
1887 if (!reg_ctx->SetPC (callAddr))
1889 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1890 result.SetStatus (eReturnStatusFailed);
1896 // Pick either the absolute line, or work out a relative one.
1897 int32_t line = (int32_t)m_options.m_line_num;
1899 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1901 // Try the current file, but override if asked.
1902 FileSpec file = sym_ctx.line_entry.file;
1903 if (m_options.m_filenames.GetSize() == 1)
1904 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1908 result.AppendErrorWithFormat ("No source file available for the current location.");
1909 result.SetStatus (eReturnStatusFailed);
1913 std::string warnings;
1914 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1918 result.SetError (err);
1922 if (!warnings.empty())
1923 result.AppendWarning (warnings.c_str());
1926 result.SetStatus (eReturnStatusSuccessFinishResult);
1930 CommandOptions m_options;
1933 CommandObjectThreadJump::CommandOptions::g_option_table[] =
1935 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1936 "Specifies the source file to jump to."},
1938 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
1939 "Specifies the line number to jump to."},
1941 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
1942 "Jumps by a relative line offset from the current line."},
1944 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
1945 "Jumps to a specific address."},
1949 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
1951 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1954 //-------------------------------------------------------------------------
1955 // Next are the subcommands of CommandObjectMultiwordThreadPlan
1956 //-------------------------------------------------------------------------
1959 //-------------------------------------------------------------------------
1960 // CommandObjectThreadPlanList
1961 //-------------------------------------------------------------------------
1962 class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1966 class CommandOptions : public Options
1970 CommandOptions (CommandInterpreter &interpreter) :
1971 Options(interpreter)
1973 // Keep default values of all options in one place: OptionParsingStarting ()
1974 OptionParsingStarting ();
1983 SetOptionValue (uint32_t option_idx, const char *option_arg)
1986 const int short_option = m_getopt_table[option_idx].val;
1988 switch (short_option)
2001 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2009 OptionParsingStarting ()
2015 const OptionDefinition*
2018 return g_option_table;
2021 // Options table: Required for subclasses of Options.
2023 static OptionDefinition g_option_table[];
2025 // Instance variables to hold the values for command options.
2030 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
2031 CommandObjectIterateOverThreads (interpreter,
2033 "Show thread plans for one or more threads. If no threads are specified, show the "
2034 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2036 eFlagRequiresProcess |
2037 eFlagRequiresThread |
2038 eFlagTryTargetAPILock |
2039 eFlagProcessMustBeLaunched |
2040 eFlagProcessMustBePaused ),
2041 m_options(interpreter)
2045 ~CommandObjectThreadPlanList ()
2057 HandleOneThread (Thread &thread, CommandReturnObject &result)
2059 Stream &strm = result.GetOutputStream();
2060 DescriptionLevel desc_level = eDescriptionLevelFull;
2061 if (m_options.m_verbose)
2062 desc_level = eDescriptionLevelVerbose;
2064 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2067 CommandOptions m_options;
2071 CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2073 { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
2074 { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2075 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2078 class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2081 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
2082 CommandObjectParsed (interpreter,
2083 "thread plan discard",
2084 "Discards thread plans up to and including the plan passed as the command argument."
2085 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2086 " without the \"-i\" argument.",
2088 eFlagRequiresProcess |
2089 eFlagRequiresThread |
2090 eFlagTryTargetAPILock |
2091 eFlagProcessMustBeLaunched |
2092 eFlagProcessMustBePaused )
2094 CommandArgumentEntry arg;
2095 CommandArgumentData plan_index_arg;
2097 // Define the first (and only) variant of this arg.
2098 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2099 plan_index_arg.arg_repetition = eArgRepeatPlain;
2101 // There is only one variant this argument could be; put it into the argument entry.
2102 arg.push_back (plan_index_arg);
2104 // Push the data for the first argument into the m_arguments vector.
2105 m_arguments.push_back (arg);
2108 virtual ~CommandObjectThreadPlanDiscard () {}
2111 DoExecute (Args& args, CommandReturnObject &result)
2113 Thread *thread = m_exe_ctx.GetThreadPtr();
2114 if (args.GetArgumentCount() != 1)
2116 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2117 args.GetArgumentCount());
2118 result.SetStatus (eReturnStatusFailed);
2123 uint32_t thread_plan_idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
2126 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2127 args.GetArgumentAtIndex(0));
2128 result.SetStatus (eReturnStatusFailed);
2132 if (thread_plan_idx == 0)
2134 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2135 result.SetStatus (eReturnStatusFailed);
2139 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2141 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2146 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2147 args.GetArgumentAtIndex(0));
2148 result.SetStatus (eReturnStatusFailed);
2154 //-------------------------------------------------------------------------
2155 // CommandObjectMultiwordThreadPlan
2156 //-------------------------------------------------------------------------
2158 class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2161 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2162 CommandObjectMultiword (interpreter,
2164 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2165 "thread plan <subcommand> [<subcommand objects]")
2167 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2168 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2171 virtual ~CommandObjectMultiwordThreadPlan () {}
2176 //-------------------------------------------------------------------------
2177 // CommandObjectMultiwordThread
2178 //-------------------------------------------------------------------------
2180 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
2181 CommandObjectMultiword (interpreter,
2183 "A set of commands for operating on one or more threads within a running process.",
2184 "thread <subcommand> [<subcommand-options>]")
2186 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2187 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2188 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
2189 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
2190 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
2191 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2192 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
2193 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
2194 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2197 "Source level single step in specified thread (current thread, if none specified).",
2200 eStepScopeSource)));
2202 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2205 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
2208 eStepScopeSource)));
2210 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2213 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
2216 eStepScopeSource)));
2218 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2221 "Single step one instruction in specified thread (current thread, if none specified).",
2224 eStepScopeInstruction)));
2226 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2228 "thread step-inst-over",
2229 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
2232 eStepScopeInstruction)));
2234 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2236 "thread step-scripted",
2237 "Step as instructed by the script class passed in the -C option.",
2240 eStepScopeSource)));
2242 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
2245 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()