blob: a2c3e6a3429daf6c4e962e2b95f2016882fc2eb3 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectThread.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Jim Inghamf59388a2012-09-14 02:14:15 +000016#include "lldb/lldb-private.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/State.h"
18#include "lldb/Core/SourceManager.h"
Greg Claytoncd548032011-02-01 01:31:41 +000019#include "lldb/Host/Host.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Interpreter/CommandInterpreter.h"
21#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000022#include "lldb/Interpreter/Options.h"
23#include "lldb/Symbol/CompileUnit.h"
24#include "lldb/Symbol/Function.h"
25#include "lldb/Symbol/LineTable.h"
26#include "lldb/Symbol/LineEntry.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Target/Process.h"
28#include "lldb/Target/RegisterContext.h"
29#include "lldb/Target/Target.h"
30#include "lldb/Target/Thread.h"
31#include "lldb/Target/ThreadPlan.h"
Chris Lattner24943d22010-06-08 16:52:24 +000032#include "lldb/Target/ThreadPlanStepInstruction.h"
33#include "lldb/Target/ThreadPlanStepOut.h"
34#include "lldb/Target/ThreadPlanStepRange.h"
35#include "lldb/Target/ThreadPlanStepInRange.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000036
Chris Lattner24943d22010-06-08 16:52:24 +000037
38using namespace lldb;
39using namespace lldb_private;
40
41
Chris Lattner24943d22010-06-08 16:52:24 +000042//-------------------------------------------------------------------------
43// CommandObjectThreadBacktrace
44//-------------------------------------------------------------------------
45
Jim Inghamda26bd22012-06-08 21:56:10 +000046class CommandObjectThreadBacktrace : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +000047{
48public:
49
Jim Ingham8ab1a802010-08-26 23:36:03 +000050 class CommandOptions : public Options
51 {
52 public:
53
Greg Claytonf15996e2011-04-07 22:46:35 +000054 CommandOptions (CommandInterpreter &interpreter) :
55 Options(interpreter)
Jim Ingham8ab1a802010-08-26 23:36:03 +000056 {
Greg Clayton143fcc32011-04-13 00:18:08 +000057 // Keep default values of all options in one place: OptionParsingStarting ()
58 OptionParsingStarting ();
Jim Ingham8ab1a802010-08-26 23:36:03 +000059 }
60
61 virtual
62 ~CommandOptions ()
63 {
64 }
65
66 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +000067 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham8ab1a802010-08-26 23:36:03 +000068 {
69 Error error;
70 char short_option = (char) m_getopt_table[option_idx].val;
71
72 switch (short_option)
73 {
74 case 'c':
75 {
76 bool success;
77 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
78 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000079 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000080 if (input_count < -1)
81 m_count = UINT32_MAX;
82 else
83 m_count = input_count;
84 }
85 break;
86 case 's':
87 {
88 bool success;
89 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
90 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000091 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000092 }
93 break;
94 default:
Greg Clayton9c236732011-10-26 00:56:27 +000095 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000096 break;
97
98 }
99 return error;
100 }
101
102 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000103 OptionParsingStarting ()
Jim Ingham8ab1a802010-08-26 23:36:03 +0000104 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000105 m_count = UINT32_MAX;
Jim Ingham8ab1a802010-08-26 23:36:03 +0000106 m_start = 0;
107 }
108
Greg Claytonb3448432011-03-24 21:19:54 +0000109 const OptionDefinition*
Jim Ingham8ab1a802010-08-26 23:36:03 +0000110 GetDefinitions ()
111 {
112 return g_option_table;
113 }
114
115 // Options table: Required for subclasses of Options.
116
Greg Claytonb3448432011-03-24 21:19:54 +0000117 static OptionDefinition g_option_table[];
Jim Ingham8ab1a802010-08-26 23:36:03 +0000118
119 // Instance variables to hold the values for command options.
120 uint32_t m_count;
121 uint32_t m_start;
122 };
123
Greg Clayton238c0a12010-09-18 01:14:36 +0000124 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000125 CommandObjectParsed (interpreter,
126 "thread backtrace",
127 "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.",
128 NULL,
129 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000130 m_options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000131 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000132 CommandArgumentEntry arg;
133 CommandArgumentData thread_idx_arg;
134
135 // Define the first (and only) variant of this arg.
136 thread_idx_arg.arg_type = eArgTypeThreadIndex;
137 thread_idx_arg.arg_repetition = eArgRepeatStar;
138
139 // There is only one variant this argument could be; put it into the argument entry.
140 arg.push_back (thread_idx_arg);
141
142 // Push the data for the first argument into the m_arguments vector.
143 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000144 }
145
146 ~CommandObjectThreadBacktrace()
147 {
148 }
149
Jim Ingham8ab1a802010-08-26 23:36:03 +0000150 virtual Options *
151 GetOptions ()
152 {
153 return &m_options;
154 }
Chris Lattner24943d22010-06-08 16:52:24 +0000155
Jim Inghamda26bd22012-06-08 21:56:10 +0000156protected:
Greg Clayton63094e02010-06-23 01:19:29 +0000157 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000158 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000159 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000160 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000161 Stream &strm = result.GetOutputStream();
162
163 // Don't show source context when doing backtraces.
164 const uint32_t num_frames_with_source = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000165 if (command.GetArgumentCount() == 0)
166 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000167 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000168 Thread *thread = exe_ctx.GetThreadPtr();
169 if (thread)
Chris Lattner24943d22010-06-08 16:52:24 +0000170 {
Johnny Chen2d268cb2011-06-02 18:02:15 +0000171 // Thread::GetStatus() returns the number of frames shown.
Greg Clayton567e7f32011-09-22 04:58:26 +0000172 if (thread->GetStatus (strm,
173 m_options.m_start,
174 m_options.m_count,
175 num_frames_with_source))
Chris Lattner24943d22010-06-08 16:52:24 +0000176 {
177 result.SetStatus (eReturnStatusSuccessFinishResult);
178 }
179 }
180 else
181 {
182 result.AppendError ("invalid thread");
183 result.SetStatus (eReturnStatusFailed);
184 }
185 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000186 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
187 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000188 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghamb9950592012-09-10 20:50:15 +0000189 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Inghameb10f7b2010-08-27 00:58:05 +0000190 uint32_t num_threads = process->GetThreadList().GetSize();
191 for (uint32_t i = 0; i < num_threads; i++)
192 {
193 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
Johnny Chen05750a62011-06-01 23:19:52 +0000194 if (!thread_sp->GetStatus (strm,
195 m_options.m_start,
196 m_options.m_count,
197 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000198 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000199 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
Jim Inghameb10f7b2010-08-27 00:58:05 +0000200 result.SetStatus (eReturnStatusFailed);
201 return false;
202 }
Jim Ingham7868bcc2011-07-26 02:39:59 +0000203
204 if (i < num_threads - 1)
205 result.AppendMessage("");
206
Jim Inghameb10f7b2010-08-27 00:58:05 +0000207 }
208 }
Chris Lattner24943d22010-06-08 16:52:24 +0000209 else
210 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000211 uint32_t num_args = command.GetArgumentCount();
Greg Clayton567e7f32011-09-22 04:58:26 +0000212 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghamb9950592012-09-10 20:50:15 +0000213 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Inghameb10f7b2010-08-27 00:58:05 +0000214 std::vector<ThreadSP> thread_sps;
215
216 for (uint32_t i = 0; i < num_args; i++)
217 {
218 bool success;
219
220 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
221 if (!success)
222 {
223 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
224 result.SetStatus (eReturnStatusFailed);
225 return false;
226 }
227
228 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
229
230 if (!thread_sps[i])
231 {
232 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
233 result.SetStatus (eReturnStatusFailed);
234 return false;
235 }
236
237 }
238
239 for (uint32_t i = 0; i < num_args; i++)
240 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000241 if (!thread_sps[i]->GetStatus (strm,
242 m_options.m_start,
243 m_options.m_count,
244 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000245 {
246 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
247 result.SetStatus (eReturnStatusFailed);
248 return false;
249 }
250
251 if (i < num_args - 1)
252 result.AppendMessage("");
253 }
Chris Lattner24943d22010-06-08 16:52:24 +0000254 }
255 return result.Succeeded();
256 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000257
Jim Ingham8ab1a802010-08-26 23:36:03 +0000258 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000259};
260
Greg Claytonb3448432011-03-24 21:19:54 +0000261OptionDefinition
Jim Ingham8ab1a802010-08-26 23:36:03 +0000262CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
263{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000264{ LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
Caroline Tice43b014a2010-10-04 22:28:36 +0000265{ LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
Caroline Tice4d6675c2010-10-01 19:59:14 +0000266{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham8ab1a802010-08-26 23:36:03 +0000267};
Chris Lattner24943d22010-06-08 16:52:24 +0000268
Greg Claytonc0418152010-07-07 17:07:17 +0000269enum StepScope
Chris Lattner24943d22010-06-08 16:52:24 +0000270{
271 eStepScopeSource,
272 eStepScopeInstruction
273};
274
Jim Inghamda26bd22012-06-08 21:56:10 +0000275class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000276{
277public:
278
279 class CommandOptions : public Options
280 {
281 public:
282
Greg Claytonf15996e2011-04-07 22:46:35 +0000283 CommandOptions (CommandInterpreter &interpreter) :
284 Options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000285 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000286 // Keep default values of all options in one place: OptionParsingStarting ()
287 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000288 }
289
290 virtual
291 ~CommandOptions ()
292 {
293 }
294
295 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000296 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000297 {
298 Error error;
299 char short_option = (char) m_getopt_table[option_idx].val;
300
301 switch (short_option)
302 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000303 case 'a':
Chris Lattner24943d22010-06-08 16:52:24 +0000304 {
305 bool success;
306 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
307 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000308 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000309 }
310 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000311
312 case 'm':
Chris Lattner24943d22010-06-08 16:52:24 +0000313 {
Chris Lattner24943d22010-06-08 16:52:24 +0000314 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000315 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000316 }
317 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000318
319 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000320 {
321 m_avoid_regexp.clear();
322 m_avoid_regexp.assign(option_arg);
323 }
324 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000325
326 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000327 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8d3802d2010-10-08 04:20:14 +0000328 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000329
330 }
331 return error;
332 }
333
334 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000335 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000336 {
Chris Lattner24943d22010-06-08 16:52:24 +0000337 m_avoid_no_debug = true;
338 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000339 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000340 }
341
Greg Claytonb3448432011-03-24 21:19:54 +0000342 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000343 GetDefinitions ()
344 {
345 return g_option_table;
346 }
347
348 // Options table: Required for subclasses of Options.
349
Greg Claytonb3448432011-03-24 21:19:54 +0000350 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000351
352 // Instance variables to hold the values for command options.
353 bool m_avoid_no_debug;
354 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000355 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000356 };
357
Greg Clayton238c0a12010-09-18 01:14:36 +0000358 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
359 const char *name,
360 const char *help,
361 const char *syntax,
362 uint32_t flags,
363 StepType step_type,
364 StepScope step_scope) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000365 CommandObjectParsed (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000366 m_step_type (step_type),
367 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000368 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000369 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000370 CommandArgumentEntry arg;
371 CommandArgumentData thread_id_arg;
372
373 // Define the first (and only) variant of this arg.
374 thread_id_arg.arg_type = eArgTypeThreadID;
375 thread_id_arg.arg_repetition = eArgRepeatOptional;
376
377 // There is only one variant this argument could be; put it into the argument entry.
378 arg.push_back (thread_id_arg);
379
380 // Push the data for the first argument into the m_arguments vector.
381 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000382 }
383
384 virtual
385 ~CommandObjectThreadStepWithTypeAndScope ()
386 {
387 }
388
389 virtual
390 Options *
391 GetOptions ()
392 {
393 return &m_options;
394 }
395
Jim Inghamda26bd22012-06-08 21:56:10 +0000396protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000397 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000398 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000399 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000400 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton238c0a12010-09-18 01:14:36 +0000401 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000402
403 if (process == NULL)
404 {
405 result.AppendError ("need a valid process to step");
406 result.SetStatus (eReturnStatusFailed);
407
408 }
409 else
410 {
411 const uint32_t num_threads = process->GetThreadList().GetSize();
412 Thread *thread = NULL;
413
414 if (command.GetArgumentCount() == 0)
415 {
Jim Inghamc8332952010-08-26 21:32:51 +0000416 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000417 if (thread == NULL)
418 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000419 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000420 result.SetStatus (eReturnStatusFailed);
421 return false;
422 }
423 }
424 else
425 {
426 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
427 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
428 if (step_thread_idx == LLDB_INVALID_INDEX32)
429 {
Greg Clayton9c236732011-10-26 00:56:27 +0000430 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +0000431 result.SetStatus (eReturnStatusFailed);
432 return false;
433 }
434 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
435 if (thread == NULL)
436 {
437 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000438 step_thread_idx, num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000439 result.SetStatus (eReturnStatusFailed);
440 return false;
441 }
442 }
443
444 const bool abort_other_plans = false;
445 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
446
447 // This is a bit unfortunate, but not all the commands in this command object support
448 // only while stepping, so I use the bool for them.
449 bool bool_stop_other_threads;
450 if (m_options.m_run_mode == eAllThreads)
451 bool_stop_other_threads = false;
Jim Inghambb9ce3e2012-09-14 21:04:15 +0000452 else if (m_options.m_run_mode == eOnlyDuringStepping)
453 {
454 if (m_step_type == eStepTypeOut)
455 bool_stop_other_threads = false;
456 else
457 bool_stop_other_threads = true;
458 }
Chris Lattner24943d22010-06-08 16:52:24 +0000459 else
460 bool_stop_other_threads = true;
461
Jim Ingham88e3de22012-05-03 21:19:36 +0000462 ThreadPlan *new_plan = NULL;
463
Chris Lattner24943d22010-06-08 16:52:24 +0000464 if (m_step_type == eStepTypeInto)
465 {
466 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000467
468 if (frame->HasDebugInformation ())
469 {
470 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
471 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
472 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000473 stop_other_threads,
474 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000475 if (new_plan && !m_options.m_avoid_regexp.empty())
476 {
477 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
478 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
479 }
Chris Lattner24943d22010-06-08 16:52:24 +0000480 }
481 else
482 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Ingham88e3de22012-05-03 21:19:36 +0000483
Chris Lattner24943d22010-06-08 16:52:24 +0000484 }
485 else if (m_step_type == eStepTypeOver)
486 {
487 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000488
489 if (frame->HasDebugInformation())
490 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
491 m_step_type,
492 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
493 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000494 stop_other_threads,
495 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000496 else
497 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
498 abort_other_plans,
499 bool_stop_other_threads);
500
Chris Lattner24943d22010-06-08 16:52:24 +0000501 }
502 else if (m_step_type == eStepTypeTrace)
503 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000504 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000505 }
506 else if (m_step_type == eStepTypeTraceOver)
507 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000508 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000509 }
510 else if (m_step_type == eStepTypeOut)
511 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000512 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
513 NULL,
514 false,
515 bool_stop_other_threads,
516 eVoteYes,
517 eVoteNoOpinion,
518 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000519 }
520 else
521 {
522 result.AppendError ("step type is not supported");
523 result.SetStatus (eReturnStatusFailed);
Jim Ingham88e3de22012-05-03 21:19:36 +0000524 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000525 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000526
527 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
528 // so that they can be interruptible). Then resume the process.
529
530 if (new_plan != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000531 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000532 new_plan->SetIsMasterPlan (true);
533 new_plan->SetOkayToDiscard (false);
534
Jim Inghamc8332952010-08-26 21:32:51 +0000535 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Jim Ingham88e3de22012-05-03 21:19:36 +0000536 process->Resume ();
537
538
539 if (synchronous_execution)
540 {
541 StateType state = process->WaitForProcessToStop (NULL);
542
543 //EventSP event_sp;
544 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
545 //while (! StateIsStoppedState (state))
546 // {
547 // state = process->WaitForStateChangedEvents (NULL, event_sp);
548 // }
549 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
550 result.SetDidChangeProcessState (true);
551 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
552 result.SetStatus (eReturnStatusSuccessFinishNoResult);
553 }
Jim Ingham53628e72012-05-16 00:37:40 +0000554 else
555 {
556 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
557 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000558 }
559 else
560 {
561 result.AppendError ("Couldn't find thread plan to implement step type.");
562 result.SetStatus (eReturnStatusFailed);
Chris Lattner24943d22010-06-08 16:52:24 +0000563 }
564 }
565 return result.Succeeded();
566 }
567
568protected:
569 StepType m_step_type;
570 StepScope m_step_scope;
571 CommandOptions m_options;
572};
573
Greg Claytonb3448432011-03-24 21:19:54 +0000574static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000575g_tri_running_mode[] =
576{
Greg Claytonfe424a92010-09-18 03:37:20 +0000577{ eOnlyThisThread, "this-thread", "Run only this thread"},
578{ eAllThreads, "all-threads", "Run all threads"},
579{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000580{ 0, NULL, NULL }
581};
582
Greg Claytonb3448432011-03-24 21:19:54 +0000583static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000584g_duo_running_mode[] =
585{
Greg Claytonfe424a92010-09-18 03:37:20 +0000586{ eOnlyThisThread, "this-thread", "Run only this thread"},
587{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000588{ 0, NULL, NULL }
589};
590
Greg Claytonb3448432011-03-24 21:19:54 +0000591OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000592CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
593{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000594{ LLDB_OPT_SET_1, false, "avoid-no-debug", 'a', required_argument, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether step-in will step over functions with no debug information."},
595{ LLDB_OPT_SET_1, false, "run-mode", 'm', required_argument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
596{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
597{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000598};
599
600
601//-------------------------------------------------------------------------
602// CommandObjectThreadContinue
603//-------------------------------------------------------------------------
604
Jim Inghamda26bd22012-06-08 21:56:10 +0000605class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000606{
607public:
608
Greg Clayton238c0a12010-09-18 01:14:36 +0000609 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000610 CommandObjectParsed (interpreter,
611 "thread continue",
612 "Continue execution of one or more threads in an active process.",
613 NULL,
614 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +0000615 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000616 CommandArgumentEntry arg;
617 CommandArgumentData thread_idx_arg;
618
619 // Define the first (and only) variant of this arg.
620 thread_idx_arg.arg_type = eArgTypeThreadIndex;
621 thread_idx_arg.arg_repetition = eArgRepeatPlus;
622
623 // There is only one variant this argument could be; put it into the argument entry.
624 arg.push_back (thread_idx_arg);
625
626 // Push the data for the first argument into the m_arguments vector.
627 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000628 }
629
630
631 virtual
632 ~CommandObjectThreadContinue ()
633 {
634 }
635
636 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000637 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000638 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000639 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000640
Greg Clayton238c0a12010-09-18 01:14:36 +0000641 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000642 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000643 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000644 result.SetStatus (eReturnStatusFailed);
645 return false;
646 }
647
Greg Clayton567e7f32011-09-22 04:58:26 +0000648 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000649 if (process == NULL)
650 {
651 result.AppendError ("no process exists. Cannot continue");
652 result.SetStatus (eReturnStatusFailed);
653 return false;
654 }
655
656 StateType state = process->GetState();
657 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
658 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000659 Mutex::Locker locker (process->GetThreadList().GetMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000660 const uint32_t num_threads = process->GetThreadList().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000661 const size_t argc = command.GetArgumentCount();
662 if (argc > 0)
663 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000664 std::vector<Thread *> resume_threads;
Chris Lattner24943d22010-06-08 16:52:24 +0000665 for (uint32_t i=0; i<argc; ++i)
666 {
Jim Inghamd07b4f52012-05-31 20:48:41 +0000667 bool success;
668 const int base = 0;
Greg Claytonedd601a2012-07-03 20:54:16 +0000669 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
670 if (success)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000671 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000672 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
673
674 if (thread)
675 {
676 resume_threads.push_back(thread);
677 }
678 else
679 {
680 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
681 result.SetStatus (eReturnStatusFailed);
682 return false;
683 }
Jim Inghamd07b4f52012-05-31 20:48:41 +0000684 }
Chris Lattner24943d22010-06-08 16:52:24 +0000685 else
Jim Inghamd07b4f52012-05-31 20:48:41 +0000686 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000687 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd07b4f52012-05-31 20:48:41 +0000688 result.SetStatus (eReturnStatusFailed);
689 return false;
690 }
Chris Lattner24943d22010-06-08 16:52:24 +0000691 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000692
693 if (resume_threads.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000694 {
695 result.AppendError ("no valid thread indexes were specified");
696 result.SetStatus (eReturnStatusFailed);
697 return false;
698 }
699 else
700 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000701 if (resume_threads.size() == 1)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000702 result.AppendMessageWithFormat ("Resuming thread: ");
703 else
704 result.AppendMessageWithFormat ("Resuming threads: ");
Greg Claytonedd601a2012-07-03 20:54:16 +0000705
706 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000707 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000708 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
709 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Jim Inghamd07b4f52012-05-31 20:48:41 +0000710
Greg Claytonedd601a2012-07-03 20:54:16 +0000711 if (this_thread_pos != resume_threads.end())
Chris Lattner24943d22010-06-08 16:52:24 +0000712 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000713 resume_threads.erase(this_thread_pos);
714 if (resume_threads.size() > 0)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000715 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
716 else
717 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
718
Chris Lattner24943d22010-06-08 16:52:24 +0000719 thread->SetResumeState (eStateRunning);
720 }
721 else
722 {
723 thread->SetResumeState (eStateSuspended);
724 }
725 }
Greg Clayton444e35b2011-10-19 18:09:39 +0000726 result.AppendMessageWithFormat ("in process %llu\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000727 }
728 }
729 else
730 {
Jim Inghamc8332952010-08-26 21:32:51 +0000731 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000732 if (current_thread == NULL)
733 {
734 result.AppendError ("the process doesn't have a current thread");
735 result.SetStatus (eReturnStatusFailed);
736 return false;
737 }
738 // Set the actions that the threads should each take when resuming
Greg Claytonedd601a2012-07-03 20:54:16 +0000739 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000740 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000741 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000742 if (thread == current_thread)
743 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000744 result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000745 thread->SetResumeState (eStateRunning);
746 }
747 else
748 {
749 thread->SetResumeState (eStateSuspended);
750 }
751 }
752 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000753
Chris Lattner24943d22010-06-08 16:52:24 +0000754 Error error (process->Resume());
755 if (error.Success())
756 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000757 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000758 if (synchronous_execution)
759 {
Greg Claytonbef15832010-07-14 00:18:15 +0000760 state = process->WaitForProcessToStop (NULL);
Greg Claytonedd601a2012-07-03 20:54:16 +0000761
Chris Lattner24943d22010-06-08 16:52:24 +0000762 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +0000763 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +0000764 result.SetStatus (eReturnStatusSuccessFinishNoResult);
765 }
766 else
767 {
768 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
769 }
770 }
771 else
772 {
773 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
774 result.SetStatus (eReturnStatusFailed);
775 }
776 }
777 else
778 {
779 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
780 StateAsCString(state));
781 result.SetStatus (eReturnStatusFailed);
782 }
783
784 return result.Succeeded();
785 }
786
787};
788
789//-------------------------------------------------------------------------
790// CommandObjectThreadUntil
791//-------------------------------------------------------------------------
792
Jim Inghamda26bd22012-06-08 21:56:10 +0000793class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000794{
795public:
796
797 class CommandOptions : public Options
798 {
799 public:
800 uint32_t m_thread_idx;
801 uint32_t m_frame_idx;
802
Greg Claytonf15996e2011-04-07 22:46:35 +0000803 CommandOptions (CommandInterpreter &interpreter) :
804 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000805 m_thread_idx(LLDB_INVALID_THREAD_ID),
806 m_frame_idx(LLDB_INVALID_FRAME_ID)
807 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000808 // Keep default values of all options in one place: OptionParsingStarting ()
809 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000810 }
811
812 virtual
813 ~CommandOptions ()
814 {
815 }
816
817 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000818 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000819 {
820 Error error;
821 char short_option = (char) m_getopt_table[option_idx].val;
822
823 switch (short_option)
824 {
825 case 't':
826 {
Greg Claytonbef15832010-07-14 00:18:15 +0000827 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000828 if (m_thread_idx == LLDB_INVALID_INDEX32)
829 {
Greg Clayton9c236732011-10-26 00:56:27 +0000830 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000831 }
832 }
833 break;
834 case 'f':
835 {
836 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
837 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
838 {
Greg Clayton9c236732011-10-26 00:56:27 +0000839 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000840 }
841 }
842 break;
843 case 'm':
844 {
Chris Lattner24943d22010-06-08 16:52:24 +0000845 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000846 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000847
Greg Clayton61aca5d2011-10-07 18:58:12 +0000848 if (error.Success())
849 {
850 if (run_mode == eAllThreads)
851 m_stop_others = false;
852 else
853 m_stop_others = true;
854 }
Chris Lattner24943d22010-06-08 16:52:24 +0000855 }
856 break;
857 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000858 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000859 break;
860
861 }
862 return error;
863 }
864
865 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000866 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000867 {
Chris Lattner24943d22010-06-08 16:52:24 +0000868 m_thread_idx = LLDB_INVALID_THREAD_ID;
869 m_frame_idx = 0;
870 m_stop_others = false;
871 }
872
Greg Claytonb3448432011-03-24 21:19:54 +0000873 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000874 GetDefinitions ()
875 {
876 return g_option_table;
877 }
878
879 uint32_t m_step_thread_idx;
880 bool m_stop_others;
881
882 // Options table: Required for subclasses of Options.
883
Greg Claytonb3448432011-03-24 21:19:54 +0000884 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000885
886 // Instance variables to hold the values for command options.
887 };
888
Greg Clayton238c0a12010-09-18 01:14:36 +0000889 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000890 CommandObjectParsed (interpreter,
891 "thread until",
892 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
893 NULL,
894 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000895 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000896 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000897 CommandArgumentEntry arg;
898 CommandArgumentData line_num_arg;
899
900 // Define the first (and only) variant of this arg.
901 line_num_arg.arg_type = eArgTypeLineNum;
902 line_num_arg.arg_repetition = eArgRepeatPlain;
903
904 // There is only one variant this argument could be; put it into the argument entry.
905 arg.push_back (line_num_arg);
906
907 // Push the data for the first argument into the m_arguments vector.
908 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000909 }
910
911
912 virtual
913 ~CommandObjectThreadUntil ()
914 {
915 }
916
917 virtual
918 Options *
919 GetOptions ()
920 {
921 return &m_options;
922 }
923
Jim Inghamda26bd22012-06-08 21:56:10 +0000924protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000925 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000926 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000927 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000928 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000929
Greg Clayton238c0a12010-09-18 01:14:36 +0000930 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000931 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000932 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000933 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000934 result.SetStatus (eReturnStatusFailed);
935 return false;
936 }
937
Greg Clayton567e7f32011-09-22 04:58:26 +0000938 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000939 if (process == NULL)
940 {
941 result.AppendError ("need a valid process to step");
942 result.SetStatus (eReturnStatusFailed);
943
944 }
945 else
946 {
947 Thread *thread = NULL;
948 uint32_t line_number;
949
950 if (command.GetArgumentCount() != 1)
951 {
952 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
953 result.SetStatus (eReturnStatusFailed);
954 return false;
955 }
956
957 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
958 if (line_number == UINT32_MAX)
959 {
Greg Clayton9c236732011-10-26 00:56:27 +0000960 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +0000961 result.SetStatus (eReturnStatusFailed);
962 return false;
963 }
964
965 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
966 {
Jim Inghamc8332952010-08-26 21:32:51 +0000967 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000968 }
969 else
970 {
Greg Claytona2243772012-05-31 00:29:20 +0000971 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000972 }
973
974 if (thread == NULL)
975 {
976 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000977 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
978 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000979 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000980 result.SetStatus (eReturnStatusFailed);
981 return false;
982 }
983
Jim Inghamd82bc6d2012-05-11 23:47:32 +0000984 const bool abort_other_plans = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000985
986 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
987 if (frame == NULL)
988 {
989
Jim Inghamb07c62a2011-05-08 00:56:32 +0000990 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
991 m_options.m_frame_idx,
992 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000993 result.SetStatus (eReturnStatusFailed);
994 return false;
995 }
996
Jim Ingham88e3de22012-05-03 21:19:36 +0000997 ThreadPlan *new_plan = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000998
999 if (frame->HasDebugInformation ())
1000 {
1001 // Finally we got here... Translate the given line number to a bunch of addresses:
1002 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1003 LineTable *line_table = NULL;
1004 if (sc.comp_unit)
1005 line_table = sc.comp_unit->GetLineTable();
1006
1007 if (line_table == NULL)
1008 {
1009 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1010 m_options.m_frame_idx, m_options.m_thread_idx);
1011 result.SetStatus (eReturnStatusFailed);
1012 return false;
1013 }
1014
1015 LineEntry function_start;
1016 uint32_t index_ptr = 0, end_ptr;
1017 std::vector<addr_t> address_list;
1018
1019 // Find the beginning & end index of the
1020 AddressRange fun_addr_range = sc.function->GetAddressRange();
1021 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1022 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1023
Jim Inghamb07c62a2011-05-08 00:56:32 +00001024 Address fun_end_addr(fun_start_addr.GetSection(),
1025 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00001026 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1027
Jim Inghamb07c62a2011-05-08 00:56:32 +00001028 bool all_in_function = true;
1029
Chris Lattner24943d22010-06-08 16:52:24 +00001030 while (index_ptr <= end_ptr)
1031 {
1032 LineEntry line_entry;
Jim Inghamd6d47972011-09-23 00:54:11 +00001033 const bool exact = false;
1034 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +00001035 if (index_ptr == UINT32_MAX)
1036 break;
1037
Greg Claytoneea26402010-09-14 23:36:40 +00001038 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001039 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001040 {
1041 if (fun_addr_range.ContainsLoadAddress (address, target))
1042 address_list.push_back (address);
1043 else
1044 all_in_function = false;
1045 }
Chris Lattner24943d22010-06-08 16:52:24 +00001046 index_ptr++;
1047 }
1048
Jim Inghamb07c62a2011-05-08 00:56:32 +00001049 if (address_list.size() == 0)
1050 {
1051 if (all_in_function)
1052 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1053 else
1054 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1055
1056 result.SetStatus (eReturnStatusFailed);
1057 return false;
1058 }
1059
1060 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1061 &address_list.front(),
1062 address_list.size(),
1063 m_options.m_stop_others,
Jim Inghamfade78a2012-09-14 20:48:14 +00001064 m_options.m_frame_idx);
Jim Ingham88e3de22012-05-03 21:19:36 +00001065 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1066 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1067 // will resume the original plan.
1068 new_plan->SetIsMasterPlan (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001069 new_plan->SetOkayToDiscard(false);
1070 }
1071 else
1072 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001073 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1074 m_options.m_frame_idx,
1075 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001076 result.SetStatus (eReturnStatusFailed);
1077 return false;
1078
1079 }
1080
Jim Inghamc8332952010-08-26 21:32:51 +00001081 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001082 Error error (process->Resume ());
1083 if (error.Success())
1084 {
Greg Clayton444e35b2011-10-19 18:09:39 +00001085 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001086 if (synchronous_execution)
1087 {
1088 StateType state = process->WaitForProcessToStop (NULL);
1089
1090 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +00001091 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +00001092 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1093 }
1094 else
1095 {
1096 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1097 }
1098 }
1099 else
1100 {
1101 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1102 result.SetStatus (eReturnStatusFailed);
1103 }
1104
1105 }
1106 return result.Succeeded();
1107 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001108
Chris Lattner24943d22010-06-08 16:52:24 +00001109 CommandOptions m_options;
1110
1111};
1112
Greg Claytonb3448432011-03-24 21:19:54 +00001113OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001114CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1115{
Caroline Tice43b014a2010-10-04 22:28:36 +00001116{ LLDB_OPT_SET_1, false, "frame", 'f', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
Caroline Tice4d6675c2010-10-01 19:59:14 +00001117{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1118{ LLDB_OPT_SET_1, false, "run-mode",'m', required_argument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
1119{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001120};
1121
1122
1123//-------------------------------------------------------------------------
1124// CommandObjectThreadSelect
1125//-------------------------------------------------------------------------
1126
Jim Inghamda26bd22012-06-08 21:56:10 +00001127class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001128{
1129public:
1130
Greg Clayton238c0a12010-09-18 01:14:36 +00001131 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001132 CommandObjectParsed (interpreter,
1133 "thread select",
1134 "Select a thread as the currently active thread.",
1135 NULL,
1136 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001137 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001138 CommandArgumentEntry arg;
1139 CommandArgumentData thread_idx_arg;
1140
1141 // Define the first (and only) variant of this arg.
1142 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1143 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1144
1145 // There is only one variant this argument could be; put it into the argument entry.
1146 arg.push_back (thread_idx_arg);
1147
1148 // Push the data for the first argument into the m_arguments vector.
1149 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001150 }
1151
1152
1153 virtual
1154 ~CommandObjectThreadSelect ()
1155 {
1156 }
1157
Jim Inghamda26bd22012-06-08 21:56:10 +00001158protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001159 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001160 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001161 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001162 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001163 if (process == NULL)
1164 {
1165 result.AppendError ("no process");
1166 result.SetStatus (eReturnStatusFailed);
1167 return false;
1168 }
1169 else if (command.GetArgumentCount() != 1)
1170 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001171 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001172 result.SetStatus (eReturnStatusFailed);
1173 return false;
1174 }
1175
1176 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1177
1178 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1179 if (new_thread == NULL)
1180 {
Greg Clayton9c236732011-10-26 00:56:27 +00001181 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +00001182 result.SetStatus (eReturnStatusFailed);
1183 return false;
1184 }
1185
Jim Inghamc8332952010-08-26 21:32:51 +00001186 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001187 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001188
Greg Claytonabe0fed2011-04-18 08:33:37 +00001189 const uint32_t start_frame = 0;
1190 const uint32_t num_frames = 1;
1191 const uint32_t num_frames_with_source = 1;
1192 new_thread->GetStatus (result.GetOutputStream(),
1193 start_frame,
1194 num_frames,
1195 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001196
1197 return result.Succeeded();
1198 }
1199
1200};
1201
1202
1203//-------------------------------------------------------------------------
1204// CommandObjectThreadList
1205//-------------------------------------------------------------------------
1206
Jim Inghamda26bd22012-06-08 21:56:10 +00001207class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001208{
Greg Clayton63094e02010-06-23 01:19:29 +00001209public:
Chris Lattner24943d22010-06-08 16:52:24 +00001210
Chris Lattner24943d22010-06-08 16:52:24 +00001211
Greg Clayton238c0a12010-09-18 01:14:36 +00001212 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Inghamda26bd22012-06-08 21:56:10 +00001213 CommandObjectParsed (interpreter,
1214 "thread list",
1215 "Show a summary of all current threads in a process.",
1216 "thread list",
1217 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001218 {
Greg Clayton63094e02010-06-23 01:19:29 +00001219 }
Chris Lattner24943d22010-06-08 16:52:24 +00001220
Greg Clayton63094e02010-06-23 01:19:29 +00001221 ~CommandObjectThreadList()
1222 {
1223 }
1224
Jim Inghamda26bd22012-06-08 21:56:10 +00001225protected:
Greg Clayton63094e02010-06-23 01:19:29 +00001226 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001227 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton63094e02010-06-23 01:19:29 +00001228 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001229 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001230 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001231 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001232 Process *process = exe_ctx.GetProcessPtr();
1233 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00001234 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001235 const bool only_threads_with_stop_reason = false;
1236 const uint32_t start_frame = 0;
1237 const uint32_t num_frames = 0;
1238 const uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +00001239 process->GetStatus(strm);
1240 process->GetThreadStatus (strm,
1241 only_threads_with_stop_reason,
1242 start_frame,
1243 num_frames,
1244 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001245 }
1246 else
1247 {
Greg Clayton63094e02010-06-23 01:19:29 +00001248 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001249 result.SetStatus (eReturnStatusFailed);
1250 }
Greg Clayton63094e02010-06-23 01:19:29 +00001251 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001252 }
Greg Clayton63094e02010-06-23 01:19:29 +00001253};
Chris Lattner24943d22010-06-08 16:52:24 +00001254
Jim Inghamf59388a2012-09-14 02:14:15 +00001255class CommandObjectThreadReturn : public CommandObjectRaw
1256{
1257public:
1258 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1259 CommandObjectRaw (interpreter,
1260 "thread return",
1261 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value.",
1262 "thread return",
1263 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1264 {
1265 CommandArgumentEntry arg;
1266 CommandArgumentData expression_arg;
1267
1268 // Define the first (and only) variant of this arg.
1269 expression_arg.arg_type = eArgTypeExpression;
1270 expression_arg.arg_repetition = eArgRepeatPlain;
1271
1272 // There is only one variant this argument could be; put it into the argument entry.
1273 arg.push_back (expression_arg);
1274
1275 // Push the data for the first argument into the m_arguments vector.
1276 m_arguments.push_back (arg);
1277
1278
1279 }
1280
1281 ~CommandObjectThreadReturn()
1282 {
1283 }
1284
1285protected:
1286
1287 bool DoExecute
1288 (
1289 const char *command,
1290 CommandReturnObject &result
1291 )
1292 {
1293 // If there is a command string, pass it to the expression parser:
1294 ExecutionContext exe_ctx = m_interpreter.GetExecutionContext();
1295 if (!(exe_ctx.HasProcessScope() && exe_ctx.HasThreadScope() && exe_ctx.HasFrameScope()))
1296 {
1297 result.AppendError("Must have selected process, thread and frame for thread return.");
1298 result.SetStatus (eReturnStatusFailed);
1299 return false;
1300 }
1301
1302 ValueObjectSP return_valobj_sp;
1303
1304 StackFrameSP frame_sp = exe_ctx.GetFrameSP();
1305 uint32_t frame_idx = frame_sp->GetFrameIndex();
1306
1307 if (frame_sp->IsInlined())
1308 {
1309 result.AppendError("Don't know how to return from inlined frames.");
1310 result.SetStatus (eReturnStatusFailed);
1311 return false;
1312 }
1313
1314 if (command && command[0] != '\0')
1315 {
1316 Target *target = exe_ctx.GetTargetPtr();
1317 Target::EvaluateExpressionOptions options;
1318
1319 options.SetUnwindOnError(true);
1320 options.SetUseDynamic(eNoDynamicValues);
1321
1322 ExecutionResults exe_results = eExecutionSetupError;
1323 exe_results = target->EvaluateExpression (command,
1324 frame_sp.get(),
1325 return_valobj_sp,
1326 options);
1327 if (exe_results != eExecutionCompleted)
1328 {
1329 if (return_valobj_sp)
1330 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1331 else
1332 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1333 result.SetStatus (eReturnStatusFailed);
1334 return false;
1335
1336 }
1337 }
1338
1339 Error error;
1340 ThreadSP thread_sp = exe_ctx.GetThreadSP();
1341 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp);
1342 if (!error.Success())
1343 {
1344 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1345 result.SetStatus (eReturnStatusFailed);
1346 return false;
1347 }
1348
1349 thread_sp->GetStatus(result.GetOutputStream(), 0, 1, 1);
1350 result.SetStatus (eReturnStatusSuccessFinishResult);
1351 return true;
1352 }
1353
1354};
1355
Chris Lattner24943d22010-06-08 16:52:24 +00001356//-------------------------------------------------------------------------
1357// CommandObjectMultiwordThread
1358//-------------------------------------------------------------------------
1359
Greg Clayton63094e02010-06-23 01:19:29 +00001360CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001361 CommandObjectMultiword (interpreter,
1362 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001363 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001364 "thread <subcommand> [<subcommand-options>]")
1365{
Greg Clayton238c0a12010-09-18 01:14:36 +00001366 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1367 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1368 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamf59388a2012-09-14 02:14:15 +00001369 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Greg Clayton238c0a12010-09-18 01:14:36 +00001370 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1371 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1372 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1373 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001374 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001375 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001376 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001377 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1378 eStepTypeInto,
1379 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001380
Greg Clayton238c0a12010-09-18 01:14:36 +00001381 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1382 interpreter,
1383 "thread step-out",
Jim Ingham1586d972011-12-17 01:35:57 +00001384 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001385 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001386 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1387 eStepTypeOut,
1388 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001389
Greg Clayton238c0a12010-09-18 01:14:36 +00001390 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1391 interpreter,
1392 "thread step-over",
1393 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001394 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001395 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1396 eStepTypeOver,
1397 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001398
Greg Clayton238c0a12010-09-18 01:14:36 +00001399 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1400 interpreter,
1401 "thread step-inst",
1402 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001403 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001404 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1405 eStepTypeTrace,
1406 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001407
Greg Clayton238c0a12010-09-18 01:14:36 +00001408 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1409 interpreter,
1410 "thread step-inst-over",
1411 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001412 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001413 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1414 eStepTypeTraceOver,
1415 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001416}
1417
1418CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1419{
1420}
1421
1422