blob: ee4650179dd1f0a463780f981b7c7de44b9295bb [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;
452 else
453 bool_stop_other_threads = true;
454
Jim Ingham88e3de22012-05-03 21:19:36 +0000455 ThreadPlan *new_plan = NULL;
456
Chris Lattner24943d22010-06-08 16:52:24 +0000457 if (m_step_type == eStepTypeInto)
458 {
459 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000460
461 if (frame->HasDebugInformation ())
462 {
463 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
464 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
465 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000466 stop_other_threads,
467 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000468 if (new_plan && !m_options.m_avoid_regexp.empty())
469 {
470 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
471 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
472 }
Chris Lattner24943d22010-06-08 16:52:24 +0000473 }
474 else
475 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Ingham88e3de22012-05-03 21:19:36 +0000476
Chris Lattner24943d22010-06-08 16:52:24 +0000477 }
478 else if (m_step_type == eStepTypeOver)
479 {
480 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000481
482 if (frame->HasDebugInformation())
483 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
484 m_step_type,
485 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
486 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000487 stop_other_threads,
488 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000489 else
490 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
491 abort_other_plans,
492 bool_stop_other_threads);
493
Chris Lattner24943d22010-06-08 16:52:24 +0000494 }
495 else if (m_step_type == eStepTypeTrace)
496 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000497 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000498 }
499 else if (m_step_type == eStepTypeTraceOver)
500 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000501 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000502 }
503 else if (m_step_type == eStepTypeOut)
504 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000505 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
506 NULL,
507 false,
508 bool_stop_other_threads,
509 eVoteYes,
510 eVoteNoOpinion,
511 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000512 }
513 else
514 {
515 result.AppendError ("step type is not supported");
516 result.SetStatus (eReturnStatusFailed);
Jim Ingham88e3de22012-05-03 21:19:36 +0000517 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000518 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000519
520 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
521 // so that they can be interruptible). Then resume the process.
522
523 if (new_plan != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000524 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000525 new_plan->SetIsMasterPlan (true);
526 new_plan->SetOkayToDiscard (false);
527
Jim Inghamc8332952010-08-26 21:32:51 +0000528 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Jim Ingham88e3de22012-05-03 21:19:36 +0000529 process->Resume ();
530
531
532 if (synchronous_execution)
533 {
534 StateType state = process->WaitForProcessToStop (NULL);
535
536 //EventSP event_sp;
537 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
538 //while (! StateIsStoppedState (state))
539 // {
540 // state = process->WaitForStateChangedEvents (NULL, event_sp);
541 // }
542 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
543 result.SetDidChangeProcessState (true);
544 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
545 result.SetStatus (eReturnStatusSuccessFinishNoResult);
546 }
Jim Ingham53628e72012-05-16 00:37:40 +0000547 else
548 {
549 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
550 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000551 }
552 else
553 {
554 result.AppendError ("Couldn't find thread plan to implement step type.");
555 result.SetStatus (eReturnStatusFailed);
Chris Lattner24943d22010-06-08 16:52:24 +0000556 }
557 }
558 return result.Succeeded();
559 }
560
561protected:
562 StepType m_step_type;
563 StepScope m_step_scope;
564 CommandOptions m_options;
565};
566
Greg Claytonb3448432011-03-24 21:19:54 +0000567static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000568g_tri_running_mode[] =
569{
Greg Claytonfe424a92010-09-18 03:37:20 +0000570{ eOnlyThisThread, "this-thread", "Run only this thread"},
571{ eAllThreads, "all-threads", "Run all threads"},
572{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000573{ 0, NULL, NULL }
574};
575
Greg Claytonb3448432011-03-24 21:19:54 +0000576static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000577g_duo_running_mode[] =
578{
Greg Claytonfe424a92010-09-18 03:37:20 +0000579{ eOnlyThisThread, "this-thread", "Run only this thread"},
580{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000581{ 0, NULL, NULL }
582};
583
Greg Claytonb3448432011-03-24 21:19:54 +0000584OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000585CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
586{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000587{ 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."},
588{ 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."},
589{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
590{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000591};
592
593
594//-------------------------------------------------------------------------
595// CommandObjectThreadContinue
596//-------------------------------------------------------------------------
597
Jim Inghamda26bd22012-06-08 21:56:10 +0000598class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000599{
600public:
601
Greg Clayton238c0a12010-09-18 01:14:36 +0000602 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000603 CommandObjectParsed (interpreter,
604 "thread continue",
605 "Continue execution of one or more threads in an active process.",
606 NULL,
607 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +0000608 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000609 CommandArgumentEntry arg;
610 CommandArgumentData thread_idx_arg;
611
612 // Define the first (and only) variant of this arg.
613 thread_idx_arg.arg_type = eArgTypeThreadIndex;
614 thread_idx_arg.arg_repetition = eArgRepeatPlus;
615
616 // There is only one variant this argument could be; put it into the argument entry.
617 arg.push_back (thread_idx_arg);
618
619 // Push the data for the first argument into the m_arguments vector.
620 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000621 }
622
623
624 virtual
625 ~CommandObjectThreadContinue ()
626 {
627 }
628
629 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000630 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000631 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000632 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000633
Greg Clayton238c0a12010-09-18 01:14:36 +0000634 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000635 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000636 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000637 result.SetStatus (eReturnStatusFailed);
638 return false;
639 }
640
Greg Clayton567e7f32011-09-22 04:58:26 +0000641 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000642 if (process == NULL)
643 {
644 result.AppendError ("no process exists. Cannot continue");
645 result.SetStatus (eReturnStatusFailed);
646 return false;
647 }
648
649 StateType state = process->GetState();
650 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
651 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000652 Mutex::Locker locker (process->GetThreadList().GetMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000653 const uint32_t num_threads = process->GetThreadList().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000654 const size_t argc = command.GetArgumentCount();
655 if (argc > 0)
656 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000657 std::vector<Thread *> resume_threads;
Chris Lattner24943d22010-06-08 16:52:24 +0000658 for (uint32_t i=0; i<argc; ++i)
659 {
Jim Inghamd07b4f52012-05-31 20:48:41 +0000660 bool success;
661 const int base = 0;
Greg Claytonedd601a2012-07-03 20:54:16 +0000662 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
663 if (success)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000664 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000665 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
666
667 if (thread)
668 {
669 resume_threads.push_back(thread);
670 }
671 else
672 {
673 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
674 result.SetStatus (eReturnStatusFailed);
675 return false;
676 }
Jim Inghamd07b4f52012-05-31 20:48:41 +0000677 }
Chris Lattner24943d22010-06-08 16:52:24 +0000678 else
Jim Inghamd07b4f52012-05-31 20:48:41 +0000679 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000680 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd07b4f52012-05-31 20:48:41 +0000681 result.SetStatus (eReturnStatusFailed);
682 return false;
683 }
Chris Lattner24943d22010-06-08 16:52:24 +0000684 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000685
686 if (resume_threads.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000687 {
688 result.AppendError ("no valid thread indexes were specified");
689 result.SetStatus (eReturnStatusFailed);
690 return false;
691 }
692 else
693 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000694 if (resume_threads.size() == 1)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000695 result.AppendMessageWithFormat ("Resuming thread: ");
696 else
697 result.AppendMessageWithFormat ("Resuming threads: ");
Greg Claytonedd601a2012-07-03 20:54:16 +0000698
699 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000700 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000701 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
702 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Jim Inghamd07b4f52012-05-31 20:48:41 +0000703
Greg Claytonedd601a2012-07-03 20:54:16 +0000704 if (this_thread_pos != resume_threads.end())
Chris Lattner24943d22010-06-08 16:52:24 +0000705 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000706 resume_threads.erase(this_thread_pos);
707 if (resume_threads.size() > 0)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000708 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
709 else
710 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
711
Chris Lattner24943d22010-06-08 16:52:24 +0000712 thread->SetResumeState (eStateRunning);
713 }
714 else
715 {
716 thread->SetResumeState (eStateSuspended);
717 }
718 }
Greg Clayton444e35b2011-10-19 18:09:39 +0000719 result.AppendMessageWithFormat ("in process %llu\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000720 }
721 }
722 else
723 {
Jim Inghamc8332952010-08-26 21:32:51 +0000724 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000725 if (current_thread == NULL)
726 {
727 result.AppendError ("the process doesn't have a current thread");
728 result.SetStatus (eReturnStatusFailed);
729 return false;
730 }
731 // Set the actions that the threads should each take when resuming
Greg Claytonedd601a2012-07-03 20:54:16 +0000732 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000733 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000734 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000735 if (thread == current_thread)
736 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000737 result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000738 thread->SetResumeState (eStateRunning);
739 }
740 else
741 {
742 thread->SetResumeState (eStateSuspended);
743 }
744 }
745 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000746
Chris Lattner24943d22010-06-08 16:52:24 +0000747 Error error (process->Resume());
748 if (error.Success())
749 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000750 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000751 if (synchronous_execution)
752 {
Greg Claytonbef15832010-07-14 00:18:15 +0000753 state = process->WaitForProcessToStop (NULL);
Greg Claytonedd601a2012-07-03 20:54:16 +0000754
Chris Lattner24943d22010-06-08 16:52:24 +0000755 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +0000756 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +0000757 result.SetStatus (eReturnStatusSuccessFinishNoResult);
758 }
759 else
760 {
761 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
762 }
763 }
764 else
765 {
766 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
767 result.SetStatus (eReturnStatusFailed);
768 }
769 }
770 else
771 {
772 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
773 StateAsCString(state));
774 result.SetStatus (eReturnStatusFailed);
775 }
776
777 return result.Succeeded();
778 }
779
780};
781
782//-------------------------------------------------------------------------
783// CommandObjectThreadUntil
784//-------------------------------------------------------------------------
785
Jim Inghamda26bd22012-06-08 21:56:10 +0000786class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000787{
788public:
789
790 class CommandOptions : public Options
791 {
792 public:
793 uint32_t m_thread_idx;
794 uint32_t m_frame_idx;
795
Greg Claytonf15996e2011-04-07 22:46:35 +0000796 CommandOptions (CommandInterpreter &interpreter) :
797 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000798 m_thread_idx(LLDB_INVALID_THREAD_ID),
799 m_frame_idx(LLDB_INVALID_FRAME_ID)
800 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000801 // Keep default values of all options in one place: OptionParsingStarting ()
802 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000803 }
804
805 virtual
806 ~CommandOptions ()
807 {
808 }
809
810 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000811 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000812 {
813 Error error;
814 char short_option = (char) m_getopt_table[option_idx].val;
815
816 switch (short_option)
817 {
818 case 't':
819 {
Greg Claytonbef15832010-07-14 00:18:15 +0000820 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000821 if (m_thread_idx == LLDB_INVALID_INDEX32)
822 {
Greg Clayton9c236732011-10-26 00:56:27 +0000823 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000824 }
825 }
826 break;
827 case 'f':
828 {
829 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
830 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
831 {
Greg Clayton9c236732011-10-26 00:56:27 +0000832 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000833 }
834 }
835 break;
836 case 'm':
837 {
Chris Lattner24943d22010-06-08 16:52:24 +0000838 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000839 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000840
Greg Clayton61aca5d2011-10-07 18:58:12 +0000841 if (error.Success())
842 {
843 if (run_mode == eAllThreads)
844 m_stop_others = false;
845 else
846 m_stop_others = true;
847 }
Chris Lattner24943d22010-06-08 16:52:24 +0000848 }
849 break;
850 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000851 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000852 break;
853
854 }
855 return error;
856 }
857
858 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000859 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000860 {
Chris Lattner24943d22010-06-08 16:52:24 +0000861 m_thread_idx = LLDB_INVALID_THREAD_ID;
862 m_frame_idx = 0;
863 m_stop_others = false;
864 }
865
Greg Claytonb3448432011-03-24 21:19:54 +0000866 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000867 GetDefinitions ()
868 {
869 return g_option_table;
870 }
871
872 uint32_t m_step_thread_idx;
873 bool m_stop_others;
874
875 // Options table: Required for subclasses of Options.
876
Greg Claytonb3448432011-03-24 21:19:54 +0000877 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000878
879 // Instance variables to hold the values for command options.
880 };
881
Greg Clayton238c0a12010-09-18 01:14:36 +0000882 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000883 CommandObjectParsed (interpreter,
884 "thread until",
885 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
886 NULL,
887 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000888 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000889 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000890 CommandArgumentEntry arg;
891 CommandArgumentData line_num_arg;
892
893 // Define the first (and only) variant of this arg.
894 line_num_arg.arg_type = eArgTypeLineNum;
895 line_num_arg.arg_repetition = eArgRepeatPlain;
896
897 // There is only one variant this argument could be; put it into the argument entry.
898 arg.push_back (line_num_arg);
899
900 // Push the data for the first argument into the m_arguments vector.
901 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000902 }
903
904
905 virtual
906 ~CommandObjectThreadUntil ()
907 {
908 }
909
910 virtual
911 Options *
912 GetOptions ()
913 {
914 return &m_options;
915 }
916
Jim Inghamda26bd22012-06-08 21:56:10 +0000917protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000918 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000919 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000920 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000921 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000922
Greg Clayton238c0a12010-09-18 01:14:36 +0000923 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000924 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000925 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000926 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000927 result.SetStatus (eReturnStatusFailed);
928 return false;
929 }
930
Greg Clayton567e7f32011-09-22 04:58:26 +0000931 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000932 if (process == NULL)
933 {
934 result.AppendError ("need a valid process to step");
935 result.SetStatus (eReturnStatusFailed);
936
937 }
938 else
939 {
940 Thread *thread = NULL;
941 uint32_t line_number;
942
943 if (command.GetArgumentCount() != 1)
944 {
945 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
946 result.SetStatus (eReturnStatusFailed);
947 return false;
948 }
949
950 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
951 if (line_number == UINT32_MAX)
952 {
Greg Clayton9c236732011-10-26 00:56:27 +0000953 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +0000954 result.SetStatus (eReturnStatusFailed);
955 return false;
956 }
957
958 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
959 {
Jim Inghamc8332952010-08-26 21:32:51 +0000960 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000961 }
962 else
963 {
Greg Claytona2243772012-05-31 00:29:20 +0000964 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000965 }
966
967 if (thread == NULL)
968 {
969 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000970 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
971 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000972 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000973 result.SetStatus (eReturnStatusFailed);
974 return false;
975 }
976
Jim Inghamd82bc6d2012-05-11 23:47:32 +0000977 const bool abort_other_plans = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000978
979 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
980 if (frame == NULL)
981 {
982
Jim Inghamb07c62a2011-05-08 00:56:32 +0000983 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
984 m_options.m_frame_idx,
985 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000986 result.SetStatus (eReturnStatusFailed);
987 return false;
988 }
989
Jim Ingham88e3de22012-05-03 21:19:36 +0000990 ThreadPlan *new_plan = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000991
992 if (frame->HasDebugInformation ())
993 {
994 // Finally we got here... Translate the given line number to a bunch of addresses:
995 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
996 LineTable *line_table = NULL;
997 if (sc.comp_unit)
998 line_table = sc.comp_unit->GetLineTable();
999
1000 if (line_table == NULL)
1001 {
1002 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1003 m_options.m_frame_idx, m_options.m_thread_idx);
1004 result.SetStatus (eReturnStatusFailed);
1005 return false;
1006 }
1007
1008 LineEntry function_start;
1009 uint32_t index_ptr = 0, end_ptr;
1010 std::vector<addr_t> address_list;
1011
1012 // Find the beginning & end index of the
1013 AddressRange fun_addr_range = sc.function->GetAddressRange();
1014 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1015 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1016
Jim Inghamb07c62a2011-05-08 00:56:32 +00001017 Address fun_end_addr(fun_start_addr.GetSection(),
1018 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00001019 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1020
Jim Inghamb07c62a2011-05-08 00:56:32 +00001021 bool all_in_function = true;
1022
Chris Lattner24943d22010-06-08 16:52:24 +00001023 while (index_ptr <= end_ptr)
1024 {
1025 LineEntry line_entry;
Jim Inghamd6d47972011-09-23 00:54:11 +00001026 const bool exact = false;
1027 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +00001028 if (index_ptr == UINT32_MAX)
1029 break;
1030
Greg Claytoneea26402010-09-14 23:36:40 +00001031 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001032 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001033 {
1034 if (fun_addr_range.ContainsLoadAddress (address, target))
1035 address_list.push_back (address);
1036 else
1037 all_in_function = false;
1038 }
Chris Lattner24943d22010-06-08 16:52:24 +00001039 index_ptr++;
1040 }
1041
Jim Inghamb07c62a2011-05-08 00:56:32 +00001042 if (address_list.size() == 0)
1043 {
1044 if (all_in_function)
1045 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1046 else
1047 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1048
1049 result.SetStatus (eReturnStatusFailed);
1050 return false;
1051 }
1052
1053 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1054 &address_list.front(),
1055 address_list.size(),
1056 m_options.m_stop_others,
Jim Inghamfade78a2012-09-14 20:48:14 +00001057 m_options.m_frame_idx);
Jim Ingham88e3de22012-05-03 21:19:36 +00001058 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1059 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1060 // will resume the original plan.
1061 new_plan->SetIsMasterPlan (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001062 new_plan->SetOkayToDiscard(false);
1063 }
1064 else
1065 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001066 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1067 m_options.m_frame_idx,
1068 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001069 result.SetStatus (eReturnStatusFailed);
1070 return false;
1071
1072 }
1073
Jim Inghamc8332952010-08-26 21:32:51 +00001074 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001075 Error error (process->Resume ());
1076 if (error.Success())
1077 {
Greg Clayton444e35b2011-10-19 18:09:39 +00001078 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001079 if (synchronous_execution)
1080 {
1081 StateType state = process->WaitForProcessToStop (NULL);
1082
1083 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +00001084 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +00001085 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1086 }
1087 else
1088 {
1089 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1090 }
1091 }
1092 else
1093 {
1094 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1095 result.SetStatus (eReturnStatusFailed);
1096 }
1097
1098 }
1099 return result.Succeeded();
1100 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001101
Chris Lattner24943d22010-06-08 16:52:24 +00001102 CommandOptions m_options;
1103
1104};
1105
Greg Claytonb3448432011-03-24 21:19:54 +00001106OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001107CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1108{
Caroline Tice43b014a2010-10-04 22:28:36 +00001109{ 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 +00001110{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1111{ 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"},
1112{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001113};
1114
1115
1116//-------------------------------------------------------------------------
1117// CommandObjectThreadSelect
1118//-------------------------------------------------------------------------
1119
Jim Inghamda26bd22012-06-08 21:56:10 +00001120class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001121{
1122public:
1123
Greg Clayton238c0a12010-09-18 01:14:36 +00001124 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001125 CommandObjectParsed (interpreter,
1126 "thread select",
1127 "Select a thread as the currently active thread.",
1128 NULL,
1129 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001130 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001131 CommandArgumentEntry arg;
1132 CommandArgumentData thread_idx_arg;
1133
1134 // Define the first (and only) variant of this arg.
1135 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1136 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1137
1138 // There is only one variant this argument could be; put it into the argument entry.
1139 arg.push_back (thread_idx_arg);
1140
1141 // Push the data for the first argument into the m_arguments vector.
1142 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001143 }
1144
1145
1146 virtual
1147 ~CommandObjectThreadSelect ()
1148 {
1149 }
1150
Jim Inghamda26bd22012-06-08 21:56:10 +00001151protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001152 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001153 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001154 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001155 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001156 if (process == NULL)
1157 {
1158 result.AppendError ("no process");
1159 result.SetStatus (eReturnStatusFailed);
1160 return false;
1161 }
1162 else if (command.GetArgumentCount() != 1)
1163 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001164 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 +00001165 result.SetStatus (eReturnStatusFailed);
1166 return false;
1167 }
1168
1169 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1170
1171 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1172 if (new_thread == NULL)
1173 {
Greg Clayton9c236732011-10-26 00:56:27 +00001174 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +00001175 result.SetStatus (eReturnStatusFailed);
1176 return false;
1177 }
1178
Jim Inghamc8332952010-08-26 21:32:51 +00001179 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001180 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001181
Greg Claytonabe0fed2011-04-18 08:33:37 +00001182 const uint32_t start_frame = 0;
1183 const uint32_t num_frames = 1;
1184 const uint32_t num_frames_with_source = 1;
1185 new_thread->GetStatus (result.GetOutputStream(),
1186 start_frame,
1187 num_frames,
1188 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001189
1190 return result.Succeeded();
1191 }
1192
1193};
1194
1195
1196//-------------------------------------------------------------------------
1197// CommandObjectThreadList
1198//-------------------------------------------------------------------------
1199
Jim Inghamda26bd22012-06-08 21:56:10 +00001200class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001201{
Greg Clayton63094e02010-06-23 01:19:29 +00001202public:
Chris Lattner24943d22010-06-08 16:52:24 +00001203
Chris Lattner24943d22010-06-08 16:52:24 +00001204
Greg Clayton238c0a12010-09-18 01:14:36 +00001205 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Inghamda26bd22012-06-08 21:56:10 +00001206 CommandObjectParsed (interpreter,
1207 "thread list",
1208 "Show a summary of all current threads in a process.",
1209 "thread list",
1210 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001211 {
Greg Clayton63094e02010-06-23 01:19:29 +00001212 }
Chris Lattner24943d22010-06-08 16:52:24 +00001213
Greg Clayton63094e02010-06-23 01:19:29 +00001214 ~CommandObjectThreadList()
1215 {
1216 }
1217
Jim Inghamda26bd22012-06-08 21:56:10 +00001218protected:
Greg Clayton63094e02010-06-23 01:19:29 +00001219 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001220 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton63094e02010-06-23 01:19:29 +00001221 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001222 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001223 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001224 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001225 Process *process = exe_ctx.GetProcessPtr();
1226 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00001227 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001228 const bool only_threads_with_stop_reason = false;
1229 const uint32_t start_frame = 0;
1230 const uint32_t num_frames = 0;
1231 const uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +00001232 process->GetStatus(strm);
1233 process->GetThreadStatus (strm,
1234 only_threads_with_stop_reason,
1235 start_frame,
1236 num_frames,
1237 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001238 }
1239 else
1240 {
Greg Clayton63094e02010-06-23 01:19:29 +00001241 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001242 result.SetStatus (eReturnStatusFailed);
1243 }
Greg Clayton63094e02010-06-23 01:19:29 +00001244 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001245 }
Greg Clayton63094e02010-06-23 01:19:29 +00001246};
Chris Lattner24943d22010-06-08 16:52:24 +00001247
Jim Inghamf59388a2012-09-14 02:14:15 +00001248class CommandObjectThreadReturn : public CommandObjectRaw
1249{
1250public:
1251 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1252 CommandObjectRaw (interpreter,
1253 "thread return",
1254 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value.",
1255 "thread return",
1256 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1257 {
1258 CommandArgumentEntry arg;
1259 CommandArgumentData expression_arg;
1260
1261 // Define the first (and only) variant of this arg.
1262 expression_arg.arg_type = eArgTypeExpression;
1263 expression_arg.arg_repetition = eArgRepeatPlain;
1264
1265 // There is only one variant this argument could be; put it into the argument entry.
1266 arg.push_back (expression_arg);
1267
1268 // Push the data for the first argument into the m_arguments vector.
1269 m_arguments.push_back (arg);
1270
1271
1272 }
1273
1274 ~CommandObjectThreadReturn()
1275 {
1276 }
1277
1278protected:
1279
1280 bool DoExecute
1281 (
1282 const char *command,
1283 CommandReturnObject &result
1284 )
1285 {
1286 // If there is a command string, pass it to the expression parser:
1287 ExecutionContext exe_ctx = m_interpreter.GetExecutionContext();
1288 if (!(exe_ctx.HasProcessScope() && exe_ctx.HasThreadScope() && exe_ctx.HasFrameScope()))
1289 {
1290 result.AppendError("Must have selected process, thread and frame for thread return.");
1291 result.SetStatus (eReturnStatusFailed);
1292 return false;
1293 }
1294
1295 ValueObjectSP return_valobj_sp;
1296
1297 StackFrameSP frame_sp = exe_ctx.GetFrameSP();
1298 uint32_t frame_idx = frame_sp->GetFrameIndex();
1299
1300 if (frame_sp->IsInlined())
1301 {
1302 result.AppendError("Don't know how to return from inlined frames.");
1303 result.SetStatus (eReturnStatusFailed);
1304 return false;
1305 }
1306
1307 if (command && command[0] != '\0')
1308 {
1309 Target *target = exe_ctx.GetTargetPtr();
1310 Target::EvaluateExpressionOptions options;
1311
1312 options.SetUnwindOnError(true);
1313 options.SetUseDynamic(eNoDynamicValues);
1314
1315 ExecutionResults exe_results = eExecutionSetupError;
1316 exe_results = target->EvaluateExpression (command,
1317 frame_sp.get(),
1318 return_valobj_sp,
1319 options);
1320 if (exe_results != eExecutionCompleted)
1321 {
1322 if (return_valobj_sp)
1323 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1324 else
1325 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1326 result.SetStatus (eReturnStatusFailed);
1327 return false;
1328
1329 }
1330 }
1331
1332 Error error;
1333 ThreadSP thread_sp = exe_ctx.GetThreadSP();
1334 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp);
1335 if (!error.Success())
1336 {
1337 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1338 result.SetStatus (eReturnStatusFailed);
1339 return false;
1340 }
1341
1342 thread_sp->GetStatus(result.GetOutputStream(), 0, 1, 1);
1343 result.SetStatus (eReturnStatusSuccessFinishResult);
1344 return true;
1345 }
1346
1347};
1348
Chris Lattner24943d22010-06-08 16:52:24 +00001349//-------------------------------------------------------------------------
1350// CommandObjectMultiwordThread
1351//-------------------------------------------------------------------------
1352
Greg Clayton63094e02010-06-23 01:19:29 +00001353CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001354 CommandObjectMultiword (interpreter,
1355 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001356 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001357 "thread <subcommand> [<subcommand-options>]")
1358{
Greg Clayton238c0a12010-09-18 01:14:36 +00001359 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1360 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1361 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamf59388a2012-09-14 02:14:15 +00001362 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Greg Clayton238c0a12010-09-18 01:14:36 +00001363 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1364 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1365 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1366 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001367 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001368 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001369 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001370 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1371 eStepTypeInto,
1372 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001373
Greg Clayton238c0a12010-09-18 01:14:36 +00001374 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1375 interpreter,
1376 "thread step-out",
Jim Ingham1586d972011-12-17 01:35:57 +00001377 "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 +00001378 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001379 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1380 eStepTypeOut,
1381 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001382
Greg Clayton238c0a12010-09-18 01:14:36 +00001383 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1384 interpreter,
1385 "thread step-over",
1386 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001387 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001388 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1389 eStepTypeOver,
1390 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001391
Greg Clayton238c0a12010-09-18 01:14:36 +00001392 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1393 interpreter,
1394 "thread step-inst",
1395 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001396 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001397 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1398 eStepTypeTrace,
1399 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001400
Greg Clayton238c0a12010-09-18 01:14:36 +00001401 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1402 interpreter,
1403 "thread step-inst-over",
1404 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001405 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001406 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1407 eStepTypeTraceOver,
1408 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001409}
1410
1411CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1412{
1413}
1414
1415