blob: 86c99b5e6d9452c01233dcd384dc1c0900ea8289 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectThread.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Inghamcb640dd2012-09-14 02:14:15 +000018#include "lldb/lldb-private.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/State.h"
20#include "lldb/Core/SourceManager.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000021#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#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"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Process.h"
30#include "lldb/Target/RegisterContext.h"
Jason Molenda750ea692013-11-12 07:02:07 +000031#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
34#include "lldb/Target/ThreadPlan.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"
38#include "lldb/Target/ThreadPlanStepInRange.h"
Greg Clayton1f746072012-08-29 21:13:06 +000039
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040
41using namespace lldb;
42using namespace lldb_private;
43
44
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045//-------------------------------------------------------------------------
46// CommandObjectThreadBacktrace
47//-------------------------------------------------------------------------
48
Jim Ingham5a988412012-06-08 21:56:10 +000049class CommandObjectThreadBacktrace : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050{
51public:
52
Jim Inghame2e0b452010-08-26 23:36:03 +000053 class CommandOptions : public Options
54 {
55 public:
56
Greg Claytoneb0103f2011-04-07 22:46:35 +000057 CommandOptions (CommandInterpreter &interpreter) :
58 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +000059 {
Greg Claytonf6b8b582011-04-13 00:18:08 +000060 // Keep default values of all options in one place: OptionParsingStarting ()
61 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +000062 }
63
64 virtual
65 ~CommandOptions ()
66 {
67 }
68
69 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +000070 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame2e0b452010-08-26 23:36:03 +000071 {
72 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000073 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame2e0b452010-08-26 23:36:03 +000074
75 switch (short_option)
76 {
77 case 'c':
78 {
79 bool success;
80 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
81 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000082 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +000083 if (input_count < -1)
84 m_count = UINT32_MAX;
85 else
86 m_count = input_count;
87 }
88 break;
89 case 's':
90 {
91 bool success;
92 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
93 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000094 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +000095 }
Jason Molenda750ea692013-11-12 07:02:07 +000096 case 'e':
97 {
98 bool success;
99 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
100 if (!success)
101 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
102 }
Jim Inghame2e0b452010-08-26 23:36:03 +0000103 break;
104 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000105 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000106 break;
107
108 }
109 return error;
110 }
111
112 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000113 OptionParsingStarting ()
Jim Inghame2e0b452010-08-26 23:36:03 +0000114 {
Greg Clayton7260f622011-04-18 08:33:37 +0000115 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000116 m_start = 0;
Jason Molenda750ea692013-11-12 07:02:07 +0000117 m_extended_backtrace = false;
Jim Inghame2e0b452010-08-26 23:36:03 +0000118 }
119
Greg Claytone0d378b2011-03-24 21:19:54 +0000120 const OptionDefinition*
Jim Inghame2e0b452010-08-26 23:36:03 +0000121 GetDefinitions ()
122 {
123 return g_option_table;
124 }
125
126 // Options table: Required for subclasses of Options.
127
Greg Claytone0d378b2011-03-24 21:19:54 +0000128 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000129
130 // Instance variables to hold the values for command options.
131 uint32_t m_count;
132 uint32_t m_start;
Jason Molenda750ea692013-11-12 07:02:07 +0000133 bool m_extended_backtrace;
Jim Inghame2e0b452010-08-26 23:36:03 +0000134 };
135
Greg Claytona7015092010-09-18 01:14:36 +0000136 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000137 CommandObjectParsed (interpreter,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000138 "thread backtrace",
139 "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.",
140 NULL,
141 eFlagRequiresProcess |
142 eFlagRequiresThread |
143 eFlagTryTargetAPILock |
144 eFlagProcessMustBeLaunched |
145 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000146 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 {
Caroline Tice405fe672010-10-04 22:28:36 +0000148 CommandArgumentEntry arg;
149 CommandArgumentData thread_idx_arg;
150
151 // Define the first (and only) variant of this arg.
152 thread_idx_arg.arg_type = eArgTypeThreadIndex;
153 thread_idx_arg.arg_repetition = eArgRepeatStar;
154
155 // There is only one variant this argument could be; put it into the argument entry.
156 arg.push_back (thread_idx_arg);
157
158 // Push the data for the first argument into the m_arguments vector.
159 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 }
161
162 ~CommandObjectThreadBacktrace()
163 {
164 }
165
Jim Inghame2e0b452010-08-26 23:36:03 +0000166 virtual Options *
167 GetOptions ()
168 {
169 return &m_options;
170 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171
Jim Ingham5a988412012-06-08 21:56:10 +0000172protected:
Jason Molenda750ea692013-11-12 07:02:07 +0000173 void
174 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
175 {
176 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
177 if (runtime)
178 {
179 Stream &strm = result.GetOutputStream();
180 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
181 for (auto type : types)
182 {
Jason Molenda008c45f2013-11-12 23:33:32 +0000183 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
Jason Molenda750ea692013-11-12 07:02:07 +0000184 if (ext_thread_sp && ext_thread_sp->IsValid ())
185 {
186 const uint32_t num_frames_with_source = 0;
187 if (ext_thread_sp->GetStatus (strm,
188 m_options.m_start,
189 m_options.m_count,
190 num_frames_with_source))
191 {
192 DoExtendedBacktrace (ext_thread_sp.get(), result);
193 }
194 }
195 }
196 }
197 }
198
Greg Clayton66111032010-06-23 01:19:29 +0000199 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000200 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton7260f622011-04-18 08:33:37 +0000201 {
Jim Ingham09b263e2010-08-27 00:58:05 +0000202 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton7260f622011-04-18 08:33:37 +0000203 Stream &strm = result.GetOutputStream();
204
205 // Don't show source context when doing backtraces.
206 const uint32_t num_frames_with_source = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207 if (command.GetArgumentCount() == 0)
208 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000209 Thread *thread = m_exe_ctx.GetThreadPtr();
210 // Thread::GetStatus() returns the number of frames shown.
211 if (thread->GetStatus (strm,
212 m_options.m_start,
213 m_options.m_count,
214 num_frames_with_source))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000216 result.SetStatus (eReturnStatusSuccessFinishResult);
Jason Molenda750ea692013-11-12 07:02:07 +0000217 if (m_options.m_extended_backtrace)
218 {
219 DoExtendedBacktrace (thread, result);
220 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221 }
222 }
Jim Ingham09b263e2010-08-27 00:58:05 +0000223 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
224 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000225 Process *process = m_exe_ctx.GetProcessPtr();
Sean Callanan5c19eac2013-11-06 19:28:40 +0000226 uint32_t idx = 0;
227 for (ThreadSP thread_sp : process->Threads())
Jim Ingham09b263e2010-08-27 00:58:05 +0000228 {
Sean Callanan5c19eac2013-11-06 19:28:40 +0000229 if (idx != 0)
230 result.AppendMessage("");
231
Johnny Chenf2ddc712011-06-01 23:19:52 +0000232 if (!thread_sp->GetStatus (strm,
233 m_options.m_start,
234 m_options.m_count,
235 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000236 {
Sean Callanan5c19eac2013-11-06 19:28:40 +0000237 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", idx);
Jim Ingham09b263e2010-08-27 00:58:05 +0000238 result.SetStatus (eReturnStatusFailed);
239 return false;
240 }
Jason Molenda750ea692013-11-12 07:02:07 +0000241 if (m_options.m_extended_backtrace)
242 {
243 DoExtendedBacktrace (thread_sp.get(), result);
244 }
Jim Ingham5c4df7a2011-07-26 02:39:59 +0000245
Sean Callanan5c19eac2013-11-06 19:28:40 +0000246 ++idx;
Jim Ingham09b263e2010-08-27 00:58:05 +0000247 }
248 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 else
250 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000251 const size_t num_args = command.GetArgumentCount();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000252 Process *process = m_exe_ctx.GetProcessPtr();
Jim Ingham41f2b942012-09-10 20:50:15 +0000253 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Ingham09b263e2010-08-27 00:58:05 +0000254 std::vector<ThreadSP> thread_sps;
255
Greg Claytonc7bece562013-01-25 18:06:21 +0000256 for (size_t i = 0; i < num_args; i++)
Jim Ingham09b263e2010-08-27 00:58:05 +0000257 {
258 bool success;
259
260 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
261 if (!success)
262 {
263 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
264 result.SetStatus (eReturnStatusFailed);
265 return false;
266 }
267
268 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
269
270 if (!thread_sps[i])
271 {
272 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
273 result.SetStatus (eReturnStatusFailed);
274 return false;
275 }
276
277 }
278
279 for (uint32_t i = 0; i < num_args; i++)
280 {
Greg Clayton7260f622011-04-18 08:33:37 +0000281 if (!thread_sps[i]->GetStatus (strm,
282 m_options.m_start,
283 m_options.m_count,
284 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000285 {
286 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
287 result.SetStatus (eReturnStatusFailed);
288 return false;
289 }
Jason Molenda750ea692013-11-12 07:02:07 +0000290 if (m_options.m_extended_backtrace)
291 {
292 DoExtendedBacktrace (thread_sps[i].get(), result);
293 }
Jim Ingham09b263e2010-08-27 00:58:05 +0000294
295 if (i < num_args - 1)
296 result.AppendMessage("");
297 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298 }
299 return result.Succeeded();
300 }
Jim Ingham5a988412012-06-08 21:56:10 +0000301
Jim Inghame2e0b452010-08-26 23:36:03 +0000302 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303};
304
Greg Claytone0d378b2011-03-24 21:19:54 +0000305OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000306CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
307{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000308{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
309{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
310{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
311{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghame2e0b452010-08-26 23:36:03 +0000312};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313
Greg Clayton69b518f2010-07-07 17:07:17 +0000314enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315{
316 eStepScopeSource,
317 eStepScopeInstruction
318};
319
Jim Ingham5a988412012-06-08 21:56:10 +0000320class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321{
322public:
323
324 class CommandOptions : public Options
325 {
326 public:
327
Greg Claytoneb0103f2011-04-07 22:46:35 +0000328 CommandOptions (CommandInterpreter &interpreter) :
329 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000331 // Keep default values of all options in one place: OptionParsingStarting ()
332 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 }
334
335 virtual
336 ~CommandOptions ()
337 {
338 }
339
340 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000341 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 {
343 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000344 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345
346 switch (short_option)
347 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000348 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 {
350 bool success;
Jim Ingham4b4b2472014-03-13 02:47:14 +0000351 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000353 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000354 else
355 {
356 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
357 }
358 }
359 break;
360
361 case 'A':
362 {
363 bool success;
364 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
365 if (!success)
366 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
367 else
368 {
369 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
370 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371 }
372 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000373
Jim Ingham7a88ec92014-07-08 19:28:57 +0000374 case 'c':
375 {
376 m_step_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
377 if (m_step_count == UINT32_MAX)
378 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
379 break;
380 }
381 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000382 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000385 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 }
387 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000388
389 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000390 {
391 m_avoid_regexp.clear();
392 m_avoid_regexp.assign(option_arg);
393 }
394 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000395
Jim Inghamc6276822012-12-12 19:58:40 +0000396 case 't':
397 {
398 m_step_in_target.clear();
399 m_step_in_target.assign(option_arg);
400
401 }
402 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000403 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000404 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000405 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406
407 }
408 return error;
409 }
410
411 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000412 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000414 m_step_in_avoid_no_debug = eLazyBoolCalculate;
415 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 m_run_mode = eOnlyDuringStepping;
Jim Inghama56c8002010-07-10 02:27:39 +0000417 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000418 m_step_in_target.clear();
Jim Ingham7a88ec92014-07-08 19:28:57 +0000419 m_step_count = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420 }
421
Greg Claytone0d378b2011-03-24 21:19:54 +0000422 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423 GetDefinitions ()
424 {
425 return g_option_table;
426 }
427
428 // Options table: Required for subclasses of Options.
429
Greg Claytone0d378b2011-03-24 21:19:54 +0000430 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431
432 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000433 LazyBool m_step_in_avoid_no_debug;
434 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000436 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000437 std::string m_step_in_target;
Jim Ingham7a88ec92014-07-08 19:28:57 +0000438 int32_t m_step_count;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 };
440
Greg Claytona7015092010-09-18 01:14:36 +0000441 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
442 const char *name,
443 const char *help,
444 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000445 StepType step_type,
446 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000447 CommandObjectParsed (interpreter, name, help, syntax,
448 eFlagRequiresProcess |
449 eFlagRequiresThread |
450 eFlagTryTargetAPILock |
451 eFlagProcessMustBeLaunched |
452 eFlagProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 m_step_type (step_type),
454 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000455 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 {
Caroline Tice405fe672010-10-04 22:28:36 +0000457 CommandArgumentEntry arg;
458 CommandArgumentData thread_id_arg;
459
460 // Define the first (and only) variant of this arg.
461 thread_id_arg.arg_type = eArgTypeThreadID;
462 thread_id_arg.arg_repetition = eArgRepeatOptional;
463
464 // There is only one variant this argument could be; put it into the argument entry.
465 arg.push_back (thread_id_arg);
466
467 // Push the data for the first argument into the m_arguments vector.
468 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469 }
470
471 virtual
472 ~CommandObjectThreadStepWithTypeAndScope ()
473 {
474 }
475
476 virtual
477 Options *
478 GetOptions ()
479 {
480 return &m_options;
481 }
482
Jim Ingham5a988412012-06-08 21:56:10 +0000483protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000485 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000487 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000488 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489
Greg Claytonf9fc6092013-01-09 19:44:40 +0000490 const uint32_t num_threads = process->GetThreadList().GetSize();
491 Thread *thread = NULL;
492
493 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000495 thread = process->GetThreadList().GetSelectedThread().get();
496 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000498 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000500 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000502 }
503 else
504 {
505 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
506 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
507 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000509 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
510 result.SetStatus (eReturnStatusFailed);
511 return false;
512 }
513 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
514 if (thread == NULL)
515 {
516 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
517 step_thread_idx, num_threads);
518 result.SetStatus (eReturnStatusFailed);
519 return false;
520 }
521 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000522
Greg Claytonf9fc6092013-01-09 19:44:40 +0000523 const bool abort_other_plans = false;
524 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
525
526 // This is a bit unfortunate, but not all the commands in this command object support
527 // only while stepping, so I use the bool for them.
528 bool bool_stop_other_threads;
529 if (m_options.m_run_mode == eAllThreads)
530 bool_stop_other_threads = false;
531 else if (m_options.m_run_mode == eOnlyDuringStepping)
532 {
533 if (m_step_type == eStepTypeOut)
534 bool_stop_other_threads = false;
535 else
536 bool_stop_other_threads = true;
537 }
538 else
539 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000540
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000541 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000542
543 if (m_step_type == eStepTypeInto)
544 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000545 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000546
547 if (frame->HasDebugInformation ())
548 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000549 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000550 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
551 frame->GetSymbolContext(eSymbolContextEverything),
552 m_options.m_step_in_target.c_str(),
553 stop_other_threads,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000554 m_options.m_step_in_avoid_no_debug,
555 m_options.m_step_out_avoid_no_debug);
556
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000557 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000558 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000559 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000560 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000561 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000562 }
563 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000564 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000565
566 }
567 else if (m_step_type == eStepTypeOver)
568 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000569 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000570
571 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000572 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000573 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
574 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000575 stop_other_threads,
576 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000577 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000578 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000579 abort_other_plans,
580 bool_stop_other_threads);
581
582 }
583 else if (m_step_type == eStepTypeTrace)
584 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000585 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000586 }
587 else if (m_step_type == eStepTypeTraceOver)
588 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000589 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000590 }
591 else if (m_step_type == eStepTypeOut)
592 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000593 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000594 NULL,
595 false,
596 bool_stop_other_threads,
597 eVoteYes,
598 eVoteNoOpinion,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000599 thread->GetSelectedFrameIndex(),
600 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000601 }
602 else
603 {
604 result.AppendError ("step type is not supported");
605 result.SetStatus (eReturnStatusFailed);
606 return false;
607 }
608
609 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
610 // so that they can be interruptible). Then resume the process.
611
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000612 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000613 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000614 new_plan_sp->SetIsMasterPlan (true);
615 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000616
617 if (m_options.m_step_count > 1)
618 {
619 if (new_plan_sp->SetIterationCount(m_options.m_step_count) != m_options.m_step_count)
620 {
621 result.AppendWarning ("step operation does not support iteration count.");
622 }
623 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000624
625 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
626 process->Resume ();
627
628
629 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000630 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000631 StateType state = process->WaitForProcessToStop (NULL);
632
633 //EventSP event_sp;
634 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
635 //while (! StateIsStoppedState (state))
636 // {
637 // state = process->WaitForStateChangedEvents (NULL, event_sp);
638 // }
639 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
640 result.SetDidChangeProcessState (true);
641 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
642 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000643 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000644 else
645 {
646 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
647 }
648 }
649 else
650 {
651 result.AppendError ("Couldn't find thread plan to implement step type.");
652 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000653 }
654 return result.Succeeded();
655 }
656
657protected:
658 StepType m_step_type;
659 StepScope m_step_scope;
660 CommandOptions m_options;
661};
662
Greg Claytone0d378b2011-03-24 21:19:54 +0000663static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664g_tri_running_mode[] =
665{
Greg Claytoned8a7052010-09-18 03:37:20 +0000666{ eOnlyThisThread, "this-thread", "Run only this thread"},
667{ eAllThreads, "all-threads", "Run all threads"},
668{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000669{ 0, NULL, NULL }
670};
671
Greg Claytone0d378b2011-03-24 21:19:54 +0000672static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673g_duo_running_mode[] =
674{
Greg Claytoned8a7052010-09-18 03:37:20 +0000675{ eOnlyThisThread, "this-thread", "Run only this thread"},
676{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000677{ 0, NULL, NULL }
678};
679
Greg Claytone0d378b2011-03-24 21:19:54 +0000680OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
682{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000683{ 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."},
684{ 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."},
685{ 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."},
686{ 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."},
687{ 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."},
688{ 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."},
689{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000690};
691
692
693//-------------------------------------------------------------------------
694// CommandObjectThreadContinue
695//-------------------------------------------------------------------------
696
Jim Ingham5a988412012-06-08 21:56:10 +0000697class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698{
699public:
700
Greg Claytona7015092010-09-18 01:14:36 +0000701 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000702 CommandObjectParsed (interpreter,
703 "thread continue",
704 "Continue execution of one or more threads in an active process.",
705 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000706 eFlagRequiresThread |
707 eFlagTryTargetAPILock |
708 eFlagProcessMustBeLaunched |
709 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000710 {
Caroline Tice405fe672010-10-04 22:28:36 +0000711 CommandArgumentEntry arg;
712 CommandArgumentData thread_idx_arg;
713
714 // Define the first (and only) variant of this arg.
715 thread_idx_arg.arg_type = eArgTypeThreadIndex;
716 thread_idx_arg.arg_repetition = eArgRepeatPlus;
717
718 // There is only one variant this argument could be; put it into the argument entry.
719 arg.push_back (thread_idx_arg);
720
721 // Push the data for the first argument into the m_arguments vector.
722 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000723 }
724
725
726 virtual
727 ~CommandObjectThreadContinue ()
728 {
729 }
730
731 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000732 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 {
Greg Claytona7015092010-09-18 01:14:36 +0000734 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735
Greg Claytona7015092010-09-18 01:14:36 +0000736 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000738 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739 result.SetStatus (eReturnStatusFailed);
740 return false;
741 }
742
Greg Claytonf9fc6092013-01-09 19:44:40 +0000743 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744 if (process == NULL)
745 {
746 result.AppendError ("no process exists. Cannot continue");
747 result.SetStatus (eReturnStatusFailed);
748 return false;
749 }
750
751 StateType state = process->GetState();
752 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
753 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 const size_t argc = command.GetArgumentCount();
755 if (argc > 0)
756 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000757 // These two lines appear at the beginning of both blocks in
758 // this if..else, but that is because we need to release the
759 // lock before calling process->Resume below.
760 Mutex::Locker locker (process->GetThreadList().GetMutex());
761 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000762 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763 for (uint32_t i=0; i<argc; ++i)
764 {
Jim Inghamce76c622012-05-31 20:48:41 +0000765 bool success;
766 const int base = 0;
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000767 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
768 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000769 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000770 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000771
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000772 if (thread)
773 {
774 resume_threads.push_back(thread);
775 }
776 else
777 {
778 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
779 result.SetStatus (eReturnStatusFailed);
780 return false;
781 }
Jim Inghamce76c622012-05-31 20:48:41 +0000782 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783 else
Jim Inghamce76c622012-05-31 20:48:41 +0000784 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000785 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000786 result.SetStatus (eReturnStatusFailed);
787 return false;
788 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000790
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000791 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000792 {
793 result.AppendError ("no valid thread indexes were specified");
794 result.SetStatus (eReturnStatusFailed);
795 return false;
796 }
797 else
798 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000799 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000800 result.AppendMessageWithFormat ("Resuming thread: ");
801 else
802 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000803
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000804 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000805 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000806 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
807 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000808
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000809 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000810 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000811 resume_threads.erase(this_thread_pos);
812 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000813 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
814 else
815 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000816
817 const bool override_suspend = true;
818 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000819 }
820 else
821 {
822 thread->SetResumeState (eStateSuspended);
823 }
824 }
Daniel Malead01b2952012-11-29 21:49:15 +0000825 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000826 }
827 }
828 else
829 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000830 // These two lines appear at the beginning of both blocks in
831 // this if..else, but that is because we need to release the
832 // lock before calling process->Resume below.
833 Mutex::Locker locker (process->GetThreadList().GetMutex());
834 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000835 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000836 if (current_thread == NULL)
837 {
838 result.AppendError ("the process doesn't have a current thread");
839 result.SetStatus (eReturnStatusFailed);
840 return false;
841 }
842 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000843 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000844 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000845 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846 if (thread == current_thread)
847 {
Daniel Malead01b2952012-11-29 21:49:15 +0000848 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000849 const bool override_suspend = true;
850 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851 }
852 else
853 {
854 thread->SetResumeState (eStateSuspended);
855 }
856 }
857 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000858
859 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860 Error error (process->Resume());
861 if (error.Success())
862 {
Daniel Malead01b2952012-11-29 21:49:15 +0000863 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000864 if (synchronous_execution)
865 {
Greg Claytonb1320972010-07-14 00:18:15 +0000866 state = process->WaitForProcessToStop (NULL);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000867
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +0000869 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000870 result.SetStatus (eReturnStatusSuccessFinishNoResult);
871 }
872 else
873 {
874 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
875 }
876 }
877 else
878 {
879 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
880 result.SetStatus (eReturnStatusFailed);
881 }
882 }
883 else
884 {
885 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
886 StateAsCString(state));
887 result.SetStatus (eReturnStatusFailed);
888 }
889
890 return result.Succeeded();
891 }
892
893};
894
895//-------------------------------------------------------------------------
896// CommandObjectThreadUntil
897//-------------------------------------------------------------------------
898
Jim Ingham5a988412012-06-08 21:56:10 +0000899class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900{
901public:
902
903 class CommandOptions : public Options
904 {
905 public:
906 uint32_t m_thread_idx;
907 uint32_t m_frame_idx;
908
Greg Claytoneb0103f2011-04-07 22:46:35 +0000909 CommandOptions (CommandInterpreter &interpreter) :
910 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 m_thread_idx(LLDB_INVALID_THREAD_ID),
912 m_frame_idx(LLDB_INVALID_FRAME_ID)
913 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000914 // Keep default values of all options in one place: OptionParsingStarting ()
915 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916 }
917
918 virtual
919 ~CommandOptions ()
920 {
921 }
922
923 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000924 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 {
926 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000927 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928
929 switch (short_option)
930 {
931 case 't':
932 {
Greg Claytonb1320972010-07-14 00:18:15 +0000933 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934 if (m_thread_idx == LLDB_INVALID_INDEX32)
935 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000936 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000937 }
938 }
939 break;
940 case 'f':
941 {
942 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
943 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
944 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000945 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946 }
947 }
948 break;
949 case 'm':
950 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000951 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000952 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000953
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000954 if (error.Success())
955 {
956 if (run_mode == eAllThreads)
957 m_stop_others = false;
958 else
959 m_stop_others = true;
960 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961 }
962 break;
963 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000964 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000965 break;
966
967 }
968 return error;
969 }
970
971 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000972 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000974 m_thread_idx = LLDB_INVALID_THREAD_ID;
975 m_frame_idx = 0;
976 m_stop_others = false;
977 }
978
Greg Claytone0d378b2011-03-24 21:19:54 +0000979 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000980 GetDefinitions ()
981 {
982 return g_option_table;
983 }
984
985 uint32_t m_step_thread_idx;
986 bool m_stop_others;
987
988 // Options table: Required for subclasses of Options.
989
Greg Claytone0d378b2011-03-24 21:19:54 +0000990 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991
992 // Instance variables to hold the values for command options.
993 };
994
Greg Claytona7015092010-09-18 01:14:36 +0000995 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000996 CommandObjectParsed (interpreter,
997 "thread until",
998 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
999 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001000 eFlagRequiresThread |
1001 eFlagTryTargetAPILock |
1002 eFlagProcessMustBeLaunched |
1003 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001004 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001005 {
Caroline Tice405fe672010-10-04 22:28:36 +00001006 CommandArgumentEntry arg;
1007 CommandArgumentData line_num_arg;
1008
1009 // Define the first (and only) variant of this arg.
1010 line_num_arg.arg_type = eArgTypeLineNum;
1011 line_num_arg.arg_repetition = eArgRepeatPlain;
1012
1013 // There is only one variant this argument could be; put it into the argument entry.
1014 arg.push_back (line_num_arg);
1015
1016 // Push the data for the first argument into the m_arguments vector.
1017 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018 }
1019
1020
1021 virtual
1022 ~CommandObjectThreadUntil ()
1023 {
1024 }
1025
1026 virtual
1027 Options *
1028 GetOptions ()
1029 {
1030 return &m_options;
1031 }
1032
Jim Ingham5a988412012-06-08 21:56:10 +00001033protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001035 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036 {
Greg Claytona7015092010-09-18 01:14:36 +00001037 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038
Greg Claytona7015092010-09-18 01:14:36 +00001039 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +00001040 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001041 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001042 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 result.SetStatus (eReturnStatusFailed);
1044 return false;
1045 }
1046
Greg Claytonf9fc6092013-01-09 19:44:40 +00001047 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048 if (process == NULL)
1049 {
1050 result.AppendError ("need a valid process to step");
1051 result.SetStatus (eReturnStatusFailed);
1052
1053 }
1054 else
1055 {
1056 Thread *thread = NULL;
1057 uint32_t line_number;
1058
1059 if (command.GetArgumentCount() != 1)
1060 {
1061 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1062 result.SetStatus (eReturnStatusFailed);
1063 return false;
1064 }
1065
1066 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1067 if (line_number == UINT32_MAX)
1068 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001069 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070 result.SetStatus (eReturnStatusFailed);
1071 return false;
1072 }
1073
1074 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1075 {
Jim Ingham2976d002010-08-26 21:32:51 +00001076 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077 }
1078 else
1079 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001080 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081 }
1082
1083 if (thread == NULL)
1084 {
1085 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001086 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1087 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001088 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089 result.SetStatus (eReturnStatusFailed);
1090 return false;
1091 }
1092
Jim Ingham7ba6e992012-05-11 23:47:32 +00001093 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094
Jason Molendab57e4a12013-11-04 09:33:30 +00001095 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 if (frame == NULL)
1097 {
1098
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001099 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1100 m_options.m_frame_idx,
1101 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102 result.SetStatus (eReturnStatusFailed);
1103 return false;
1104 }
1105
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001106 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001107
1108 if (frame->HasDebugInformation ())
1109 {
1110 // Finally we got here... Translate the given line number to a bunch of addresses:
1111 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1112 LineTable *line_table = NULL;
1113 if (sc.comp_unit)
1114 line_table = sc.comp_unit->GetLineTable();
1115
1116 if (line_table == NULL)
1117 {
1118 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1119 m_options.m_frame_idx, m_options.m_thread_idx);
1120 result.SetStatus (eReturnStatusFailed);
1121 return false;
1122 }
1123
1124 LineEntry function_start;
1125 uint32_t index_ptr = 0, end_ptr;
1126 std::vector<addr_t> address_list;
1127
1128 // Find the beginning & end index of the
1129 AddressRange fun_addr_range = sc.function->GetAddressRange();
1130 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1131 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1132
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001133 Address fun_end_addr(fun_start_addr.GetSection(),
1134 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1136
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001137 bool all_in_function = true;
1138
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139 while (index_ptr <= end_ptr)
1140 {
1141 LineEntry line_entry;
Jim Ingham87df91b2011-09-23 00:54:11 +00001142 const bool exact = false;
1143 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144 if (index_ptr == UINT32_MAX)
1145 break;
1146
Greg Claytonf5e56de2010-09-14 23:36:40 +00001147 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148 if (address != LLDB_INVALID_ADDRESS)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001149 {
1150 if (fun_addr_range.ContainsLoadAddress (address, target))
1151 address_list.push_back (address);
1152 else
1153 all_in_function = false;
1154 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001155 index_ptr++;
1156 }
1157
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001158 if (address_list.size() == 0)
1159 {
1160 if (all_in_function)
1161 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1162 else
1163 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1164
1165 result.SetStatus (eReturnStatusFailed);
1166 return false;
1167 }
1168
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001169 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001170 &address_list.front(),
1171 address_list.size(),
1172 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001173 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001174 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1175 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1176 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001177 new_plan_sp->SetIsMasterPlan (true);
1178 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 }
1180 else
1181 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001182 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1183 m_options.m_frame_idx,
1184 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185 result.SetStatus (eReturnStatusFailed);
1186 return false;
1187
1188 }
1189
Jim Ingham2976d002010-08-26 21:32:51 +00001190 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191 Error error (process->Resume ());
1192 if (error.Success())
1193 {
Daniel Malead01b2952012-11-29 21:49:15 +00001194 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001195 if (synchronous_execution)
1196 {
1197 StateType state = process->WaitForProcessToStop (NULL);
1198
1199 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +00001200 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1202 }
1203 else
1204 {
1205 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1206 }
1207 }
1208 else
1209 {
1210 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1211 result.SetStatus (eReturnStatusFailed);
1212 }
1213
1214 }
1215 return result.Succeeded();
1216 }
Jim Ingham5a988412012-06-08 21:56:10 +00001217
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001218 CommandOptions m_options;
1219
1220};
1221
Greg Claytone0d378b2011-03-24 21:19:54 +00001222OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001223CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1224{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001225{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1226{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1227{ 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"},
1228{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001229};
1230
1231
1232//-------------------------------------------------------------------------
1233// CommandObjectThreadSelect
1234//-------------------------------------------------------------------------
1235
Jim Ingham5a988412012-06-08 21:56:10 +00001236class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237{
1238public:
1239
Greg Claytona7015092010-09-18 01:14:36 +00001240 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001241 CommandObjectParsed (interpreter,
1242 "thread select",
1243 "Select a thread as the currently active thread.",
1244 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001245 eFlagRequiresProcess |
1246 eFlagTryTargetAPILock |
1247 eFlagProcessMustBeLaunched |
1248 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001249 {
Caroline Tice405fe672010-10-04 22:28:36 +00001250 CommandArgumentEntry arg;
1251 CommandArgumentData thread_idx_arg;
1252
1253 // Define the first (and only) variant of this arg.
1254 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1255 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1256
1257 // There is only one variant this argument could be; put it into the argument entry.
1258 arg.push_back (thread_idx_arg);
1259
1260 // Push the data for the first argument into the m_arguments vector.
1261 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 }
1263
1264
1265 virtual
1266 ~CommandObjectThreadSelect ()
1267 {
1268 }
1269
Jim Ingham5a988412012-06-08 21:56:10 +00001270protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001272 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001273 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001274 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275 if (process == NULL)
1276 {
1277 result.AppendError ("no process");
1278 result.SetStatus (eReturnStatusFailed);
1279 return false;
1280 }
1281 else if (command.GetArgumentCount() != 1)
1282 {
Jason Molendafd54b362011-09-20 21:44:10 +00001283 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001284 result.SetStatus (eReturnStatusFailed);
1285 return false;
1286 }
1287
1288 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1289
1290 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1291 if (new_thread == NULL)
1292 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001293 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294 result.SetStatus (eReturnStatusFailed);
1295 return false;
1296 }
1297
Jim Inghamc3faa192012-12-11 02:31:48 +00001298 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001299 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001301 return result.Succeeded();
1302 }
1303
1304};
1305
1306
1307//-------------------------------------------------------------------------
1308// CommandObjectThreadList
1309//-------------------------------------------------------------------------
1310
Jim Ingham5a988412012-06-08 21:56:10 +00001311class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001312{
Greg Clayton66111032010-06-23 01:19:29 +00001313public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001314
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001315
Greg Claytona7015092010-09-18 01:14:36 +00001316 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001317 CommandObjectParsed (interpreter,
1318 "thread list",
1319 "Show a summary of all current threads in a process.",
1320 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001321 eFlagRequiresProcess |
1322 eFlagTryTargetAPILock |
1323 eFlagProcessMustBeLaunched |
1324 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001325 {
Greg Clayton66111032010-06-23 01:19:29 +00001326 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001327
Greg Clayton66111032010-06-23 01:19:29 +00001328 ~CommandObjectThreadList()
1329 {
1330 }
1331
Jim Ingham5a988412012-06-08 21:56:10 +00001332protected:
Greg Clayton66111032010-06-23 01:19:29 +00001333 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001334 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001335 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001336 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001337 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001338 Process *process = m_exe_ctx.GetProcessPtr();
1339 const bool only_threads_with_stop_reason = false;
1340 const uint32_t start_frame = 0;
1341 const uint32_t num_frames = 0;
1342 const uint32_t num_frames_with_source = 0;
1343 process->GetStatus(strm);
1344 process->GetThreadStatus (strm,
1345 only_threads_with_stop_reason,
1346 start_frame,
1347 num_frames,
1348 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001349 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350 }
Greg Clayton66111032010-06-23 01:19:29 +00001351};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352
Jim Ingham93208b82013-01-31 21:46:01 +00001353//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001354// CommandObjectThreadInfo
1355//-------------------------------------------------------------------------
1356
1357class CommandObjectThreadInfo : public CommandObjectParsed
1358{
1359public:
1360
1361 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
1362 CommandObjectParsed (interpreter,
1363 "thread info",
1364 "Show an extended summary of information about thread(s) in a process.",
1365 "thread info",
1366 eFlagRequiresProcess |
1367 eFlagTryTargetAPILock |
1368 eFlagProcessMustBeLaunched |
1369 eFlagProcessMustBePaused),
1370 m_options (interpreter)
1371 {
1372 CommandArgumentEntry arg;
1373 CommandArgumentData thread_idx_arg;
1374
1375 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1376 thread_idx_arg.arg_repetition = eArgRepeatStar;
1377
1378 // There is only one variant this argument could be; put it into the argument entry.
1379 arg.push_back (thread_idx_arg);
1380
1381 // Push the data for the first argument into the m_arguments vector.
1382 m_arguments.push_back (arg);
1383 }
1384
1385 class CommandOptions : public Options
1386 {
1387 public:
1388
1389 CommandOptions (CommandInterpreter &interpreter) :
1390 Options (interpreter)
1391 {
1392 OptionParsingStarting ();
1393 }
1394
1395 void
1396 OptionParsingStarting ()
1397 {
1398 m_json = false;
1399 }
1400
1401 virtual
1402 ~CommandOptions ()
1403 {
1404 }
1405
1406 virtual Error
1407 SetOptionValue (uint32_t option_idx, const char *option_arg)
1408 {
1409 const int short_option = m_getopt_table[option_idx].val;
1410 Error error;
1411
1412 switch (short_option)
1413 {
1414 case 'j':
1415 m_json = true;
1416 break;
1417
1418 default:
1419 return Error("invalid short option character '%c'", short_option);
1420
1421 }
1422 return error;
1423 }
1424
1425 const OptionDefinition*
1426 GetDefinitions ()
1427 {
1428 return g_option_table;
1429 }
1430
1431 bool m_json;
1432
1433 static OptionDefinition g_option_table[];
1434 };
1435
1436 virtual
1437 Options *
1438 GetOptions ()
1439 {
1440 return &m_options;
1441 }
1442
1443
1444 virtual
1445 ~CommandObjectThreadInfo ()
1446 {
1447 }
1448
1449 virtual bool
1450 DoExecute (Args& command, CommandReturnObject &result)
1451 {
1452 result.SetStatus (eReturnStatusSuccessFinishResult);
1453 Stream &strm = result.GetOutputStream();
1454
1455 if (command.GetArgumentCount() == 0)
1456 {
1457 Thread *thread = m_exe_ctx.GetThreadPtr();
1458 if (thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json))
1459 {
1460 result.SetStatus (eReturnStatusSuccessFinishResult);
1461 }
1462 }
1463 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
1464 {
1465 Process *process = m_exe_ctx.GetProcessPtr();
1466 uint32_t idx = 0;
1467 for (ThreadSP thread_sp : process->Threads())
1468 {
1469 if (idx != 0)
1470 result.AppendMessage("");
1471 if (!thread_sp->GetDescription (strm, eDescriptionLevelFull, m_options.m_json))
1472 {
1473 result.AppendErrorWithFormat ("error displaying info for thread: \"0x%4.4x\"\n", idx);
1474 result.SetStatus (eReturnStatusFailed);
1475 return false;
1476 }
1477 ++idx;
1478 }
1479 }
1480 else
1481 {
1482 const size_t num_args = command.GetArgumentCount();
1483 Process *process = m_exe_ctx.GetProcessPtr();
1484 Mutex::Locker locker (process->GetThreadList().GetMutex());
1485 std::vector<ThreadSP> thread_sps;
1486
1487 for (size_t i = 0; i < num_args; i++)
1488 {
1489 bool success;
1490
1491 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
1492 if (!success)
1493 {
1494 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
1495 result.SetStatus (eReturnStatusFailed);
1496 return false;
1497 }
1498
1499 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
1500
1501 if (!thread_sps[i])
1502 {
1503 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
1504 result.SetStatus (eReturnStatusFailed);
1505 return false;
1506 }
1507
1508 }
1509
1510 for (uint32_t i = 0; i < num_args; i++)
1511 {
1512 if (!thread_sps[i]->GetDescription (strm, eDescriptionLevelFull, m_options.m_json))
1513 {
1514 result.AppendErrorWithFormat ("error displaying info for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
1515 result.SetStatus (eReturnStatusFailed);
1516 return false;
1517 }
1518
1519 if (i < num_args - 1)
1520 result.AppendMessage("");
1521 }
1522
1523 }
1524 return result.Succeeded();
1525 }
1526
1527 CommandOptions m_options;
1528
1529};
1530
1531OptionDefinition
1532CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1533{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001534 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."},
Jason Molenda705b1802014-06-13 02:37:02 +00001535
Zachary Turnerd37221d2014-07-09 16:31:49 +00001536 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jason Molenda705b1802014-06-13 02:37:02 +00001537};
1538
1539
1540//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001541// CommandObjectThreadReturn
1542//-------------------------------------------------------------------------
1543
Jim Inghamcb640dd2012-09-14 02:14:15 +00001544class CommandObjectThreadReturn : public CommandObjectRaw
1545{
1546public:
Jim Ingham93208b82013-01-31 21:46:01 +00001547 class CommandOptions : public Options
1548 {
1549 public:
1550
1551 CommandOptions (CommandInterpreter &interpreter) :
1552 Options (interpreter),
1553 m_from_expression (false)
1554 {
1555 // Keep default values of all options in one place: OptionParsingStarting ()
1556 OptionParsingStarting ();
1557 }
1558
1559 virtual
1560 ~CommandOptions ()
1561 {
1562 }
1563
1564 virtual Error
1565 SetOptionValue (uint32_t option_idx, const char *option_arg)
1566 {
1567 Error error;
1568 const int short_option = m_getopt_table[option_idx].val;
1569
1570 switch (short_option)
1571 {
1572 case 'x':
1573 {
1574 bool success;
1575 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1576 if (success)
1577 m_from_expression = tmp_value;
1578 else
1579 {
1580 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1581 }
1582 }
1583 break;
1584 default:
1585 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1586 break;
1587
1588 }
1589 return error;
1590 }
1591
1592 void
1593 OptionParsingStarting ()
1594 {
1595 m_from_expression = false;
1596 }
1597
1598 const OptionDefinition*
1599 GetDefinitions ()
1600 {
1601 return g_option_table;
1602 }
1603
1604 bool m_from_expression;
1605
1606 // Options table: Required for subclasses of Options.
1607
1608 static OptionDefinition g_option_table[];
1609
1610 // Instance variables to hold the values for command options.
1611 };
1612
1613 virtual
1614 Options *
1615 GetOptions ()
1616 {
1617 return &m_options;
1618 }
1619
Jim Inghamcb640dd2012-09-14 02:14:15 +00001620 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1621 CommandObjectRaw (interpreter,
1622 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001623 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1624 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001625 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001626 eFlagRequiresFrame |
1627 eFlagTryTargetAPILock |
1628 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001629 eFlagProcessMustBePaused ),
1630 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001631 {
1632 CommandArgumentEntry arg;
1633 CommandArgumentData expression_arg;
1634
1635 // Define the first (and only) variant of this arg.
1636 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001637 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001638
1639 // There is only one variant this argument could be; put it into the argument entry.
1640 arg.push_back (expression_arg);
1641
1642 // Push the data for the first argument into the m_arguments vector.
1643 m_arguments.push_back (arg);
1644
1645
1646 }
1647
1648 ~CommandObjectThreadReturn()
1649 {
1650 }
1651
1652protected:
1653
1654 bool DoExecute
1655 (
1656 const char *command,
1657 CommandReturnObject &result
1658 )
1659 {
Jim Ingham93208b82013-01-31 21:46:01 +00001660 // I am going to handle this by hand, because I don't want you to have to say:
1661 // "thread return -- -5".
1662 if (command[0] == '-' && command[1] == 'x')
1663 {
1664 if (command && command[2] != '\0')
1665 result.AppendWarning("Return values ignored when returning from user called expressions");
1666
1667 Thread *thread = m_exe_ctx.GetThreadPtr();
1668 Error error;
1669 error = thread->UnwindInnermostExpression();
1670 if (!error.Success())
1671 {
1672 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1673 result.SetStatus (eReturnStatusFailed);
1674 }
1675 else
1676 {
1677 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1678 if (success)
1679 {
1680 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1681 result.SetStatus (eReturnStatusSuccessFinishResult);
1682 }
1683 else
1684 {
1685 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1686 result.SetStatus (eReturnStatusFailed);
1687 }
1688 }
1689 return result.Succeeded();
1690 }
1691
Jim Inghamcb640dd2012-09-14 02:14:15 +00001692 ValueObjectSP return_valobj_sp;
1693
Jason Molendab57e4a12013-11-04 09:33:30 +00001694 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001695 uint32_t frame_idx = frame_sp->GetFrameIndex();
1696
1697 if (frame_sp->IsInlined())
1698 {
1699 result.AppendError("Don't know how to return from inlined frames.");
1700 result.SetStatus (eReturnStatusFailed);
1701 return false;
1702 }
1703
1704 if (command && command[0] != '\0')
1705 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001706 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001707 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001708
1709 options.SetUnwindOnError(true);
1710 options.SetUseDynamic(eNoDynamicValues);
1711
Jim Ingham8646d3c2014-05-05 02:47:44 +00001712 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001713 exe_results = target->EvaluateExpression (command,
1714 frame_sp.get(),
1715 return_valobj_sp,
1716 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001717 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001718 {
1719 if (return_valobj_sp)
1720 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1721 else
1722 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1723 result.SetStatus (eReturnStatusFailed);
1724 return false;
1725
1726 }
1727 }
1728
1729 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001730 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001731 const bool broadcast = true;
1732 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001733 if (!error.Success())
1734 {
1735 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1736 result.SetStatus (eReturnStatusFailed);
1737 return false;
1738 }
1739
Jim Inghamcb640dd2012-09-14 02:14:15 +00001740 result.SetStatus (eReturnStatusSuccessFinishResult);
1741 return true;
1742 }
Jim Ingham93208b82013-01-31 21:46:01 +00001743
1744 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001745
1746};
Jim Ingham93208b82013-01-31 21:46:01 +00001747OptionDefinition
1748CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1749{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001750{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1751{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham93208b82013-01-31 21:46:01 +00001752};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001753
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001754//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001755// CommandObjectThreadJump
1756//-------------------------------------------------------------------------
1757
1758class CommandObjectThreadJump : public CommandObjectParsed
1759{
1760public:
1761 class CommandOptions : public Options
1762 {
1763 public:
1764
1765 CommandOptions (CommandInterpreter &interpreter) :
1766 Options (interpreter)
1767 {
1768 OptionParsingStarting ();
1769 }
1770
1771 void
1772 OptionParsingStarting ()
1773 {
1774 m_filenames.Clear();
1775 m_line_num = 0;
1776 m_line_offset = 0;
1777 m_load_addr = LLDB_INVALID_ADDRESS;
1778 m_force = false;
1779 }
1780
1781 virtual
1782 ~CommandOptions ()
1783 {
1784 }
1785
1786 virtual Error
1787 SetOptionValue (uint32_t option_idx, const char *option_arg)
1788 {
1789 bool success;
1790 const int short_option = m_getopt_table[option_idx].val;
1791 Error error;
1792
1793 switch (short_option)
1794 {
1795 case 'f':
1796 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1797 if (m_filenames.GetSize() > 1)
1798 return Error("only one source file expected.");
1799 break;
1800 case 'l':
1801 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1802 if (!success || m_line_num == 0)
1803 return Error("invalid line number: '%s'.", option_arg);
1804 break;
1805 case 'b':
1806 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1807 if (!success)
1808 return Error("invalid line offset: '%s'.", option_arg);
1809 break;
1810 case 'a':
1811 {
1812 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1813 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1814 }
1815 break;
1816 case 'r':
1817 m_force = true;
1818 break;
1819
1820 default:
1821 return Error("invalid short option character '%c'", short_option);
1822
1823 }
1824 return error;
1825 }
1826
1827 const OptionDefinition*
1828 GetDefinitions ()
1829 {
1830 return g_option_table;
1831 }
1832
1833 FileSpecList m_filenames;
1834 uint32_t m_line_num;
1835 int32_t m_line_offset;
1836 lldb::addr_t m_load_addr;
1837 bool m_force;
1838
1839 static OptionDefinition g_option_table[];
1840 };
1841
1842 virtual
1843 Options *
1844 GetOptions ()
1845 {
1846 return &m_options;
1847 }
1848
1849 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1850 CommandObjectParsed (interpreter,
1851 "thread jump",
1852 "Sets the program counter to a new address.",
1853 "thread jump",
1854 eFlagRequiresFrame |
1855 eFlagTryTargetAPILock |
1856 eFlagProcessMustBeLaunched |
1857 eFlagProcessMustBePaused ),
1858 m_options (interpreter)
1859 {
1860 }
1861
1862 ~CommandObjectThreadJump()
1863 {
1864 }
1865
1866protected:
1867
1868 bool DoExecute (Args& args, CommandReturnObject &result)
1869 {
1870 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001871 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001872 Thread *thread = m_exe_ctx.GetThreadPtr();
1873 Target *target = m_exe_ctx.GetTargetPtr();
1874 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1875
1876 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1877 {
1878 // Use this address directly.
1879 Address dest = Address(m_options.m_load_addr);
1880
1881 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1882 if (callAddr == LLDB_INVALID_ADDRESS)
1883 {
1884 result.AppendErrorWithFormat ("Invalid destination address.");
1885 result.SetStatus (eReturnStatusFailed);
1886 return false;
1887 }
1888
1889 if (!reg_ctx->SetPC (callAddr))
1890 {
1891 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1892 result.SetStatus (eReturnStatusFailed);
1893 return false;
1894 }
1895 }
1896 else
1897 {
1898 // Pick either the absolute line, or work out a relative one.
1899 int32_t line = (int32_t)m_options.m_line_num;
1900 if (line == 0)
1901 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1902
1903 // Try the current file, but override if asked.
1904 FileSpec file = sym_ctx.line_entry.file;
1905 if (m_options.m_filenames.GetSize() == 1)
1906 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1907
1908 if (!file)
1909 {
1910 result.AppendErrorWithFormat ("No source file available for the current location.");
1911 result.SetStatus (eReturnStatusFailed);
1912 return false;
1913 }
1914
1915 std::string warnings;
1916 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1917
1918 if (err.Fail())
1919 {
1920 result.SetError (err);
1921 return false;
1922 }
1923
1924 if (!warnings.empty())
1925 result.AppendWarning (warnings.c_str());
1926 }
1927
1928 result.SetStatus (eReturnStatusSuccessFinishResult);
1929 return true;
1930 }
1931
1932 CommandOptions m_options;
1933};
1934OptionDefinition
1935CommandObjectThreadJump::CommandOptions::g_option_table[] =
1936{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001937 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001938 "Specifies the source file to jump to."},
1939
Zachary Turnerd37221d2014-07-09 16:31:49 +00001940 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001941 "Specifies the line number to jump to."},
1942
Zachary Turnerd37221d2014-07-09 16:31:49 +00001943 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001944 "Jumps by a relative line offset from the current line."},
1945
Zachary Turnerd37221d2014-07-09 16:31:49 +00001946 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001947 "Jumps to a specific address."},
1948
1949 { LLDB_OPT_SET_1|
1950 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +00001951 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
Richard Mittonf86248d2013-09-12 02:20:34 +00001952
Zachary Turnerd37221d2014-07-09 16:31:49 +00001953 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Richard Mittonf86248d2013-09-12 02:20:34 +00001954};
1955
1956//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001957// CommandObjectMultiwordThread
1958//-------------------------------------------------------------------------
1959
Greg Clayton66111032010-06-23 01:19:29 +00001960CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001961 CommandObjectMultiword (interpreter,
1962 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001963 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001964 "thread <subcommand> [<subcommand-options>]")
1965{
Greg Claytona7015092010-09-18 01:14:36 +00001966 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1967 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1968 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00001969 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00001970 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001971 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1972 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00001973 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001974 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1975 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00001976 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00001977 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001978 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001979 eStepTypeInto,
1980 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00001981
Greg Claytona7015092010-09-18 01:14:36 +00001982 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1983 interpreter,
1984 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00001985 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001986 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001987 eStepTypeOut,
1988 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001989
Greg Claytona7015092010-09-18 01:14:36 +00001990 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1991 interpreter,
1992 "thread step-over",
1993 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001994 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001995 eStepTypeOver,
1996 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001997
Greg Claytona7015092010-09-18 01:14:36 +00001998 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1999 interpreter,
2000 "thread step-inst",
2001 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002002 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002003 eStepTypeTrace,
2004 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002005
Greg Claytona7015092010-09-18 01:14:36 +00002006 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2007 interpreter,
2008 "thread step-inst-over",
2009 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002010 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002011 eStepTypeTraceOver,
2012 eStepScopeInstruction)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002013}
2014
2015CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
2016{
2017}
2018
2019