blob: e5662dd44789fa77f71bce0bee2c5b9d2f5ff699 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectThread.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/SourceManager.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include "lldb/Core/State.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000018#include "lldb/Core/ValueObject.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000019#include "lldb/Host/Host.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000020#include "lldb/Host/StringConvert.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Interpreter/CommandInterpreter.h"
22#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton1f746072012-08-29 21:13:06 +000023#include "lldb/Interpreter/Options.h"
24#include "lldb/Symbol/CompileUnit.h"
25#include "lldb/Symbol/Function.h"
Greg Clayton1f746072012-08-29 21:13:06 +000026#include "lldb/Symbol/LineEntry.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000027#include "lldb/Symbol/LineTable.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Target/Process.h"
29#include "lldb/Target/RegisterContext.h"
Jason Molenda750ea692013-11-12 07:02:07 +000030#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
33#include "lldb/Target/ThreadPlan.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000034#include "lldb/Target/ThreadPlanStepInRange.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Target/ThreadPlanStepInstruction.h"
36#include "lldb/Target/ThreadPlanStepOut.h"
37#include "lldb/Target/ThreadPlanStepRange.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000038#include "lldb/lldb-private.h"
Greg Clayton1f746072012-08-29 21:13:06 +000039
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040using namespace lldb;
41using namespace lldb_private;
42
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043//-------------------------------------------------------------------------
44// CommandObjectThreadBacktrace
45//-------------------------------------------------------------------------
46
Kate Stoneb9c1b512016-09-06 20:57:50 +000047class CommandObjectIterateOverThreads : public CommandObjectParsed {
Jim Ingham2bdbfd52014-09-29 23:17:18 +000048public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 CommandObjectIterateOverThreads(CommandInterpreter &interpreter,
50 const char *name, const char *help,
51 const char *syntax, uint32_t flags)
52 : CommandObjectParsed(interpreter, name, help, syntax, flags) {}
53
54 ~CommandObjectIterateOverThreads() override = default;
55
56 bool DoExecute(Args &command, CommandReturnObject &result) override {
57 result.SetStatus(m_success_return);
58
59 if (command.GetArgumentCount() == 0) {
60 Thread *thread = m_exe_ctx.GetThreadPtr();
61 if (!HandleOneThread(thread->GetID(), result))
62 return false;
63 return result.Succeeded();
Jim Ingham2bdbfd52014-09-29 23:17:18 +000064 }
65
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 // Use tids instead of ThreadSPs to prevent deadlocking problems which
67 // result from JIT-ing
68 // code while iterating over the (locked) ThreadSP list.
69 std::vector<lldb::tid_t> tids;
Bruce Mitchener13d21e92015-10-07 16:56:17 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 if (command.GetArgumentCount() == 1 &&
72 ::strcmp(command.GetArgumentAtIndex(0), "all") == 0) {
73 Process *process = m_exe_ctx.GetProcessPtr();
Jim Ingham2bdbfd52014-09-29 23:17:18 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 for (ThreadSP thread_sp : process->Threads())
76 tids.push_back(thread_sp->GetID());
77 } else {
78 const size_t num_args = command.GetArgumentCount();
79 Process *process = m_exe_ctx.GetProcessPtr();
80
81 std::lock_guard<std::recursive_mutex> guard(
82 process->GetThreadList().GetMutex());
83
84 for (size_t i = 0; i < num_args; i++) {
85 bool success;
86
87 uint32_t thread_idx = StringConvert::ToUInt32(
88 command.GetArgumentAtIndex(i), 0, 0, &success);
89 if (!success) {
90 result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
91 command.GetArgumentAtIndex(i));
92 result.SetStatus(eReturnStatusFailed);
93 return false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +000094 }
Stephane Sezerf8104912016-03-17 18:52:41 +000095
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 ThreadSP thread =
97 process->GetThreadList().FindThreadByIndexID(thread_idx);
Stephane Sezerf8104912016-03-17 18:52:41 +000098
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 if (!thread) {
100 result.AppendErrorWithFormat("no thread with index: \"%s\"\n",
101 command.GetArgumentAtIndex(i));
102 result.SetStatus(eReturnStatusFailed);
103 return false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000104 }
Stephane Sezerf8104912016-03-17 18:52:41 +0000105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106 tids.push_back(thread->GetID());
107 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000108 }
109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 uint32_t idx = 0;
111 for (const lldb::tid_t &tid : tids) {
112 if (idx != 0 && m_add_return)
113 result.AppendMessage("");
114
115 if (!HandleOneThread(tid, result))
116 return false;
117
118 ++idx;
119 }
120 return result.Succeeded();
121 }
122
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000123protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 // Override this to do whatever you need to do for one thread.
125 //
126 // If you return false, the iteration will stop, otherwise it will proceed.
127 // The result is set to m_success_return (defaults to
128 // eReturnStatusSuccessFinishResult) before the iteration,
129 // so you only need to set the return status in HandleOneThread if you want to
130 // indicate an error.
131 // If m_add_return is true, a blank line will be inserted between each of the
132 // listings (except the last one.)
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 virtual bool HandleOneThread(lldb::tid_t, CommandReturnObject &result) = 0;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
137 bool m_add_return = true;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000138};
139
140//-------------------------------------------------------------------------
141// CommandObjectThreadBacktrace
142//-------------------------------------------------------------------------
143
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000144static OptionDefinition g_thread_backtrace_options[] = {
145 // clang-format off
146 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)" },
147 { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace" },
148 { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available" }
149 // clang-format on
150};
151
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 class CommandOptions : public Options {
155 public:
156 CommandOptions() : Options() {
157 // Keep default values of all options in one place: OptionParsingStarting
158 // ()
159 OptionParsingStarting(nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 }
161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 ~CommandOptions() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
165 ExecutionContext *execution_context) override {
166 Error error;
167 const int short_option = m_getopt_table[option_idx].val;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000168 auto option_strref = llvm::StringRef::withNullAsEmpty(option_arg);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169
170 switch (short_option) {
171 case 'c': {
172 bool success;
173 int32_t input_count =
174 StringConvert::ToSInt32(option_arg, -1, 0, &success);
175 if (!success)
176 error.SetErrorStringWithFormat(
177 "invalid integer value for option '%c'", short_option);
178 if (input_count < -1)
179 m_count = UINT32_MAX;
180 else
181 m_count = input_count;
182 } break;
183 case 's': {
184 bool success;
185 m_start = StringConvert::ToUInt32(option_arg, 0, 0, &success);
186 if (!success)
187 error.SetErrorStringWithFormat(
188 "invalid integer value for option '%c'", short_option);
189 } break;
190 case 'e': {
191 bool success;
192 m_extended_backtrace =
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000193 Args::StringToBoolean(option_strref, false, &success);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 if (!success)
195 error.SetErrorStringWithFormat(
196 "invalid boolean value for option '%c'", short_option);
197 } break;
198 default:
199 error.SetErrorStringWithFormat("invalid short option character '%c'",
200 short_option);
201 break;
202 }
203 return error;
Jim Inghame2e0b452010-08-26 23:36:03 +0000204 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 void OptionParsingStarting(ExecutionContext *execution_context) override {
207 m_count = UINT32_MAX;
208 m_start = 0;
209 m_extended_backtrace = false;
210 }
211
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000212 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000213 return llvm::makeArrayRef(g_thread_backtrace_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000214 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215
216 // Instance variables to hold the values for command options.
217 uint32_t m_count;
218 uint32_t m_start;
219 bool m_extended_backtrace;
220 };
221
222 CommandObjectThreadBacktrace(CommandInterpreter &interpreter)
223 : CommandObjectIterateOverThreads(
224 interpreter, "thread backtrace",
225 "Show thread call stacks. Defaults to the current thread, thread "
226 "indexes can be specified as arguments. Use the thread-index "
227 "\"all\" "
228 "to see all threads.",
229 nullptr,
230 eCommandRequiresProcess | eCommandRequiresThread |
231 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
232 eCommandProcessMustBePaused),
233 m_options() {}
234
235 ~CommandObjectThreadBacktrace() override = default;
236
237 Options *GetOptions() override { return &m_options; }
238
Jim Ingham5a988412012-06-08 21:56:10 +0000239protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240 void DoExtendedBacktrace(Thread *thread, CommandReturnObject &result) {
241 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
242 if (runtime) {
243 Stream &strm = result.GetOutputStream();
244 const std::vector<ConstString> &types =
245 runtime->GetExtendedBacktraceTypes();
246 for (auto type : types) {
247 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread(
248 thread->shared_from_this(), type);
249 if (ext_thread_sp && ext_thread_sp->IsValid()) {
250 const uint32_t num_frames_with_source = 0;
Jim Ingham6a9767c2016-11-08 20:36:40 +0000251 const bool stop_format = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 if (ext_thread_sp->GetStatus(strm, m_options.m_start,
253 m_options.m_count,
Jim Ingham6a9767c2016-11-08 20:36:40 +0000254 num_frames_with_source,
255 stop_format)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000256 DoExtendedBacktrace(ext_thread_sp.get(), result);
257 }
Jason Molenda750ea692013-11-12 07:02:07 +0000258 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 }
260 }
261 }
262
263 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
264 ThreadSP thread_sp =
265 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
266 if (!thread_sp) {
267 result.AppendErrorWithFormat(
268 "thread disappeared while computing backtraces: 0x%" PRIx64 "\n",
269 tid);
270 result.SetStatus(eReturnStatusFailed);
271 return false;
Jason Molenda750ea692013-11-12 07:02:07 +0000272 }
273
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 Thread *thread = thread_sp.get();
Stephane Sezerf8104912016-03-17 18:52:41 +0000275
Kate Stoneb9c1b512016-09-06 20:57:50 +0000276 Stream &strm = result.GetOutputStream();
Stephane Sezerf8104912016-03-17 18:52:41 +0000277
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 // Don't show source context when doing backtraces.
279 const uint32_t num_frames_with_source = 0;
Jim Ingham4f243e82016-11-08 23:43:36 +0000280 const bool stop_format = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 if (!thread->GetStatus(strm, m_options.m_start, m_options.m_count,
Jim Ingham4f243e82016-11-08 23:43:36 +0000282 num_frames_with_source, stop_format)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000283 result.AppendErrorWithFormat(
284 "error displaying backtrace for thread: \"0x%4.4x\"\n",
285 thread->GetIndexID());
286 result.SetStatus(eReturnStatusFailed);
287 return false;
288 }
289 if (m_options.m_extended_backtrace) {
290 DoExtendedBacktrace(thread, result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291 }
Jim Ingham5a988412012-06-08 21:56:10 +0000292
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 return true;
294 }
295
296 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297};
298
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299enum StepScope { eStepScopeSource, eStepScopeInstruction };
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000301static OptionEnumValueElement g_tri_running_mode[] = {
302 {eOnlyThisThread, "this-thread", "Run only this thread"},
303 {eAllThreads, "all-threads", "Run all threads"},
304 {eOnlyDuringStepping, "while-stepping",
305 "Run only this thread while stepping"},
306 {0, nullptr, nullptr}};
307
308static OptionEnumValueElement g_duo_running_mode[] = {
309 {eOnlyThisThread, "this-thread", "Run only this thread"},
310 {eAllThreads, "all-threads", "Run all threads"},
311 {0, nullptr, nullptr}};
312
313static OptionDefinition g_thread_step_scope_options[] = {
314 // clang-format off
315 { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information." },
316 { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information." },
317 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst." },
318 { LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over. You can also pass the string 'block' to step to the end of the current block. This is particularly useful in conjunction with --step-target to step through a complex calling sequence." },
319 { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread." },
320 { LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in." },
321 { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into." },
322 { LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step." }
323 // clang-format on
324};
325
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328 class CommandOptions : public Options {
329 public:
330 CommandOptions() : Options() {
331 // Keep default values of all options in one place: OptionParsingStarting
332 // ()
333 OptionParsingStarting(nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334 }
335
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336 ~CommandOptions() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
339 ExecutionContext *execution_context) override {
340 Error error;
341 const int short_option = m_getopt_table[option_idx].val;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000342 auto option_strref = llvm::StringRef::withNullAsEmpty(option_arg);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343
344 switch (short_option) {
345 case 'a': {
346 bool success;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000347 bool avoid_no_debug =
348 Args::StringToBoolean(option_strref, true, &success);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349 if (!success)
350 error.SetErrorStringWithFormat(
351 "invalid boolean value for option '%c'", short_option);
352 else {
353 m_step_in_avoid_no_debug =
354 avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
355 }
356 } break;
357
358 case 'A': {
359 bool success;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000360 bool avoid_no_debug =
361 Args::StringToBoolean(option_strref, true, &success);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362 if (!success)
363 error.SetErrorStringWithFormat(
364 "invalid boolean value for option '%c'", short_option);
365 else {
366 m_step_out_avoid_no_debug =
367 avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
368 }
369 } break;
370
371 case 'c':
372 m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
373 if (m_step_count == UINT32_MAX)
374 error.SetErrorStringWithFormat("invalid step count '%s'", option_arg);
375 break;
376
377 case 'C':
378 m_class_name.clear();
379 m_class_name.assign(option_arg);
380 break;
381
382 case 'm': {
383 OptionEnumValueElement *enum_values =
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000384 GetDefinitions()[option_idx].enum_values;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385 m_run_mode = (lldb::RunMode)Args::StringToOptionEnum(
Zachary Turner8cef4b02016-09-23 17:48:13 +0000386 option_strref, enum_values, eOnlyDuringStepping, error);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000387 } break;
388
389 case 'e': {
390 if (strcmp(option_arg, "block") == 0) {
391 m_end_line_is_block_end = 1;
392 break;
393 }
394 uint32_t tmp_end_line =
395 StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
396 if (tmp_end_line == UINT32_MAX)
397 error.SetErrorStringWithFormat("invalid end line number '%s'",
398 option_arg);
399 else
400 m_end_line = tmp_end_line;
401 break;
402 } break;
403
404 case 'r':
405 m_avoid_regexp.clear();
406 m_avoid_regexp.assign(option_arg);
407 break;
408
409 case 't':
410 m_step_in_target.clear();
411 m_step_in_target.assign(option_arg);
412 break;
413
414 default:
415 error.SetErrorStringWithFormat("invalid short option character '%c'",
416 short_option);
417 break;
418 }
419 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420 }
421
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 void OptionParsingStarting(ExecutionContext *execution_context) override {
423 m_step_in_avoid_no_debug = eLazyBoolCalculate;
424 m_step_out_avoid_no_debug = eLazyBoolCalculate;
425 m_run_mode = eOnlyDuringStepping;
426
427 // Check if we are in Non-Stop mode
428 TargetSP target_sp =
429 execution_context ? execution_context->GetTargetSP() : TargetSP();
430 if (target_sp && target_sp->GetNonStopModeEnabled())
431 m_run_mode = eOnlyThisThread;
432
433 m_avoid_regexp.clear();
434 m_step_in_target.clear();
435 m_class_name.clear();
436 m_step_count = 1;
437 m_end_line = LLDB_INVALID_LINE_NUMBER;
438 m_end_line_is_block_end = false;
439 }
440
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000441 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000442 return llvm::makeArrayRef(g_thread_step_scope_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000443 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444
445 // Instance variables to hold the values for command options.
446 LazyBool m_step_in_avoid_no_debug;
447 LazyBool m_step_out_avoid_no_debug;
448 RunMode m_run_mode;
449 std::string m_avoid_regexp;
450 std::string m_step_in_target;
451 std::string m_class_name;
452 uint32_t m_step_count;
453 uint32_t m_end_line;
454 bool m_end_line_is_block_end;
455 };
456
457 CommandObjectThreadStepWithTypeAndScope(CommandInterpreter &interpreter,
458 const char *name, const char *help,
459 const char *syntax,
460 StepType step_type,
461 StepScope step_scope)
462 : CommandObjectParsed(interpreter, name, help, syntax,
463 eCommandRequiresProcess | eCommandRequiresThread |
464 eCommandTryTargetAPILock |
465 eCommandProcessMustBeLaunched |
466 eCommandProcessMustBePaused),
467 m_step_type(step_type), m_step_scope(step_scope), m_options() {
468 CommandArgumentEntry arg;
469 CommandArgumentData thread_id_arg;
470
471 // Define the first (and only) variant of this arg.
472 thread_id_arg.arg_type = eArgTypeThreadID;
473 thread_id_arg.arg_repetition = eArgRepeatOptional;
474
475 // There is only one variant this argument could be; put it into the
476 // argument entry.
477 arg.push_back(thread_id_arg);
478
479 // Push the data for the first argument into the m_arguments vector.
480 m_arguments.push_back(arg);
481 }
482
483 ~CommandObjectThreadStepWithTypeAndScope() override = default;
484
485 Options *GetOptions() override { return &m_options; }
486
Jim Ingham5a988412012-06-08 21:56:10 +0000487protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488 bool DoExecute(Args &command, CommandReturnObject &result) override {
489 Process *process = m_exe_ctx.GetProcessPtr();
490 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491
Kate Stoneb9c1b512016-09-06 20:57:50 +0000492 const uint32_t num_threads = process->GetThreadList().GetSize();
493 Thread *thread = nullptr;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000494
Kate Stoneb9c1b512016-09-06 20:57:50 +0000495 if (command.GetArgumentCount() == 0) {
496 thread = GetDefaultThread();
Jim Ingham8d94ba02016-03-12 02:45:34 +0000497
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498 if (thread == nullptr) {
499 result.AppendError("no selected thread in process");
500 result.SetStatus(eReturnStatusFailed);
501 return false;
502 }
503 } else {
504 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
505 uint32_t step_thread_idx =
506 StringConvert::ToUInt32(thread_idx_cstr, LLDB_INVALID_INDEX32);
507 if (step_thread_idx == LLDB_INVALID_INDEX32) {
508 result.AppendErrorWithFormat("invalid thread index '%s'.\n",
509 thread_idx_cstr);
510 result.SetStatus(eReturnStatusFailed);
511 return false;
512 }
513 thread =
514 process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
515 if (thread == nullptr) {
516 result.AppendErrorWithFormat(
517 "Thread index %u is out of range (valid values are 0 - %u).\n",
518 step_thread_idx, num_threads);
519 result.SetStatus(eReturnStatusFailed);
520 return false;
521 }
522 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000523
Kate Stoneb9c1b512016-09-06 20:57:50 +0000524 if (m_step_type == eStepTypeScripted) {
525 if (m_options.m_class_name.empty()) {
526 result.AppendErrorWithFormat("empty class name for scripted step.");
527 result.SetStatus(eReturnStatusFailed);
528 return false;
529 } else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(
530 m_options.m_class_name.c_str())) {
531 result.AppendErrorWithFormat(
532 "class for scripted step: \"%s\" does not exist.",
533 m_options.m_class_name.c_str());
534 result.SetStatus(eReturnStatusFailed);
535 return false;
536 }
537 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000538
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER &&
540 m_step_type != eStepTypeInto) {
541 result.AppendErrorWithFormat(
542 "end line option is only valid for step into");
543 result.SetStatus(eReturnStatusFailed);
544 return false;
545 }
546
547 const bool abort_other_plans = false;
548 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
549
550 // This is a bit unfortunate, but not all the commands in this command
551 // object support
552 // only while stepping, so I use the bool for them.
553 bool bool_stop_other_threads;
554 if (m_options.m_run_mode == eAllThreads)
555 bool_stop_other_threads = false;
556 else if (m_options.m_run_mode == eOnlyDuringStepping)
557 bool_stop_other_threads =
558 (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
559 else
560 bool_stop_other_threads = true;
561
562 ThreadPlanSP new_plan_sp;
563
564 if (m_step_type == eStepTypeInto) {
565 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
566 assert(frame != nullptr);
567
568 if (frame->HasDebugInformation()) {
569 AddressRange range;
570 SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
571 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER) {
572 Error error;
573 if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range,
574 error)) {
575 result.AppendErrorWithFormat("invalid end-line option: %s.",
576 error.AsCString());
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000577 result.SetStatus(eReturnStatusFailed);
578 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 }
580 } else if (m_options.m_end_line_is_block_end) {
581 Error error;
582 Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
583 if (!block) {
584 result.AppendErrorWithFormat("Could not find the current block.");
585 result.SetStatus(eReturnStatusFailed);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000586 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000587 }
588
589 AddressRange block_range;
590 Address pc_address = frame->GetFrameCodeAddress();
591 block->GetRangeContainingAddress(pc_address, block_range);
592 if (!block_range.GetBaseAddress().IsValid()) {
593 result.AppendErrorWithFormat(
594 "Could not find the current block address.");
595 result.SetStatus(eReturnStatusFailed);
596 return false;
597 }
598 lldb::addr_t pc_offset_in_block =
599 pc_address.GetFileAddress() -
600 block_range.GetBaseAddress().GetFileAddress();
601 lldb::addr_t range_length =
602 block_range.GetByteSize() - pc_offset_in_block;
603 range = AddressRange(pc_address, range_length);
604 } else {
605 range = sc.line_entry.range;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000606 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000607
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608 new_plan_sp = thread->QueueThreadPlanForStepInRange(
609 abort_other_plans, range,
610 frame->GetSymbolContext(eSymbolContextEverything),
611 m_options.m_step_in_target.c_str(), stop_other_threads,
612 m_options.m_step_in_avoid_no_debug,
613 m_options.m_step_out_avoid_no_debug);
Greg Claytondc6224e2014-10-21 01:00:42 +0000614
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615 if (new_plan_sp && !m_options.m_avoid_regexp.empty()) {
616 ThreadPlanStepInRange *step_in_range_plan =
617 static_cast<ThreadPlanStepInRange *>(new_plan_sp.get());
618 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000619 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000620 } else
621 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
622 false, abort_other_plans, bool_stop_other_threads);
623 } else if (m_step_type == eStepTypeOver) {
624 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
625
626 if (frame->HasDebugInformation())
627 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
628 abort_other_plans,
629 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
630 frame->GetSymbolContext(eSymbolContextEverything),
631 stop_other_threads, m_options.m_step_out_avoid_no_debug);
632 else
633 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
634 true, abort_other_plans, bool_stop_other_threads);
635 } else if (m_step_type == eStepTypeTrace) {
636 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
637 false, abort_other_plans, bool_stop_other_threads);
638 } else if (m_step_type == eStepTypeTraceOver) {
639 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
640 true, abort_other_plans, bool_stop_other_threads);
641 } else if (m_step_type == eStepTypeOut) {
642 new_plan_sp = thread->QueueThreadPlanForStepOut(
643 abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes,
644 eVoteNoOpinion, thread->GetSelectedFrameIndex(),
645 m_options.m_step_out_avoid_no_debug);
646 } else if (m_step_type == eStepTypeScripted) {
647 new_plan_sp = thread->QueueThreadPlanForStepScripted(
648 abort_other_plans, m_options.m_class_name.c_str(),
649 bool_stop_other_threads);
650 } else {
651 result.AppendError("step type is not supported");
652 result.SetStatus(eReturnStatusFailed);
653 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654 }
655
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 // If we got a new plan, then set it to be a master plan (User level Plans
657 // should be master plans
658 // so that they can be interruptible). Then resume the process.
659
660 if (new_plan_sp) {
661 new_plan_sp->SetIsMasterPlan(true);
662 new_plan_sp->SetOkayToDiscard(false);
663
664 if (m_options.m_step_count > 1) {
665 if (new_plan_sp->SetIterationCount(m_options.m_step_count)) {
666 result.AppendWarning(
667 "step operation does not support iteration count.");
668 }
669 }
670
671 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
672
673 const uint32_t iohandler_id = process->GetIOHandlerID();
674
675 StreamString stream;
676 Error error;
677 if (synchronous_execution)
678 error = process->ResumeSynchronous(&stream);
679 else
680 error = process->Resume();
681
682 // There is a race condition where this thread will return up the call
683 // stack to the main command handler
684 // and show an (lldb) prompt before HandlePrivateEvent (from
685 // PrivateStateThread) has
686 // a chance to call PushProcessIOHandler().
687 process->SyncIOHandler(iohandler_id, 2000);
688
689 if (synchronous_execution) {
690 // If any state changed events had anything to say, add that to the
691 // result
692 if (stream.GetData())
693 result.AppendMessage(stream.GetData());
694
695 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
696 result.SetDidChangeProcessState(true);
697 result.SetStatus(eReturnStatusSuccessFinishNoResult);
698 } else {
699 result.SetStatus(eReturnStatusSuccessContinuingNoResult);
700 }
701 } else {
702 result.AppendError("Couldn't find thread plan to implement step type.");
703 result.SetStatus(eReturnStatusFailed);
704 }
705 return result.Succeeded();
706 }
707
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000708protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709 StepType m_step_type;
710 StepScope m_step_scope;
711 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000712};
713
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714//-------------------------------------------------------------------------
715// CommandObjectThreadContinue
716//-------------------------------------------------------------------------
717
Kate Stoneb9c1b512016-09-06 20:57:50 +0000718class CommandObjectThreadContinue : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000720 CommandObjectThreadContinue(CommandInterpreter &interpreter)
721 : CommandObjectParsed(
722 interpreter, "thread continue",
723 "Continue execution of the current target process. One "
724 "or more threads may be specified, by default all "
725 "threads continue.",
726 nullptr,
727 eCommandRequiresThread | eCommandTryTargetAPILock |
728 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
729 CommandArgumentEntry arg;
730 CommandArgumentData thread_idx_arg;
731
732 // Define the first (and only) variant of this arg.
733 thread_idx_arg.arg_type = eArgTypeThreadIndex;
734 thread_idx_arg.arg_repetition = eArgRepeatPlus;
735
736 // There is only one variant this argument could be; put it into the
737 // argument entry.
738 arg.push_back(thread_idx_arg);
739
740 // Push the data for the first argument into the m_arguments vector.
741 m_arguments.push_back(arg);
742 }
743
744 ~CommandObjectThreadContinue() override = default;
745
746 bool DoExecute(Args &command, CommandReturnObject &result) override {
747 bool synchronous_execution = m_interpreter.GetSynchronous();
748
749 if (!m_interpreter.GetDebugger().GetSelectedTarget()) {
750 result.AppendError("invalid target, create a debug target using the "
751 "'target create' command");
752 result.SetStatus(eReturnStatusFailed);
753 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 }
755
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756 Process *process = m_exe_ctx.GetProcessPtr();
757 if (process == nullptr) {
758 result.AppendError("no process exists. Cannot continue");
759 result.SetStatus(eReturnStatusFailed);
760 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000762
763 StateType state = process->GetState();
764 if ((state == eStateCrashed) || (state == eStateStopped) ||
765 (state == eStateSuspended)) {
766 const size_t argc = command.GetArgumentCount();
767 if (argc > 0) {
768 // These two lines appear at the beginning of both blocks in
769 // this if..else, but that is because we need to release the
770 // lock before calling process->Resume below.
771 std::lock_guard<std::recursive_mutex> guard(
772 process->GetThreadList().GetMutex());
773 const uint32_t num_threads = process->GetThreadList().GetSize();
774 std::vector<Thread *> resume_threads;
Zachary Turner97d2c402016-10-05 23:40:23 +0000775 for (auto &entry : command.entries()) {
776 uint32_t thread_idx;
777 if (entry.ref.getAsInteger(0, thread_idx)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000778 result.AppendErrorWithFormat(
Zachary Turner97d2c402016-10-05 23:40:23 +0000779 "invalid thread index argument: \"%s\".\n", entry.c_str());
780 result.SetStatus(eReturnStatusFailed);
781 return false;
782 }
783 Thread *thread =
784 process->GetThreadList().FindThreadByIndexID(thread_idx).get();
785
786 if (thread) {
787 resume_threads.push_back(thread);
788 } else {
789 result.AppendErrorWithFormat("invalid thread index %u.\n",
790 thread_idx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000791 result.SetStatus(eReturnStatusFailed);
792 return false;
793 }
794 }
795
796 if (resume_threads.empty()) {
797 result.AppendError("no valid thread indexes were specified");
798 result.SetStatus(eReturnStatusFailed);
799 return false;
800 } else {
801 if (resume_threads.size() == 1)
802 result.AppendMessageWithFormat("Resuming thread: ");
803 else
804 result.AppendMessageWithFormat("Resuming threads: ");
805
806 for (uint32_t idx = 0; idx < num_threads; ++idx) {
807 Thread *thread =
808 process->GetThreadList().GetThreadAtIndex(idx).get();
809 std::vector<Thread *>::iterator this_thread_pos =
810 find(resume_threads.begin(), resume_threads.end(), thread);
811
812 if (this_thread_pos != resume_threads.end()) {
813 resume_threads.erase(this_thread_pos);
814 if (!resume_threads.empty())
815 result.AppendMessageWithFormat("%u, ", thread->GetIndexID());
816 else
817 result.AppendMessageWithFormat("%u ", thread->GetIndexID());
818
819 const bool override_suspend = true;
820 thread->SetResumeState(eStateRunning, override_suspend);
821 } else {
822 thread->SetResumeState(eStateSuspended);
823 }
824 }
825 result.AppendMessageWithFormat("in process %" PRIu64 "\n",
826 process->GetID());
827 }
828 } else {
829 // These two lines appear at the beginning of both blocks in
830 // this if..else, but that is because we need to release the
831 // lock before calling process->Resume below.
832 std::lock_guard<std::recursive_mutex> guard(
833 process->GetThreadList().GetMutex());
834 const uint32_t num_threads = process->GetThreadList().GetSize();
835 Thread *current_thread = GetDefaultThread();
836 if (current_thread == nullptr) {
837 result.AppendError("the process doesn't have a current thread");
838 result.SetStatus(eReturnStatusFailed);
839 return false;
840 }
841 // Set the actions that the threads should each take when resuming
842 for (uint32_t idx = 0; idx < num_threads; ++idx) {
843 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
844 if (thread == current_thread) {
845 result.AppendMessageWithFormat("Resuming thread 0x%4.4" PRIx64
846 " in process %" PRIu64 "\n",
847 thread->GetID(), process->GetID());
848 const bool override_suspend = true;
849 thread->SetResumeState(eStateRunning, override_suspend);
850 } else {
851 thread->SetResumeState(eStateSuspended);
852 }
853 }
854 }
855
856 StreamString stream;
857 Error error;
858 if (synchronous_execution)
859 error = process->ResumeSynchronous(&stream);
860 else
861 error = process->Resume();
862
863 // We should not be holding the thread list lock when we do this.
864 if (error.Success()) {
865 result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
866 process->GetID());
867 if (synchronous_execution) {
868 // If any state changed events had anything to say, add that to the
869 // result
870 if (stream.GetData())
871 result.AppendMessage(stream.GetData());
872
873 result.SetDidChangeProcessState(true);
874 result.SetStatus(eReturnStatusSuccessFinishNoResult);
875 } else {
876 result.SetStatus(eReturnStatusSuccessContinuingNoResult);
877 }
878 } else {
879 result.AppendErrorWithFormat("Failed to resume process: %s\n",
880 error.AsCString());
881 result.SetStatus(eReturnStatusFailed);
882 }
883 } else {
884 result.AppendErrorWithFormat(
885 "Process cannot be continued from its current state (%s).\n",
886 StateAsCString(state));
887 result.SetStatus(eReturnStatusFailed);
888 }
889
890 return result.Succeeded();
891 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892};
893
894//-------------------------------------------------------------------------
895// CommandObjectThreadUntil
896//-------------------------------------------------------------------------
897
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000898static OptionDefinition g_thread_until_options[] = {
899 // clang-format off
900 { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0" },
901 { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation" },
902 { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one" },
903 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times." }
904 // clang-format on
905};
906
Kate Stoneb9c1b512016-09-06 20:57:50 +0000907class CommandObjectThreadUntil : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909 class CommandOptions : public Options {
910 public:
911 uint32_t m_thread_idx;
912 uint32_t m_frame_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914 CommandOptions()
915 : Options(), m_thread_idx(LLDB_INVALID_THREAD_ID),
916 m_frame_idx(LLDB_INVALID_FRAME_ID) {
917 // Keep default values of all options in one place: OptionParsingStarting
918 // ()
919 OptionParsingStarting(nullptr);
920 }
921
922 ~CommandOptions() override = default;
923
924 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
925 ExecutionContext *execution_context) override {
926 Error error;
927 const int short_option = m_getopt_table[option_idx].val;
928
929 switch (short_option) {
930 case 'a': {
931 lldb::addr_t tmp_addr = Args::StringToAddress(
932 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
933 if (error.Success())
934 m_until_addrs.push_back(tmp_addr);
935 } break;
936 case 't':
937 m_thread_idx =
938 StringConvert::ToUInt32(option_arg, LLDB_INVALID_INDEX32);
939 if (m_thread_idx == LLDB_INVALID_INDEX32) {
940 error.SetErrorStringWithFormat("invalid thread index '%s'",
941 option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000942 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000943 break;
944 case 'f':
945 m_frame_idx =
946 StringConvert::ToUInt32(option_arg, LLDB_INVALID_FRAME_ID);
947 if (m_frame_idx == LLDB_INVALID_FRAME_ID) {
948 error.SetErrorStringWithFormat("invalid frame index '%s'",
949 option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000951 break;
952 case 'm': {
953 OptionEnumValueElement *enum_values =
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000954 GetDefinitions()[option_idx].enum_values;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000955 lldb::RunMode run_mode = (lldb::RunMode)Args::StringToOptionEnum(
Zachary Turner8cef4b02016-09-23 17:48:13 +0000956 llvm::StringRef::withNullAsEmpty(option_arg), enum_values,
957 eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000958
Kate Stoneb9c1b512016-09-06 20:57:50 +0000959 if (error.Success()) {
960 if (run_mode == eAllThreads)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961 m_stop_others = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000962 else
963 m_stop_others = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000965 } break;
966 default:
967 error.SetErrorStringWithFormat("invalid short option character '%c'",
968 short_option);
969 break;
970 }
971 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972 }
973
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974 void OptionParsingStarting(ExecutionContext *execution_context) override {
975 m_thread_idx = LLDB_INVALID_THREAD_ID;
976 m_frame_idx = 0;
977 m_stop_others = false;
978 m_until_addrs.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979 }
980
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000981 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000982 return llvm::makeArrayRef(g_thread_until_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000983 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000984
985 uint32_t m_step_thread_idx;
986 bool m_stop_others;
987 std::vector<lldb::addr_t> m_until_addrs;
988
Kate Stoneb9c1b512016-09-06 20:57:50 +0000989 // Instance variables to hold the values for command options.
990 };
991
992 CommandObjectThreadUntil(CommandInterpreter &interpreter)
993 : CommandObjectParsed(
994 interpreter, "thread until",
995 "Continue until a line number or address is reached by the "
996 "current or specified thread. Stops when returning from "
997 "the current function as a safety measure.",
998 nullptr,
999 eCommandRequiresThread | eCommandTryTargetAPILock |
1000 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
1001 m_options() {
1002 CommandArgumentEntry arg;
1003 CommandArgumentData line_num_arg;
1004
1005 // Define the first (and only) variant of this arg.
1006 line_num_arg.arg_type = eArgTypeLineNum;
1007 line_num_arg.arg_repetition = eArgRepeatPlain;
1008
1009 // There is only one variant this argument could be; put it into the
1010 // argument entry.
1011 arg.push_back(line_num_arg);
1012
1013 // Push the data for the first argument into the m_arguments vector.
1014 m_arguments.push_back(arg);
1015 }
1016
1017 ~CommandObjectThreadUntil() override = default;
1018
1019 Options *GetOptions() override { return &m_options; }
1020
Jim Ingham5a988412012-06-08 21:56:10 +00001021protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 bool DoExecute(Args &command, CommandReturnObject &result) override {
1023 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001024
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1026 if (target == nullptr) {
1027 result.AppendError("invalid target, create a debug target using the "
1028 "'target create' command");
1029 result.SetStatus(eReturnStatusFailed);
1030 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031 }
Jim Ingham5a988412012-06-08 21:56:10 +00001032
Kate Stoneb9c1b512016-09-06 20:57:50 +00001033 Process *process = m_exe_ctx.GetProcessPtr();
1034 if (process == nullptr) {
1035 result.AppendError("need a valid process to step");
1036 result.SetStatus(eReturnStatusFailed);
1037 } else {
1038 Thread *thread = nullptr;
1039 std::vector<uint32_t> line_numbers;
1040
1041 if (command.GetArgumentCount() >= 1) {
1042 size_t num_args = command.GetArgumentCount();
1043 for (size_t i = 0; i < num_args; i++) {
1044 uint32_t line_number;
1045 line_number = StringConvert::ToUInt32(command.GetArgumentAtIndex(0),
1046 UINT32_MAX);
1047 if (line_number == UINT32_MAX) {
1048 result.AppendErrorWithFormat("invalid line number: '%s'.\n",
1049 command.GetArgumentAtIndex(0));
1050 result.SetStatus(eReturnStatusFailed);
1051 return false;
1052 } else
1053 line_numbers.push_back(line_number);
1054 }
1055 } else if (m_options.m_until_addrs.empty()) {
1056 result.AppendErrorWithFormat("No line number or address provided:\n%s",
1057 GetSyntax());
1058 result.SetStatus(eReturnStatusFailed);
1059 return false;
1060 }
1061
1062 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) {
1063 thread = GetDefaultThread();
1064 } else {
1065 thread = process->GetThreadList()
1066 .FindThreadByIndexID(m_options.m_thread_idx)
1067 .get();
1068 }
1069
1070 if (thread == nullptr) {
1071 const uint32_t num_threads = process->GetThreadList().GetSize();
1072 result.AppendErrorWithFormat(
1073 "Thread index %u is out of range (valid values are 0 - %u).\n",
1074 m_options.m_thread_idx, num_threads);
1075 result.SetStatus(eReturnStatusFailed);
1076 return false;
1077 }
1078
1079 const bool abort_other_plans = false;
1080
1081 StackFrame *frame =
1082 thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
1083 if (frame == nullptr) {
1084 result.AppendErrorWithFormat(
1085 "Frame index %u is out of range for thread %u.\n",
1086 m_options.m_frame_idx, m_options.m_thread_idx);
1087 result.SetStatus(eReturnStatusFailed);
1088 return false;
1089 }
1090
1091 ThreadPlanSP new_plan_sp;
1092
1093 if (frame->HasDebugInformation()) {
1094 // Finally we got here... Translate the given line number to a bunch of
1095 // addresses:
1096 SymbolContext sc(frame->GetSymbolContext(eSymbolContextCompUnit));
1097 LineTable *line_table = nullptr;
1098 if (sc.comp_unit)
1099 line_table = sc.comp_unit->GetLineTable();
1100
1101 if (line_table == nullptr) {
1102 result.AppendErrorWithFormat("Failed to resolve the line table for "
1103 "frame %u of thread index %u.\n",
1104 m_options.m_frame_idx,
1105 m_options.m_thread_idx);
1106 result.SetStatus(eReturnStatusFailed);
1107 return false;
1108 }
1109
1110 LineEntry function_start;
1111 uint32_t index_ptr = 0, end_ptr;
1112 std::vector<addr_t> address_list;
1113
1114 // Find the beginning & end index of the
1115 AddressRange fun_addr_range = sc.function->GetAddressRange();
1116 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1117 line_table->FindLineEntryByAddress(fun_start_addr, function_start,
1118 &index_ptr);
1119
1120 Address fun_end_addr(fun_start_addr.GetSection(),
1121 fun_start_addr.GetOffset() +
1122 fun_addr_range.GetByteSize());
1123
1124 bool all_in_function = true;
1125
1126 line_table->FindLineEntryByAddress(fun_end_addr, function_start,
1127 &end_ptr);
1128
1129 for (uint32_t line_number : line_numbers) {
1130 uint32_t start_idx_ptr = index_ptr;
1131 while (start_idx_ptr <= end_ptr) {
1132 LineEntry line_entry;
1133 const bool exact = false;
1134 start_idx_ptr = sc.comp_unit->FindLineEntry(
1135 start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
1136 if (start_idx_ptr == UINT32_MAX)
1137 break;
1138
1139 addr_t address =
1140 line_entry.range.GetBaseAddress().GetLoadAddress(target);
1141 if (address != LLDB_INVALID_ADDRESS) {
1142 if (fun_addr_range.ContainsLoadAddress(address, target))
1143 address_list.push_back(address);
1144 else
1145 all_in_function = false;
1146 }
1147 start_idx_ptr++;
1148 }
1149 }
1150
1151 for (lldb::addr_t address : m_options.m_until_addrs) {
1152 if (fun_addr_range.ContainsLoadAddress(address, target))
1153 address_list.push_back(address);
1154 else
1155 all_in_function = false;
1156 }
1157
1158 if (address_list.empty()) {
1159 if (all_in_function)
1160 result.AppendErrorWithFormat(
1161 "No line entries matching until target.\n");
1162 else
1163 result.AppendErrorWithFormat(
1164 "Until target outside of the current function.\n");
1165
1166 result.SetStatus(eReturnStatusFailed);
1167 return false;
1168 }
1169
1170 new_plan_sp = thread->QueueThreadPlanForStepUntil(
1171 abort_other_plans, &address_list.front(), address_list.size(),
1172 m_options.m_stop_others, m_options.m_frame_idx);
1173 // User level plans should be master plans so they can be interrupted
1174 // (e.g. by hitting a breakpoint)
1175 // and other plans executed by the user (stepping around the breakpoint)
1176 // and then a "continue"
1177 // will resume the original plan.
1178 new_plan_sp->SetIsMasterPlan(true);
1179 new_plan_sp->SetOkayToDiscard(false);
1180 } else {
1181 result.AppendErrorWithFormat(
1182 "Frame index %u of thread %u has no debug information.\n",
1183 m_options.m_frame_idx, m_options.m_thread_idx);
1184 result.SetStatus(eReturnStatusFailed);
1185 return false;
1186 }
1187
1188 process->GetThreadList().SetSelectedThreadByID(m_options.m_thread_idx);
1189
1190 StreamString stream;
1191 Error error;
1192 if (synchronous_execution)
1193 error = process->ResumeSynchronous(&stream);
1194 else
1195 error = process->Resume();
1196
1197 if (error.Success()) {
1198 result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
1199 process->GetID());
1200 if (synchronous_execution) {
1201 // If any state changed events had anything to say, add that to the
1202 // result
1203 if (stream.GetData())
1204 result.AppendMessage(stream.GetData());
1205
1206 result.SetDidChangeProcessState(true);
1207 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1208 } else {
1209 result.SetStatus(eReturnStatusSuccessContinuingNoResult);
1210 }
1211 } else {
1212 result.AppendErrorWithFormat("Failed to resume process: %s.\n",
1213 error.AsCString());
1214 result.SetStatus(eReturnStatusFailed);
1215 }
1216 }
1217 return result.Succeeded();
1218 }
1219
1220 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001221};
1222
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001223//-------------------------------------------------------------------------
1224// CommandObjectThreadSelect
1225//-------------------------------------------------------------------------
1226
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227class CommandObjectThreadSelect : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001228public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001229 CommandObjectThreadSelect(CommandInterpreter &interpreter)
1230 : CommandObjectParsed(interpreter, "thread select",
1231 "Change the currently selected thread.", nullptr,
1232 eCommandRequiresProcess | eCommandTryTargetAPILock |
1233 eCommandProcessMustBeLaunched |
1234 eCommandProcessMustBePaused) {
1235 CommandArgumentEntry arg;
1236 CommandArgumentData thread_idx_arg;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238 // Define the first (and only) variant of this arg.
1239 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1240 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1241
1242 // There is only one variant this argument could be; put it into the
1243 // argument entry.
1244 arg.push_back(thread_idx_arg);
1245
1246 // Push the data for the first argument into the m_arguments vector.
1247 m_arguments.push_back(arg);
1248 }
1249
1250 ~CommandObjectThreadSelect() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001251
Jim Ingham5a988412012-06-08 21:56:10 +00001252protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001253 bool DoExecute(Args &command, CommandReturnObject &result) override {
1254 Process *process = m_exe_ctx.GetProcessPtr();
1255 if (process == nullptr) {
1256 result.AppendError("no process");
1257 result.SetStatus(eReturnStatusFailed);
1258 return false;
1259 } else if (command.GetArgumentCount() != 1) {
1260 result.AppendErrorWithFormat(
1261 "'%s' takes exactly one thread index argument:\nUsage: %s\n",
1262 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1263 result.SetStatus(eReturnStatusFailed);
1264 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001266
1267 uint32_t index_id =
1268 StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1269
1270 Thread *new_thread =
1271 process->GetThreadList().FindThreadByIndexID(index_id).get();
1272 if (new_thread == nullptr) {
1273 result.AppendErrorWithFormat("invalid thread #%s.\n",
1274 command.GetArgumentAtIndex(0));
1275 result.SetStatus(eReturnStatusFailed);
1276 return false;
1277 }
1278
1279 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1280 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1281
1282 return result.Succeeded();
1283 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001284};
1285
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001286//-------------------------------------------------------------------------
1287// CommandObjectThreadList
1288//-------------------------------------------------------------------------
1289
Kate Stoneb9c1b512016-09-06 20:57:50 +00001290class CommandObjectThreadList : public CommandObjectParsed {
Greg Clayton66111032010-06-23 01:19:29 +00001291public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001292 CommandObjectThreadList(CommandInterpreter &interpreter)
1293 : CommandObjectParsed(
1294 interpreter, "thread list",
1295 "Show a summary of each thread in the current target process.",
1296 "thread list",
1297 eCommandRequiresProcess | eCommandTryTargetAPILock |
1298 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001299
Kate Stoneb9c1b512016-09-06 20:57:50 +00001300 ~CommandObjectThreadList() override = default;
Greg Clayton66111032010-06-23 01:19:29 +00001301
Jim Ingham5a988412012-06-08 21:56:10 +00001302protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001303 bool DoExecute(Args &command, CommandReturnObject &result) override {
1304 Stream &strm = result.GetOutputStream();
1305 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1306 Process *process = m_exe_ctx.GetProcessPtr();
1307 const bool only_threads_with_stop_reason = false;
1308 const uint32_t start_frame = 0;
1309 const uint32_t num_frames = 0;
1310 const uint32_t num_frames_with_source = 0;
1311 process->GetStatus(strm);
1312 process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
Jim Ingham6a9767c2016-11-08 20:36:40 +00001313 num_frames, num_frames_with_source, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001314 return result.Succeeded();
1315 }
Greg Clayton66111032010-06-23 01:19:29 +00001316};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317
Jim Ingham93208b82013-01-31 21:46:01 +00001318//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001319// CommandObjectThreadInfo
1320//-------------------------------------------------------------------------
1321
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001322static OptionDefinition g_thread_info_options[] = {
1323 // clang-format off
1324 { LLDB_OPT_SET_ALL, false, "json", 'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format." },
1325 { LLDB_OPT_SET_ALL, false, "stop-info", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format." }
1326 // clang-format on
1327};
1328
Kate Stoneb9c1b512016-09-06 20:57:50 +00001329class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
Jason Molenda705b1802014-06-13 02:37:02 +00001330public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001331 class CommandOptions : public Options {
1332 public:
1333 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Jason Molenda705b1802014-06-13 02:37:02 +00001334
Kate Stoneb9c1b512016-09-06 20:57:50 +00001335 ~CommandOptions() override = default;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001336
Kate Stoneb9c1b512016-09-06 20:57:50 +00001337 void OptionParsingStarting(ExecutionContext *execution_context) override {
1338 m_json_thread = false;
1339 m_json_stopinfo = false;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001340 }
1341
Kate Stoneb9c1b512016-09-06 20:57:50 +00001342 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
1343 ExecutionContext *execution_context) override {
1344 const int short_option = m_getopt_table[option_idx].val;
1345 Error error;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001346
Kate Stoneb9c1b512016-09-06 20:57:50 +00001347 switch (short_option) {
1348 case 'j':
1349 m_json_thread = true;
1350 break;
1351
1352 case 's':
1353 m_json_stopinfo = true;
1354 break;
1355
1356 default:
1357 return Error("invalid short option character '%c'", short_option);
1358 }
1359 return error;
Jason Molenda705b1802014-06-13 02:37:02 +00001360 }
1361
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001362 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00001363 return llvm::makeArrayRef(g_thread_info_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001364 }
Stephane Sezerf8104912016-03-17 18:52:41 +00001365
Kate Stoneb9c1b512016-09-06 20:57:50 +00001366 bool m_json_thread;
1367 bool m_json_stopinfo;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001368 };
1369
1370 CommandObjectThreadInfo(CommandInterpreter &interpreter)
1371 : CommandObjectIterateOverThreads(
1372 interpreter, "thread info", "Show an extended summary of one or "
1373 "more threads. Defaults to the "
1374 "current thread.",
1375 "thread info",
1376 eCommandRequiresProcess | eCommandTryTargetAPILock |
1377 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
1378 m_options() {
1379 m_add_return = false;
1380 }
1381
1382 ~CommandObjectThreadInfo() override = default;
1383
1384 Options *GetOptions() override { return &m_options; }
1385
1386 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1387 ThreadSP thread_sp =
1388 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1389 if (!thread_sp) {
1390 result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1391 tid);
1392 result.SetStatus(eReturnStatusFailed);
1393 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001394 }
1395
Kate Stoneb9c1b512016-09-06 20:57:50 +00001396 Thread *thread = thread_sp.get();
1397
1398 Stream &strm = result.GetOutputStream();
1399 if (!thread->GetDescription(strm, eDescriptionLevelFull,
1400 m_options.m_json_thread,
1401 m_options.m_json_stopinfo)) {
1402 result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1403 thread->GetIndexID());
1404 result.SetStatus(eReturnStatusFailed);
1405 return false;
1406 }
1407 return true;
1408 }
1409
1410 CommandOptions m_options;
Jason Molenda705b1802014-06-13 02:37:02 +00001411};
1412
Jason Molenda705b1802014-06-13 02:37:02 +00001413//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001414// CommandObjectThreadReturn
1415//-------------------------------------------------------------------------
1416
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001417static OptionDefinition g_thread_return_options[] = {
1418 // clang-format off
1419 { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation." }
1420 // clang-format on
1421};
1422
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423class CommandObjectThreadReturn : public CommandObjectRaw {
Jim Inghamcb640dd2012-09-14 02:14:15 +00001424public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001425 class CommandOptions : public Options {
1426 public:
1427 CommandOptions() : Options(), m_from_expression(false) {
1428 // Keep default values of all options in one place: OptionParsingStarting
1429 // ()
1430 OptionParsingStarting(nullptr);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001431 }
Jim Inghamcb640dd2012-09-14 02:14:15 +00001432
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433 ~CommandOptions() override = default;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001434
Kate Stoneb9c1b512016-09-06 20:57:50 +00001435 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
1436 ExecutionContext *execution_context) override {
1437 Error error;
1438 const int short_option = m_getopt_table[option_idx].val;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +00001439 auto option_strref = llvm::StringRef::withNullAsEmpty(option_arg);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001440
1441 switch (short_option) {
1442 case 'x': {
1443 bool success;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +00001444 bool tmp_value = Args::StringToBoolean(option_strref, false, &success);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001445 if (success)
1446 m_from_expression = tmp_value;
1447 else {
1448 error.SetErrorStringWithFormat(
1449 "invalid boolean value '%s' for 'x' option", option_arg);
1450 }
1451 } break;
1452 default:
1453 error.SetErrorStringWithFormat("invalid short option character '%c'",
1454 short_option);
1455 break;
1456 }
1457 return error;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001458 }
1459
Kate Stoneb9c1b512016-09-06 20:57:50 +00001460 void OptionParsingStarting(ExecutionContext *execution_context) override {
1461 m_from_expression = false;
1462 }
1463
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001464 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00001465 return llvm::makeArrayRef(g_thread_return_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001466 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001467
1468 bool m_from_expression;
1469
Kate Stoneb9c1b512016-09-06 20:57:50 +00001470 // Instance variables to hold the values for command options.
1471 };
1472
1473 CommandObjectThreadReturn(CommandInterpreter &interpreter)
1474 : CommandObjectRaw(interpreter, "thread return",
1475 "Prematurely return from a stack frame, "
1476 "short-circuiting execution of newer frames "
1477 "and optionally yielding a specified value. Defaults "
1478 "to the exiting the current stack "
1479 "frame.",
1480 "thread return",
1481 eCommandRequiresFrame | eCommandTryTargetAPILock |
1482 eCommandProcessMustBeLaunched |
1483 eCommandProcessMustBePaused),
1484 m_options() {
1485 CommandArgumentEntry arg;
1486 CommandArgumentData expression_arg;
1487
1488 // Define the first (and only) variant of this arg.
1489 expression_arg.arg_type = eArgTypeExpression;
1490 expression_arg.arg_repetition = eArgRepeatOptional;
1491
1492 // There is only one variant this argument could be; put it into the
1493 // argument entry.
1494 arg.push_back(expression_arg);
1495
1496 // Push the data for the first argument into the m_arguments vector.
1497 m_arguments.push_back(arg);
1498 }
1499
1500 ~CommandObjectThreadReturn() override = default;
1501
1502 Options *GetOptions() override { return &m_options; }
1503
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001504protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001505 bool DoExecute(const char *command, CommandReturnObject &result) override {
1506 // I am going to handle this by hand, because I don't want you to have to
1507 // say:
1508 // "thread return -- -5".
1509 if (command[0] == '-' && command[1] == 'x') {
1510 if (command && command[2] != '\0')
1511 result.AppendWarning("Return values ignored when returning from user "
1512 "called expressions");
Jim Inghamcb640dd2012-09-14 02:14:15 +00001513
Kate Stoneb9c1b512016-09-06 20:57:50 +00001514 Thread *thread = m_exe_ctx.GetThreadPtr();
1515 Error error;
1516 error = thread->UnwindInnermostExpression();
1517 if (!error.Success()) {
1518 result.AppendErrorWithFormat("Unwinding expression failed - %s.",
1519 error.AsCString());
1520 result.SetStatus(eReturnStatusFailed);
1521 } else {
1522 bool success =
1523 thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream());
1524 if (success) {
1525 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame());
1526 result.SetStatus(eReturnStatusSuccessFinishResult);
1527 } else {
1528 result.AppendErrorWithFormat(
1529 "Could not select 0th frame after unwinding expression.");
1530 result.SetStatus(eReturnStatusFailed);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001531 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001532 }
1533 return result.Succeeded();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001534 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001535
1536 ValueObjectSP return_valobj_sp;
1537
1538 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1539 uint32_t frame_idx = frame_sp->GetFrameIndex();
1540
1541 if (frame_sp->IsInlined()) {
1542 result.AppendError("Don't know how to return from inlined frames.");
1543 result.SetStatus(eReturnStatusFailed);
1544 return false;
1545 }
1546
1547 if (command && command[0] != '\0') {
1548 Target *target = m_exe_ctx.GetTargetPtr();
1549 EvaluateExpressionOptions options;
1550
1551 options.SetUnwindOnError(true);
1552 options.SetUseDynamic(eNoDynamicValues);
1553
1554 ExpressionResults exe_results = eExpressionSetupError;
1555 exe_results = target->EvaluateExpression(command, frame_sp.get(),
1556 return_valobj_sp, options);
1557 if (exe_results != eExpressionCompleted) {
1558 if (return_valobj_sp)
1559 result.AppendErrorWithFormat(
1560 "Error evaluating result expression: %s",
1561 return_valobj_sp->GetError().AsCString());
1562 else
1563 result.AppendErrorWithFormat(
1564 "Unknown error evaluating result expression.");
1565 result.SetStatus(eReturnStatusFailed);
1566 return false;
1567 }
1568 }
1569
1570 Error error;
1571 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1572 const bool broadcast = true;
1573 error = thread_sp->ReturnFromFrame(frame_sp, return_valobj_sp, broadcast);
1574 if (!error.Success()) {
1575 result.AppendErrorWithFormat(
1576 "Error returning from frame %d of thread %d: %s.", frame_idx,
1577 thread_sp->GetIndexID(), error.AsCString());
1578 result.SetStatus(eReturnStatusFailed);
1579 return false;
1580 }
1581
1582 result.SetStatus(eReturnStatusSuccessFinishResult);
1583 return true;
1584 }
1585
1586 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001587};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001588
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001589//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001590// CommandObjectThreadJump
1591//-------------------------------------------------------------------------
1592
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001593static OptionDefinition g_thread_jump_options[] = {
1594 // clang-format off
1595 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file to jump to." },
1596 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number to jump to." },
1597 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Jumps by a relative line offset from the current line." },
1598 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Jumps to a specific address." },
1599 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allows the PC to leave the current function." }
1600 // clang-format on
1601};
1602
Kate Stoneb9c1b512016-09-06 20:57:50 +00001603class CommandObjectThreadJump : public CommandObjectParsed {
Richard Mittonf86248d2013-09-12 02:20:34 +00001604public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001605 class CommandOptions : public Options {
1606 public:
1607 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Richard Mittonf86248d2013-09-12 02:20:34 +00001608
Kate Stoneb9c1b512016-09-06 20:57:50 +00001609 ~CommandOptions() override = default;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001610
Kate Stoneb9c1b512016-09-06 20:57:50 +00001611 void OptionParsingStarting(ExecutionContext *execution_context) override {
1612 m_filenames.Clear();
1613 m_line_num = 0;
1614 m_line_offset = 0;
1615 m_load_addr = LLDB_INVALID_ADDRESS;
1616 m_force = false;
Richard Mittonf86248d2013-09-12 02:20:34 +00001617 }
1618
Kate Stoneb9c1b512016-09-06 20:57:50 +00001619 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
1620 ExecutionContext *execution_context) override {
1621 bool success;
1622 const int short_option = m_getopt_table[option_idx].val;
1623 Error error;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001624
Kate Stoneb9c1b512016-09-06 20:57:50 +00001625 switch (short_option) {
1626 case 'f':
1627 m_filenames.AppendIfUnique(FileSpec(option_arg, false));
1628 if (m_filenames.GetSize() > 1)
1629 return Error("only one source file expected.");
1630 break;
1631 case 'l':
1632 m_line_num = StringConvert::ToUInt32(option_arg, 0, 0, &success);
1633 if (!success || m_line_num == 0)
1634 return Error("invalid line number: '%s'.", option_arg);
1635 break;
1636 case 'b':
1637 m_line_offset = StringConvert::ToSInt32(option_arg, 0, 0, &success);
1638 if (!success)
1639 return Error("invalid line offset: '%s'.", option_arg);
1640 break;
1641 case 'a':
1642 m_load_addr = Args::StringToAddress(execution_context, option_arg,
1643 LLDB_INVALID_ADDRESS, &error);
1644 break;
1645 case 'r':
1646 m_force = true;
1647 break;
1648 default:
1649 return Error("invalid short option character '%c'", short_option);
1650 }
1651 return error;
Richard Mittonf86248d2013-09-12 02:20:34 +00001652 }
1653
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001654 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00001655 return llvm::makeArrayRef(g_thread_jump_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001656 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001657
1658 FileSpecList m_filenames;
1659 uint32_t m_line_num;
1660 int32_t m_line_offset;
1661 lldb::addr_t m_load_addr;
1662 bool m_force;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001663 };
1664
1665 CommandObjectThreadJump(CommandInterpreter &interpreter)
1666 : CommandObjectParsed(
1667 interpreter, "thread jump",
1668 "Sets the program counter to a new address.", "thread jump",
1669 eCommandRequiresFrame | eCommandTryTargetAPILock |
1670 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
1671 m_options() {}
1672
1673 ~CommandObjectThreadJump() override = default;
1674
1675 Options *GetOptions() override { return &m_options; }
1676
Richard Mittonf86248d2013-09-12 02:20:34 +00001677protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001678 bool DoExecute(Args &args, CommandReturnObject &result) override {
1679 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1680 StackFrame *frame = m_exe_ctx.GetFramePtr();
1681 Thread *thread = m_exe_ctx.GetThreadPtr();
1682 Target *target = m_exe_ctx.GetTargetPtr();
1683 const SymbolContext &sym_ctx =
1684 frame->GetSymbolContext(eSymbolContextLineEntry);
Richard Mittonf86248d2013-09-12 02:20:34 +00001685
Kate Stoneb9c1b512016-09-06 20:57:50 +00001686 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) {
1687 // Use this address directly.
1688 Address dest = Address(m_options.m_load_addr);
Richard Mittonf86248d2013-09-12 02:20:34 +00001689
Kate Stoneb9c1b512016-09-06 20:57:50 +00001690 lldb::addr_t callAddr = dest.GetCallableLoadAddress(target);
1691 if (callAddr == LLDB_INVALID_ADDRESS) {
1692 result.AppendErrorWithFormat("Invalid destination address.");
1693 result.SetStatus(eReturnStatusFailed);
1694 return false;
1695 }
Richard Mittonf86248d2013-09-12 02:20:34 +00001696
Kate Stoneb9c1b512016-09-06 20:57:50 +00001697 if (!reg_ctx->SetPC(callAddr)) {
1698 result.AppendErrorWithFormat("Error changing PC value for thread %d.",
1699 thread->GetIndexID());
1700 result.SetStatus(eReturnStatusFailed);
1701 return false;
1702 }
1703 } else {
1704 // Pick either the absolute line, or work out a relative one.
1705 int32_t line = (int32_t)m_options.m_line_num;
1706 if (line == 0)
1707 line = sym_ctx.line_entry.line + m_options.m_line_offset;
Richard Mittonf86248d2013-09-12 02:20:34 +00001708
Kate Stoneb9c1b512016-09-06 20:57:50 +00001709 // Try the current file, but override if asked.
1710 FileSpec file = sym_ctx.line_entry.file;
1711 if (m_options.m_filenames.GetSize() == 1)
1712 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Richard Mittonf86248d2013-09-12 02:20:34 +00001713
Kate Stoneb9c1b512016-09-06 20:57:50 +00001714 if (!file) {
1715 result.AppendErrorWithFormat(
1716 "No source file available for the current location.");
1717 result.SetStatus(eReturnStatusFailed);
1718 return false;
1719 }
Richard Mittonf86248d2013-09-12 02:20:34 +00001720
Kate Stoneb9c1b512016-09-06 20:57:50 +00001721 std::string warnings;
1722 Error err = thread->JumpToLine(file, line, m_options.m_force, &warnings);
Richard Mittonf86248d2013-09-12 02:20:34 +00001723
Kate Stoneb9c1b512016-09-06 20:57:50 +00001724 if (err.Fail()) {
1725 result.SetError(err);
1726 return false;
1727 }
Richard Mittonf86248d2013-09-12 02:20:34 +00001728
Kate Stoneb9c1b512016-09-06 20:57:50 +00001729 if (!warnings.empty())
1730 result.AppendWarning(warnings.c_str());
Richard Mittonf86248d2013-09-12 02:20:34 +00001731 }
1732
Kate Stoneb9c1b512016-09-06 20:57:50 +00001733 result.SetStatus(eReturnStatusSuccessFinishResult);
1734 return true;
1735 }
1736
1737 CommandOptions m_options;
Richard Mittonf86248d2013-09-12 02:20:34 +00001738};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001739
Richard Mittonf86248d2013-09-12 02:20:34 +00001740//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001741// Next are the subcommands of CommandObjectMultiwordThreadPlan
1742//-------------------------------------------------------------------------
1743
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001744//-------------------------------------------------------------------------
1745// CommandObjectThreadPlanList
1746//-------------------------------------------------------------------------
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001747
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001748static OptionDefinition g_thread_plan_list_options[] = {
1749 // clang-format off
1750 { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans" },
1751 { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans" }
1752 // clang-format on
1753};
1754
Kate Stoneb9c1b512016-09-06 20:57:50 +00001755class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001756public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001757 class CommandOptions : public Options {
1758 public:
1759 CommandOptions() : Options() {
1760 // Keep default values of all options in one place: OptionParsingStarting
1761 // ()
1762 OptionParsingStarting(nullptr);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001763 }
1764
Kate Stoneb9c1b512016-09-06 20:57:50 +00001765 ~CommandOptions() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001766
Kate Stoneb9c1b512016-09-06 20:57:50 +00001767 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
1768 ExecutionContext *execution_context) override {
1769 Error error;
1770 const int short_option = m_getopt_table[option_idx].val;
1771
1772 switch (short_option) {
1773 case 'i':
1774 m_internal = true;
1775 break;
1776 case 'v':
1777 m_verbose = true;
1778 break;
1779 default:
1780 error.SetErrorStringWithFormat("invalid short option character '%c'",
1781 short_option);
1782 break;
1783 }
1784 return error;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001785 }
1786
Kate Stoneb9c1b512016-09-06 20:57:50 +00001787 void OptionParsingStarting(ExecutionContext *execution_context) override {
1788 m_verbose = false;
1789 m_internal = false;
1790 }
1791
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001792 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00001793 return llvm::makeArrayRef(g_thread_plan_list_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001794 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001795
1796 // Instance variables to hold the values for command options.
1797 bool m_verbose;
1798 bool m_internal;
1799 };
1800
1801 CommandObjectThreadPlanList(CommandInterpreter &interpreter)
1802 : CommandObjectIterateOverThreads(
1803 interpreter, "thread plan list",
1804 "Show thread plans for one or more threads. If no threads are "
1805 "specified, show the "
1806 "current thread. Use the thread-index \"all\" to see all threads.",
1807 nullptr,
1808 eCommandRequiresProcess | eCommandRequiresThread |
1809 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
1810 eCommandProcessMustBePaused),
1811 m_options() {}
1812
1813 ~CommandObjectThreadPlanList() override = default;
1814
1815 Options *GetOptions() override { return &m_options; }
1816
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001817protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001818 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1819 ThreadSP thread_sp =
1820 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1821 if (!thread_sp) {
1822 result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1823 tid);
1824 result.SetStatus(eReturnStatusFailed);
1825 return false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001826 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001827
Kate Stoneb9c1b512016-09-06 20:57:50 +00001828 Thread *thread = thread_sp.get();
1829
1830 Stream &strm = result.GetOutputStream();
1831 DescriptionLevel desc_level = eDescriptionLevelFull;
1832 if (m_options.m_verbose)
1833 desc_level = eDescriptionLevelVerbose;
1834
1835 thread->DumpThreadPlans(&strm, desc_level, m_options.m_internal, true);
1836 return true;
1837 }
1838
1839 CommandOptions m_options;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001840};
1841
Kate Stoneb9c1b512016-09-06 20:57:50 +00001842class CommandObjectThreadPlanDiscard : public CommandObjectParsed {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001843public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001844 CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
1845 : CommandObjectParsed(interpreter, "thread plan discard",
1846 "Discards thread plans up to and including the "
1847 "specified index (see 'thread plan list'.) "
1848 "Only user visible plans can be discarded.",
1849 nullptr,
1850 eCommandRequiresProcess | eCommandRequiresThread |
1851 eCommandTryTargetAPILock |
1852 eCommandProcessMustBeLaunched |
1853 eCommandProcessMustBePaused) {
1854 CommandArgumentEntry arg;
1855 CommandArgumentData plan_index_arg;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001856
Kate Stoneb9c1b512016-09-06 20:57:50 +00001857 // Define the first (and only) variant of this arg.
1858 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
1859 plan_index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001860
Kate Stoneb9c1b512016-09-06 20:57:50 +00001861 // There is only one variant this argument could be; put it into the
1862 // argument entry.
1863 arg.push_back(plan_index_arg);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001864
Kate Stoneb9c1b512016-09-06 20:57:50 +00001865 // Push the data for the first argument into the m_arguments vector.
1866 m_arguments.push_back(arg);
1867 }
1868
1869 ~CommandObjectThreadPlanDiscard() override = default;
1870
1871 bool DoExecute(Args &args, CommandReturnObject &result) override {
1872 Thread *thread = m_exe_ctx.GetThreadPtr();
1873 if (args.GetArgumentCount() != 1) {
1874 result.AppendErrorWithFormat("Too many arguments, expected one - the "
1875 "thread plan index - but got %zu.",
1876 args.GetArgumentCount());
1877 result.SetStatus(eReturnStatusFailed);
1878 return false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001879 }
1880
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881 bool success;
1882 uint32_t thread_plan_idx =
1883 StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
1884 if (!success) {
1885 result.AppendErrorWithFormat(
1886 "Invalid thread index: \"%s\" - should be unsigned int.",
1887 args.GetArgumentAtIndex(0));
1888 result.SetStatus(eReturnStatusFailed);
1889 return false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001890 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001891
1892 if (thread_plan_idx == 0) {
1893 result.AppendErrorWithFormat(
1894 "You wouldn't really want me to discard the base thread plan.");
1895 result.SetStatus(eReturnStatusFailed);
1896 return false;
1897 }
1898
1899 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) {
1900 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1901 return true;
1902 } else {
1903 result.AppendErrorWithFormat(
1904 "Could not find User thread plan with index %s.",
1905 args.GetArgumentAtIndex(0));
1906 result.SetStatus(eReturnStatusFailed);
1907 return false;
1908 }
1909 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001910};
1911
1912//-------------------------------------------------------------------------
1913// CommandObjectMultiwordThreadPlan
1914//-------------------------------------------------------------------------
1915
Kate Stoneb9c1b512016-09-06 20:57:50 +00001916class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001917public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001918 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
1919 : CommandObjectMultiword(
1920 interpreter, "plan",
1921 "Commands for managing thread plans that control execution.",
1922 "thread plan <subcommand> [<subcommand objects]") {
1923 LoadSubCommand(
1924 "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter)));
1925 LoadSubCommand(
1926 "discard",
1927 CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter)));
1928 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001929
Kate Stoneb9c1b512016-09-06 20:57:50 +00001930 ~CommandObjectMultiwordThreadPlan() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001931};
1932
1933//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001934// CommandObjectMultiwordThread
1935//-------------------------------------------------------------------------
1936
Kate Stoneb9c1b512016-09-06 20:57:50 +00001937CommandObjectMultiwordThread::CommandObjectMultiwordThread(
1938 CommandInterpreter &interpreter)
1939 : CommandObjectMultiword(interpreter, "thread", "Commands for operating on "
1940 "one or more threads in "
1941 "the current process.",
1942 "thread <subcommand> [<subcommand-options>]") {
1943 LoadSubCommand("backtrace", CommandObjectSP(new CommandObjectThreadBacktrace(
1944 interpreter)));
1945 LoadSubCommand("continue",
1946 CommandObjectSP(new CommandObjectThreadContinue(interpreter)));
1947 LoadSubCommand("list",
1948 CommandObjectSP(new CommandObjectThreadList(interpreter)));
1949 LoadSubCommand("return",
1950 CommandObjectSP(new CommandObjectThreadReturn(interpreter)));
1951 LoadSubCommand("jump",
1952 CommandObjectSP(new CommandObjectThreadJump(interpreter)));
1953 LoadSubCommand("select",
1954 CommandObjectSP(new CommandObjectThreadSelect(interpreter)));
1955 LoadSubCommand("until",
1956 CommandObjectSP(new CommandObjectThreadUntil(interpreter)));
1957 LoadSubCommand("info",
1958 CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
1959 LoadSubCommand("step-in",
1960 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
1961 interpreter, "thread step-in",
1962 "Source level single step, stepping into calls. Defaults "
1963 "to current thread unless specified.",
1964 nullptr, eStepTypeInto, eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001965
Kate Stoneb9c1b512016-09-06 20:57:50 +00001966 LoadSubCommand("step-out",
1967 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
1968 interpreter, "thread step-out",
1969 "Finish executing the current stack frame and stop after "
1970 "returning. Defaults to current thread unless specified.",
1971 nullptr, eStepTypeOut, eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001972
Kate Stoneb9c1b512016-09-06 20:57:50 +00001973 LoadSubCommand("step-over",
1974 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
1975 interpreter, "thread step-over",
1976 "Source level single step, stepping over calls. Defaults "
1977 "to current thread unless specified.",
1978 nullptr, eStepTypeOver, eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00001979
Kate Stoneb9c1b512016-09-06 20:57:50 +00001980 LoadSubCommand("step-inst",
1981 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
1982 interpreter, "thread step-inst",
1983 "Instruction level single step, stepping into calls. "
1984 "Defaults to current thread unless specified.",
1985 nullptr, eStepTypeTrace, eStepScopeInstruction)));
Kate Stone7428a182016-07-14 22:03:10 +00001986
Kate Stoneb9c1b512016-09-06 20:57:50 +00001987 LoadSubCommand("step-inst-over",
1988 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
1989 interpreter, "thread step-inst-over",
1990 "Instruction level single step, stepping over calls. "
1991 "Defaults to current thread unless specified.",
1992 nullptr, eStepTypeTraceOver, eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001993
Kate Stoneb9c1b512016-09-06 20:57:50 +00001994 LoadSubCommand(
1995 "step-scripted",
1996 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
1997 interpreter, "thread step-scripted",
1998 "Step as instructed by the script class passed in the -C option.",
1999 nullptr, eStepTypeScripted, eStepScopeSource)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002000
Kate Stoneb9c1b512016-09-06 20:57:50 +00002001 LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
2002 interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002003}
2004
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002005CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;