blob: ebf42b15782c42ea8fc203fb1983e7fee3213ba7 [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{
Virgile Belloe2607b52013-09-05 16:42:23 +0000308{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
309{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
Jason Molenda750ea692013-11-12 07:02:07 +0000310{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
Caroline Ticedeaab222010-10-01 19:59:14 +0000311{ 0, false, NULL, 0, 0, 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
374 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000377 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 }
379 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000380
381 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000382 {
383 m_avoid_regexp.clear();
384 m_avoid_regexp.assign(option_arg);
385 }
386 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000387
Jim Inghamc6276822012-12-12 19:58:40 +0000388 case 't':
389 {
390 m_step_in_target.clear();
391 m_step_in_target.assign(option_arg);
392
393 }
394 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000395 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000396 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000397 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398
399 }
400 return error;
401 }
402
403 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000404 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000406 m_step_in_avoid_no_debug = eLazyBoolCalculate;
407 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408 m_run_mode = eOnlyDuringStepping;
Jim Inghama56c8002010-07-10 02:27:39 +0000409 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000410 m_step_in_target.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411 }
412
Greg Claytone0d378b2011-03-24 21:19:54 +0000413 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414 GetDefinitions ()
415 {
416 return g_option_table;
417 }
418
419 // Options table: Required for subclasses of Options.
420
Greg Claytone0d378b2011-03-24 21:19:54 +0000421 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422
423 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000424 LazyBool m_step_in_avoid_no_debug;
425 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000427 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000428 std::string m_step_in_target;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429 };
430
Greg Claytona7015092010-09-18 01:14:36 +0000431 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
432 const char *name,
433 const char *help,
434 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000435 StepType step_type,
436 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000437 CommandObjectParsed (interpreter, name, help, syntax,
438 eFlagRequiresProcess |
439 eFlagRequiresThread |
440 eFlagTryTargetAPILock |
441 eFlagProcessMustBeLaunched |
442 eFlagProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443 m_step_type (step_type),
444 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000445 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446 {
Caroline Tice405fe672010-10-04 22:28:36 +0000447 CommandArgumentEntry arg;
448 CommandArgumentData thread_id_arg;
449
450 // Define the first (and only) variant of this arg.
451 thread_id_arg.arg_type = eArgTypeThreadID;
452 thread_id_arg.arg_repetition = eArgRepeatOptional;
453
454 // There is only one variant this argument could be; put it into the argument entry.
455 arg.push_back (thread_id_arg);
456
457 // Push the data for the first argument into the m_arguments vector.
458 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 }
460
461 virtual
462 ~CommandObjectThreadStepWithTypeAndScope ()
463 {
464 }
465
466 virtual
467 Options *
468 GetOptions ()
469 {
470 return &m_options;
471 }
472
Jim Ingham5a988412012-06-08 21:56:10 +0000473protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000475 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000477 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000478 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000479
Greg Claytonf9fc6092013-01-09 19:44:40 +0000480 const uint32_t num_threads = process->GetThreadList().GetSize();
481 Thread *thread = NULL;
482
483 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000485 thread = process->GetThreadList().GetSelectedThread().get();
486 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000488 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000490 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000492 }
493 else
494 {
495 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
496 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
497 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000498 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000499 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
500 result.SetStatus (eReturnStatusFailed);
501 return false;
502 }
503 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
504 if (thread == NULL)
505 {
506 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
507 step_thread_idx, num_threads);
508 result.SetStatus (eReturnStatusFailed);
509 return false;
510 }
511 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000512
Greg Claytonf9fc6092013-01-09 19:44:40 +0000513 const bool abort_other_plans = false;
514 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
515
516 // This is a bit unfortunate, but not all the commands in this command object support
517 // only while stepping, so I use the bool for them.
518 bool bool_stop_other_threads;
519 if (m_options.m_run_mode == eAllThreads)
520 bool_stop_other_threads = false;
521 else if (m_options.m_run_mode == eOnlyDuringStepping)
522 {
523 if (m_step_type == eStepTypeOut)
524 bool_stop_other_threads = false;
525 else
526 bool_stop_other_threads = true;
527 }
528 else
529 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000530
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000531 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000532
533 if (m_step_type == eStepTypeInto)
534 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000535 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000536
537 if (frame->HasDebugInformation ())
538 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000539 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000540 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
541 frame->GetSymbolContext(eSymbolContextEverything),
542 m_options.m_step_in_target.c_str(),
543 stop_other_threads,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000544 m_options.m_step_in_avoid_no_debug,
545 m_options.m_step_out_avoid_no_debug);
546
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000547 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000548 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000549 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000550 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000551 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000552 }
553 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000554 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000555
556 }
557 else if (m_step_type == eStepTypeOver)
558 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000559 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000560
561 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000562 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000563 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
564 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000565 stop_other_threads,
566 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000567 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000568 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000569 abort_other_plans,
570 bool_stop_other_threads);
571
572 }
573 else if (m_step_type == eStepTypeTrace)
574 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000575 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000576 }
577 else if (m_step_type == eStepTypeTraceOver)
578 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000579 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000580 }
581 else if (m_step_type == eStepTypeOut)
582 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000583 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000584 NULL,
585 false,
586 bool_stop_other_threads,
587 eVoteYes,
588 eVoteNoOpinion,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000589 thread->GetSelectedFrameIndex(),
590 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000591 }
592 else
593 {
594 result.AppendError ("step type is not supported");
595 result.SetStatus (eReturnStatusFailed);
596 return false;
597 }
598
599 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
600 // so that they can be interruptible). Then resume the process.
601
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000602 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000603 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000604 new_plan_sp->SetIsMasterPlan (true);
605 new_plan_sp->SetOkayToDiscard (false);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000606
607 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
608 process->Resume ();
609
610
611 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000612 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000613 StateType state = process->WaitForProcessToStop (NULL);
614
615 //EventSP event_sp;
616 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
617 //while (! StateIsStoppedState (state))
618 // {
619 // state = process->WaitForStateChangedEvents (NULL, event_sp);
620 // }
621 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
622 result.SetDidChangeProcessState (true);
623 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
624 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000626 else
627 {
628 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
629 }
630 }
631 else
632 {
633 result.AppendError ("Couldn't find thread plan to implement step type.");
634 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000635 }
636 return result.Succeeded();
637 }
638
639protected:
640 StepType m_step_type;
641 StepScope m_step_scope;
642 CommandOptions m_options;
643};
644
Greg Claytone0d378b2011-03-24 21:19:54 +0000645static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646g_tri_running_mode[] =
647{
Greg Claytoned8a7052010-09-18 03:37:20 +0000648{ eOnlyThisThread, "this-thread", "Run only this thread"},
649{ eAllThreads, "all-threads", "Run all threads"},
650{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000651{ 0, NULL, NULL }
652};
653
Greg Claytone0d378b2011-03-24 21:19:54 +0000654static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655g_duo_running_mode[] =
656{
Greg Claytoned8a7052010-09-18 03:37:20 +0000657{ eOnlyThisThread, "this-thread", "Run only this thread"},
658{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659{ 0, NULL, NULL }
660};
661
Greg Claytone0d378b2011-03-24 21:19:54 +0000662OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
664{
Jim Ingham4b4b2472014-03-13 02:47:14 +0000665{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
666{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, 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."},
Virgile Belloe2607b52013-09-05 16:42:23 +0000667{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
668{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
669{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
Caroline Ticedeaab222010-10-01 19:59:14 +0000670{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671};
672
673
674//-------------------------------------------------------------------------
675// CommandObjectThreadContinue
676//-------------------------------------------------------------------------
677
Jim Ingham5a988412012-06-08 21:56:10 +0000678class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679{
680public:
681
Greg Claytona7015092010-09-18 01:14:36 +0000682 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000683 CommandObjectParsed (interpreter,
684 "thread continue",
685 "Continue execution of one or more threads in an active process.",
686 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000687 eFlagRequiresThread |
688 eFlagTryTargetAPILock |
689 eFlagProcessMustBeLaunched |
690 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000691 {
Caroline Tice405fe672010-10-04 22:28:36 +0000692 CommandArgumentEntry arg;
693 CommandArgumentData thread_idx_arg;
694
695 // Define the first (and only) variant of this arg.
696 thread_idx_arg.arg_type = eArgTypeThreadIndex;
697 thread_idx_arg.arg_repetition = eArgRepeatPlus;
698
699 // There is only one variant this argument could be; put it into the argument entry.
700 arg.push_back (thread_idx_arg);
701
702 // Push the data for the first argument into the m_arguments vector.
703 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704 }
705
706
707 virtual
708 ~CommandObjectThreadContinue ()
709 {
710 }
711
712 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000713 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714 {
Greg Claytona7015092010-09-18 01:14:36 +0000715 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716
Greg Claytona7015092010-09-18 01:14:36 +0000717 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000719 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720 result.SetStatus (eReturnStatusFailed);
721 return false;
722 }
723
Greg Claytonf9fc6092013-01-09 19:44:40 +0000724 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725 if (process == NULL)
726 {
727 result.AppendError ("no process exists. Cannot continue");
728 result.SetStatus (eReturnStatusFailed);
729 return false;
730 }
731
732 StateType state = process->GetState();
733 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
734 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735 const size_t argc = command.GetArgumentCount();
736 if (argc > 0)
737 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000738 // These two lines appear at the beginning of both blocks in
739 // this if..else, but that is because we need to release the
740 // lock before calling process->Resume below.
741 Mutex::Locker locker (process->GetThreadList().GetMutex());
742 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000743 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744 for (uint32_t i=0; i<argc; ++i)
745 {
Jim Inghamce76c622012-05-31 20:48:41 +0000746 bool success;
747 const int base = 0;
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000748 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
749 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000750 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000751 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000752
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000753 if (thread)
754 {
755 resume_threads.push_back(thread);
756 }
757 else
758 {
759 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
760 result.SetStatus (eReturnStatusFailed);
761 return false;
762 }
Jim Inghamce76c622012-05-31 20:48:41 +0000763 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 else
Jim Inghamce76c622012-05-31 20:48:41 +0000765 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000766 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000767 result.SetStatus (eReturnStatusFailed);
768 return false;
769 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000771
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000772 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773 {
774 result.AppendError ("no valid thread indexes were specified");
775 result.SetStatus (eReturnStatusFailed);
776 return false;
777 }
778 else
779 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000780 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000781 result.AppendMessageWithFormat ("Resuming thread: ");
782 else
783 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000784
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000785 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000787 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
788 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000789
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000790 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000791 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000792 resume_threads.erase(this_thread_pos);
793 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000794 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
795 else
796 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000797
798 const bool override_suspend = true;
799 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 }
801 else
802 {
803 thread->SetResumeState (eStateSuspended);
804 }
805 }
Daniel Malead01b2952012-11-29 21:49:15 +0000806 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000807 }
808 }
809 else
810 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000811 // These two lines appear at the beginning of both blocks in
812 // this if..else, but that is because we need to release the
813 // lock before calling process->Resume below.
814 Mutex::Locker locker (process->GetThreadList().GetMutex());
815 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000816 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817 if (current_thread == NULL)
818 {
819 result.AppendError ("the process doesn't have a current thread");
820 result.SetStatus (eReturnStatusFailed);
821 return false;
822 }
823 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000824 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000826 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000827 if (thread == current_thread)
828 {
Daniel Malead01b2952012-11-29 21:49:15 +0000829 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000830 const bool override_suspend = true;
831 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832 }
833 else
834 {
835 thread->SetResumeState (eStateSuspended);
836 }
837 }
838 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000839
840 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841 Error error (process->Resume());
842 if (error.Success())
843 {
Daniel Malead01b2952012-11-29 21:49:15 +0000844 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845 if (synchronous_execution)
846 {
Greg Claytonb1320972010-07-14 00:18:15 +0000847 state = process->WaitForProcessToStop (NULL);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000848
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000849 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +0000850 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851 result.SetStatus (eReturnStatusSuccessFinishNoResult);
852 }
853 else
854 {
855 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
856 }
857 }
858 else
859 {
860 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
861 result.SetStatus (eReturnStatusFailed);
862 }
863 }
864 else
865 {
866 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
867 StateAsCString(state));
868 result.SetStatus (eReturnStatusFailed);
869 }
870
871 return result.Succeeded();
872 }
873
874};
875
876//-------------------------------------------------------------------------
877// CommandObjectThreadUntil
878//-------------------------------------------------------------------------
879
Jim Ingham5a988412012-06-08 21:56:10 +0000880class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000881{
882public:
883
884 class CommandOptions : public Options
885 {
886 public:
887 uint32_t m_thread_idx;
888 uint32_t m_frame_idx;
889
Greg Claytoneb0103f2011-04-07 22:46:35 +0000890 CommandOptions (CommandInterpreter &interpreter) :
891 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 m_thread_idx(LLDB_INVALID_THREAD_ID),
893 m_frame_idx(LLDB_INVALID_FRAME_ID)
894 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000895 // Keep default values of all options in one place: OptionParsingStarting ()
896 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000897 }
898
899 virtual
900 ~CommandOptions ()
901 {
902 }
903
904 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000905 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906 {
907 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000908 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000909
910 switch (short_option)
911 {
912 case 't':
913 {
Greg Claytonb1320972010-07-14 00:18:15 +0000914 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000915 if (m_thread_idx == LLDB_INVALID_INDEX32)
916 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000917 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000918 }
919 }
920 break;
921 case 'f':
922 {
923 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
924 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
925 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000926 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000927 }
928 }
929 break;
930 case 'm':
931 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000933 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000935 if (error.Success())
936 {
937 if (run_mode == eAllThreads)
938 m_stop_others = false;
939 else
940 m_stop_others = true;
941 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000942 }
943 break;
944 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000945 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946 break;
947
948 }
949 return error;
950 }
951
952 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000953 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955 m_thread_idx = LLDB_INVALID_THREAD_ID;
956 m_frame_idx = 0;
957 m_stop_others = false;
958 }
959
Greg Claytone0d378b2011-03-24 21:19:54 +0000960 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961 GetDefinitions ()
962 {
963 return g_option_table;
964 }
965
966 uint32_t m_step_thread_idx;
967 bool m_stop_others;
968
969 // Options table: Required for subclasses of Options.
970
Greg Claytone0d378b2011-03-24 21:19:54 +0000971 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972
973 // Instance variables to hold the values for command options.
974 };
975
Greg Claytona7015092010-09-18 01:14:36 +0000976 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000977 CommandObjectParsed (interpreter,
978 "thread until",
979 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
980 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000981 eFlagRequiresThread |
982 eFlagTryTargetAPILock |
983 eFlagProcessMustBeLaunched |
984 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000985 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000986 {
Caroline Tice405fe672010-10-04 22:28:36 +0000987 CommandArgumentEntry arg;
988 CommandArgumentData line_num_arg;
989
990 // Define the first (and only) variant of this arg.
991 line_num_arg.arg_type = eArgTypeLineNum;
992 line_num_arg.arg_repetition = eArgRepeatPlain;
993
994 // There is only one variant this argument could be; put it into the argument entry.
995 arg.push_back (line_num_arg);
996
997 // Push the data for the first argument into the m_arguments vector.
998 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000999 }
1000
1001
1002 virtual
1003 ~CommandObjectThreadUntil ()
1004 {
1005 }
1006
1007 virtual
1008 Options *
1009 GetOptions ()
1010 {
1011 return &m_options;
1012 }
1013
Jim Ingham5a988412012-06-08 21:56:10 +00001014protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001016 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 {
Greg Claytona7015092010-09-18 01:14:36 +00001018 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019
Greg Claytona7015092010-09-18 01:14:36 +00001020 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +00001021 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001023 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001024 result.SetStatus (eReturnStatusFailed);
1025 return false;
1026 }
1027
Greg Claytonf9fc6092013-01-09 19:44:40 +00001028 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 if (process == NULL)
1030 {
1031 result.AppendError ("need a valid process to step");
1032 result.SetStatus (eReturnStatusFailed);
1033
1034 }
1035 else
1036 {
1037 Thread *thread = NULL;
1038 uint32_t line_number;
1039
1040 if (command.GetArgumentCount() != 1)
1041 {
1042 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1043 result.SetStatus (eReturnStatusFailed);
1044 return false;
1045 }
1046
1047 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1048 if (line_number == UINT32_MAX)
1049 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001050 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051 result.SetStatus (eReturnStatusFailed);
1052 return false;
1053 }
1054
1055 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1056 {
Jim Ingham2976d002010-08-26 21:32:51 +00001057 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001058 }
1059 else
1060 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001061 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062 }
1063
1064 if (thread == NULL)
1065 {
1066 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001067 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1068 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001069 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070 result.SetStatus (eReturnStatusFailed);
1071 return false;
1072 }
1073
Jim Ingham7ba6e992012-05-11 23:47:32 +00001074 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001075
Jason Molendab57e4a12013-11-04 09:33:30 +00001076 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077 if (frame == NULL)
1078 {
1079
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001080 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1081 m_options.m_frame_idx,
1082 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083 result.SetStatus (eReturnStatusFailed);
1084 return false;
1085 }
1086
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001087 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001088
1089 if (frame->HasDebugInformation ())
1090 {
1091 // Finally we got here... Translate the given line number to a bunch of addresses:
1092 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1093 LineTable *line_table = NULL;
1094 if (sc.comp_unit)
1095 line_table = sc.comp_unit->GetLineTable();
1096
1097 if (line_table == NULL)
1098 {
1099 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1100 m_options.m_frame_idx, m_options.m_thread_idx);
1101 result.SetStatus (eReturnStatusFailed);
1102 return false;
1103 }
1104
1105 LineEntry function_start;
1106 uint32_t index_ptr = 0, end_ptr;
1107 std::vector<addr_t> address_list;
1108
1109 // Find the beginning & end index of the
1110 AddressRange fun_addr_range = sc.function->GetAddressRange();
1111 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1112 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1113
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001114 Address fun_end_addr(fun_start_addr.GetSection(),
1115 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1117
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001118 bool all_in_function = true;
1119
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001120 while (index_ptr <= end_ptr)
1121 {
1122 LineEntry line_entry;
Jim Ingham87df91b2011-09-23 00:54:11 +00001123 const bool exact = false;
1124 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125 if (index_ptr == UINT32_MAX)
1126 break;
1127
Greg Claytonf5e56de2010-09-14 23:36:40 +00001128 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129 if (address != LLDB_INVALID_ADDRESS)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001130 {
1131 if (fun_addr_range.ContainsLoadAddress (address, target))
1132 address_list.push_back (address);
1133 else
1134 all_in_function = false;
1135 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136 index_ptr++;
1137 }
1138
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001139 if (address_list.size() == 0)
1140 {
1141 if (all_in_function)
1142 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1143 else
1144 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1145
1146 result.SetStatus (eReturnStatusFailed);
1147 return false;
1148 }
1149
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001150 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001151 &address_list.front(),
1152 address_list.size(),
1153 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001154 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001155 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1156 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1157 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001158 new_plan_sp->SetIsMasterPlan (true);
1159 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001160 }
1161 else
1162 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001163 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1164 m_options.m_frame_idx,
1165 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 result.SetStatus (eReturnStatusFailed);
1167 return false;
1168
1169 }
1170
Jim Ingham2976d002010-08-26 21:32:51 +00001171 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 Error error (process->Resume ());
1173 if (error.Success())
1174 {
Daniel Malead01b2952012-11-29 21:49:15 +00001175 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001176 if (synchronous_execution)
1177 {
1178 StateType state = process->WaitForProcessToStop (NULL);
1179
1180 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +00001181 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1183 }
1184 else
1185 {
1186 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1187 }
1188 }
1189 else
1190 {
1191 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1192 result.SetStatus (eReturnStatusFailed);
1193 }
1194
1195 }
1196 return result.Succeeded();
1197 }
Jim Ingham5a988412012-06-08 21:56:10 +00001198
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199 CommandOptions m_options;
1200
1201};
1202
Greg Claytone0d378b2011-03-24 21:19:54 +00001203OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001204CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1205{
Virgile Belloe2607b52013-09-05 16:42:23 +00001206{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1207{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1208{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
Caroline Ticedeaab222010-10-01 19:59:14 +00001209{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001210};
1211
1212
1213//-------------------------------------------------------------------------
1214// CommandObjectThreadSelect
1215//-------------------------------------------------------------------------
1216
Jim Ingham5a988412012-06-08 21:56:10 +00001217class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001218{
1219public:
1220
Greg Claytona7015092010-09-18 01:14:36 +00001221 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001222 CommandObjectParsed (interpreter,
1223 "thread select",
1224 "Select a thread as the currently active thread.",
1225 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001226 eFlagRequiresProcess |
1227 eFlagTryTargetAPILock |
1228 eFlagProcessMustBeLaunched |
1229 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230 {
Caroline Tice405fe672010-10-04 22:28:36 +00001231 CommandArgumentEntry arg;
1232 CommandArgumentData thread_idx_arg;
1233
1234 // Define the first (and only) variant of this arg.
1235 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1236 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1237
1238 // There is only one variant this argument could be; put it into the argument entry.
1239 arg.push_back (thread_idx_arg);
1240
1241 // Push the data for the first argument into the m_arguments vector.
1242 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001243 }
1244
1245
1246 virtual
1247 ~CommandObjectThreadSelect ()
1248 {
1249 }
1250
Jim Ingham5a988412012-06-08 21:56:10 +00001251protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001252 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001253 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001254 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001255 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001256 if (process == NULL)
1257 {
1258 result.AppendError ("no process");
1259 result.SetStatus (eReturnStatusFailed);
1260 return false;
1261 }
1262 else if (command.GetArgumentCount() != 1)
1263 {
Jason Molendafd54b362011-09-20 21:44:10 +00001264 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 +00001265 result.SetStatus (eReturnStatusFailed);
1266 return false;
1267 }
1268
1269 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1270
1271 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1272 if (new_thread == NULL)
1273 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001274 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275 result.SetStatus (eReturnStatusFailed);
1276 return false;
1277 }
1278
Jim Inghamc3faa192012-12-11 02:31:48 +00001279 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001280 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001282 return result.Succeeded();
1283 }
1284
1285};
1286
1287
1288//-------------------------------------------------------------------------
1289// CommandObjectThreadList
1290//-------------------------------------------------------------------------
1291
Jim Ingham5a988412012-06-08 21:56:10 +00001292class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001293{
Greg Clayton66111032010-06-23 01:19:29 +00001294public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296
Greg Claytona7015092010-09-18 01:14:36 +00001297 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001298 CommandObjectParsed (interpreter,
1299 "thread list",
1300 "Show a summary of all current threads in a process.",
1301 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001302 eFlagRequiresProcess |
1303 eFlagTryTargetAPILock |
1304 eFlagProcessMustBeLaunched |
1305 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001306 {
Greg Clayton66111032010-06-23 01:19:29 +00001307 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001308
Greg Clayton66111032010-06-23 01:19:29 +00001309 ~CommandObjectThreadList()
1310 {
1311 }
1312
Jim Ingham5a988412012-06-08 21:56:10 +00001313protected:
Greg Clayton66111032010-06-23 01:19:29 +00001314 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001315 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001316 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001317 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001318 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001319 Process *process = m_exe_ctx.GetProcessPtr();
1320 const bool only_threads_with_stop_reason = false;
1321 const uint32_t start_frame = 0;
1322 const uint32_t num_frames = 0;
1323 const uint32_t num_frames_with_source = 0;
1324 process->GetStatus(strm);
1325 process->GetThreadStatus (strm,
1326 only_threads_with_stop_reason,
1327 start_frame,
1328 num_frames,
1329 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001330 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001331 }
Greg Clayton66111032010-06-23 01:19:29 +00001332};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001333
Jim Ingham93208b82013-01-31 21:46:01 +00001334//-------------------------------------------------------------------------
1335// CommandObjectThreadReturn
1336//-------------------------------------------------------------------------
1337
Jim Inghamcb640dd2012-09-14 02:14:15 +00001338class CommandObjectThreadReturn : public CommandObjectRaw
1339{
1340public:
Jim Ingham93208b82013-01-31 21:46:01 +00001341 class CommandOptions : public Options
1342 {
1343 public:
1344
1345 CommandOptions (CommandInterpreter &interpreter) :
1346 Options (interpreter),
1347 m_from_expression (false)
1348 {
1349 // Keep default values of all options in one place: OptionParsingStarting ()
1350 OptionParsingStarting ();
1351 }
1352
1353 virtual
1354 ~CommandOptions ()
1355 {
1356 }
1357
1358 virtual Error
1359 SetOptionValue (uint32_t option_idx, const char *option_arg)
1360 {
1361 Error error;
1362 const int short_option = m_getopt_table[option_idx].val;
1363
1364 switch (short_option)
1365 {
1366 case 'x':
1367 {
1368 bool success;
1369 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1370 if (success)
1371 m_from_expression = tmp_value;
1372 else
1373 {
1374 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1375 }
1376 }
1377 break;
1378 default:
1379 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1380 break;
1381
1382 }
1383 return error;
1384 }
1385
1386 void
1387 OptionParsingStarting ()
1388 {
1389 m_from_expression = false;
1390 }
1391
1392 const OptionDefinition*
1393 GetDefinitions ()
1394 {
1395 return g_option_table;
1396 }
1397
1398 bool m_from_expression;
1399
1400 // Options table: Required for subclasses of Options.
1401
1402 static OptionDefinition g_option_table[];
1403
1404 // Instance variables to hold the values for command options.
1405 };
1406
1407 virtual
1408 Options *
1409 GetOptions ()
1410 {
1411 return &m_options;
1412 }
1413
Jim Inghamcb640dd2012-09-14 02:14:15 +00001414 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1415 CommandObjectRaw (interpreter,
1416 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001417 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1418 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001419 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001420 eFlagRequiresFrame |
1421 eFlagTryTargetAPILock |
1422 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001423 eFlagProcessMustBePaused ),
1424 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001425 {
1426 CommandArgumentEntry arg;
1427 CommandArgumentData expression_arg;
1428
1429 // Define the first (and only) variant of this arg.
1430 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001431 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001432
1433 // There is only one variant this argument could be; put it into the argument entry.
1434 arg.push_back (expression_arg);
1435
1436 // Push the data for the first argument into the m_arguments vector.
1437 m_arguments.push_back (arg);
1438
1439
1440 }
1441
1442 ~CommandObjectThreadReturn()
1443 {
1444 }
1445
1446protected:
1447
1448 bool DoExecute
1449 (
1450 const char *command,
1451 CommandReturnObject &result
1452 )
1453 {
Jim Ingham93208b82013-01-31 21:46:01 +00001454 // I am going to handle this by hand, because I don't want you to have to say:
1455 // "thread return -- -5".
1456 if (command[0] == '-' && command[1] == 'x')
1457 {
1458 if (command && command[2] != '\0')
1459 result.AppendWarning("Return values ignored when returning from user called expressions");
1460
1461 Thread *thread = m_exe_ctx.GetThreadPtr();
1462 Error error;
1463 error = thread->UnwindInnermostExpression();
1464 if (!error.Success())
1465 {
1466 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1467 result.SetStatus (eReturnStatusFailed);
1468 }
1469 else
1470 {
1471 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1472 if (success)
1473 {
1474 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1475 result.SetStatus (eReturnStatusSuccessFinishResult);
1476 }
1477 else
1478 {
1479 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1480 result.SetStatus (eReturnStatusFailed);
1481 }
1482 }
1483 return result.Succeeded();
1484 }
1485
Jim Inghamcb640dd2012-09-14 02:14:15 +00001486 ValueObjectSP return_valobj_sp;
1487
Jason Molendab57e4a12013-11-04 09:33:30 +00001488 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001489 uint32_t frame_idx = frame_sp->GetFrameIndex();
1490
1491 if (frame_sp->IsInlined())
1492 {
1493 result.AppendError("Don't know how to return from inlined frames.");
1494 result.SetStatus (eReturnStatusFailed);
1495 return false;
1496 }
1497
1498 if (command && command[0] != '\0')
1499 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001500 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001501 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001502
1503 options.SetUnwindOnError(true);
1504 options.SetUseDynamic(eNoDynamicValues);
1505
Jim Ingham8646d3c2014-05-05 02:47:44 +00001506 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001507 exe_results = target->EvaluateExpression (command,
1508 frame_sp.get(),
1509 return_valobj_sp,
1510 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001511 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001512 {
1513 if (return_valobj_sp)
1514 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1515 else
1516 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1517 result.SetStatus (eReturnStatusFailed);
1518 return false;
1519
1520 }
1521 }
1522
1523 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001524 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001525 const bool broadcast = true;
1526 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001527 if (!error.Success())
1528 {
1529 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1530 result.SetStatus (eReturnStatusFailed);
1531 return false;
1532 }
1533
Jim Inghamcb640dd2012-09-14 02:14:15 +00001534 result.SetStatus (eReturnStatusSuccessFinishResult);
1535 return true;
1536 }
Jim Ingham93208b82013-01-31 21:46:01 +00001537
1538 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001539
1540};
Jim Ingham93208b82013-01-31 21:46:01 +00001541OptionDefinition
1542CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1543{
Virgile Belloe2607b52013-09-05 16:42:23 +00001544{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
Jim Ingham93208b82013-01-31 21:46:01 +00001545{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1546};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001547
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001548//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001549// CommandObjectThreadJump
1550//-------------------------------------------------------------------------
1551
1552class CommandObjectThreadJump : public CommandObjectParsed
1553{
1554public:
1555 class CommandOptions : public Options
1556 {
1557 public:
1558
1559 CommandOptions (CommandInterpreter &interpreter) :
1560 Options (interpreter)
1561 {
1562 OptionParsingStarting ();
1563 }
1564
1565 void
1566 OptionParsingStarting ()
1567 {
1568 m_filenames.Clear();
1569 m_line_num = 0;
1570 m_line_offset = 0;
1571 m_load_addr = LLDB_INVALID_ADDRESS;
1572 m_force = false;
1573 }
1574
1575 virtual
1576 ~CommandOptions ()
1577 {
1578 }
1579
1580 virtual Error
1581 SetOptionValue (uint32_t option_idx, const char *option_arg)
1582 {
1583 bool success;
1584 const int short_option = m_getopt_table[option_idx].val;
1585 Error error;
1586
1587 switch (short_option)
1588 {
1589 case 'f':
1590 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1591 if (m_filenames.GetSize() > 1)
1592 return Error("only one source file expected.");
1593 break;
1594 case 'l':
1595 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1596 if (!success || m_line_num == 0)
1597 return Error("invalid line number: '%s'.", option_arg);
1598 break;
1599 case 'b':
1600 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1601 if (!success)
1602 return Error("invalid line offset: '%s'.", option_arg);
1603 break;
1604 case 'a':
1605 {
1606 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1607 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1608 }
1609 break;
1610 case 'r':
1611 m_force = true;
1612 break;
1613
1614 default:
1615 return Error("invalid short option character '%c'", short_option);
1616
1617 }
1618 return error;
1619 }
1620
1621 const OptionDefinition*
1622 GetDefinitions ()
1623 {
1624 return g_option_table;
1625 }
1626
1627 FileSpecList m_filenames;
1628 uint32_t m_line_num;
1629 int32_t m_line_offset;
1630 lldb::addr_t m_load_addr;
1631 bool m_force;
1632
1633 static OptionDefinition g_option_table[];
1634 };
1635
1636 virtual
1637 Options *
1638 GetOptions ()
1639 {
1640 return &m_options;
1641 }
1642
1643 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1644 CommandObjectParsed (interpreter,
1645 "thread jump",
1646 "Sets the program counter to a new address.",
1647 "thread jump",
1648 eFlagRequiresFrame |
1649 eFlagTryTargetAPILock |
1650 eFlagProcessMustBeLaunched |
1651 eFlagProcessMustBePaused ),
1652 m_options (interpreter)
1653 {
1654 }
1655
1656 ~CommandObjectThreadJump()
1657 {
1658 }
1659
1660protected:
1661
1662 bool DoExecute (Args& args, CommandReturnObject &result)
1663 {
1664 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001665 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001666 Thread *thread = m_exe_ctx.GetThreadPtr();
1667 Target *target = m_exe_ctx.GetTargetPtr();
1668 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1669
1670 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1671 {
1672 // Use this address directly.
1673 Address dest = Address(m_options.m_load_addr);
1674
1675 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1676 if (callAddr == LLDB_INVALID_ADDRESS)
1677 {
1678 result.AppendErrorWithFormat ("Invalid destination address.");
1679 result.SetStatus (eReturnStatusFailed);
1680 return false;
1681 }
1682
1683 if (!reg_ctx->SetPC (callAddr))
1684 {
1685 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1686 result.SetStatus (eReturnStatusFailed);
1687 return false;
1688 }
1689 }
1690 else
1691 {
1692 // Pick either the absolute line, or work out a relative one.
1693 int32_t line = (int32_t)m_options.m_line_num;
1694 if (line == 0)
1695 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1696
1697 // Try the current file, but override if asked.
1698 FileSpec file = sym_ctx.line_entry.file;
1699 if (m_options.m_filenames.GetSize() == 1)
1700 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1701
1702 if (!file)
1703 {
1704 result.AppendErrorWithFormat ("No source file available for the current location.");
1705 result.SetStatus (eReturnStatusFailed);
1706 return false;
1707 }
1708
1709 std::string warnings;
1710 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1711
1712 if (err.Fail())
1713 {
1714 result.SetError (err);
1715 return false;
1716 }
1717
1718 if (!warnings.empty())
1719 result.AppendWarning (warnings.c_str());
1720 }
1721
1722 result.SetStatus (eReturnStatusSuccessFinishResult);
1723 return true;
1724 }
1725
1726 CommandOptions m_options;
1727};
1728OptionDefinition
1729CommandObjectThreadJump::CommandOptions::g_option_table[] =
1730{
1731 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1732 "Specifies the source file to jump to."},
1733
1734 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
1735 "Specifies the line number to jump to."},
1736
1737 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset,
1738 "Jumps by a relative line offset from the current line."},
1739
1740 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression,
1741 "Jumps to a specific address."},
1742
1743 { LLDB_OPT_SET_1|
1744 LLDB_OPT_SET_2|
1745 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
1746
1747 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1748};
1749
1750//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001751// CommandObjectMultiwordThread
1752//-------------------------------------------------------------------------
1753
Greg Clayton66111032010-06-23 01:19:29 +00001754CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001755 CommandObjectMultiword (interpreter,
1756 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001757 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001758 "thread <subcommand> [<subcommand-options>]")
1759{
Greg Claytona7015092010-09-18 01:14:36 +00001760 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1761 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1762 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00001763 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00001764 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001765 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1766 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1767 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1768 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00001769 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00001770 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001771 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001772 eStepTypeInto,
1773 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00001774
Greg Claytona7015092010-09-18 01:14:36 +00001775 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1776 interpreter,
1777 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00001778 "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 +00001779 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001780 eStepTypeOut,
1781 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001782
Greg Claytona7015092010-09-18 01:14:36 +00001783 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1784 interpreter,
1785 "thread step-over",
1786 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001787 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001788 eStepTypeOver,
1789 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001790
Greg Claytona7015092010-09-18 01:14:36 +00001791 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1792 interpreter,
1793 "thread step-inst",
1794 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001795 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001796 eStepTypeTrace,
1797 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00001798
Greg Claytona7015092010-09-18 01:14:36 +00001799 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1800 interpreter,
1801 "thread step-inst-over",
1802 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001803 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001804 eStepTypeTraceOver,
1805 eStepScopeInstruction)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001806}
1807
1808CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1809{
1810}
1811
1812