blob: 93ecf36fdd278814bfab99624243fe6c32835b2a [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
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Core/State.h"
17#include "lldb/Core/SourceManager.h"
Greg Claytoncd548032011-02-01 01:31:41 +000018#include "lldb/Host/Host.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Interpreter/CommandInterpreter.h"
20#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000021#include "lldb/Interpreter/Options.h"
22#include "lldb/Symbol/CompileUnit.h"
23#include "lldb/Symbol/Function.h"
24#include "lldb/Symbol/LineTable.h"
25#include "lldb/Symbol/LineEntry.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Target/Process.h"
27#include "lldb/Target/RegisterContext.h"
28#include "lldb/Target/Target.h"
29#include "lldb/Target/Thread.h"
30#include "lldb/Target/ThreadPlan.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031#include "lldb/Target/ThreadPlanStepInstruction.h"
32#include "lldb/Target/ThreadPlanStepOut.h"
33#include "lldb/Target/ThreadPlanStepRange.h"
34#include "lldb/Target/ThreadPlanStepInRange.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000035
Chris Lattner24943d22010-06-08 16:52:24 +000036
37using namespace lldb;
38using namespace lldb_private;
39
40
Chris Lattner24943d22010-06-08 16:52:24 +000041//-------------------------------------------------------------------------
42// CommandObjectThreadBacktrace
43//-------------------------------------------------------------------------
44
Jim Inghamda26bd22012-06-08 21:56:10 +000045class CommandObjectThreadBacktrace : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +000046{
47public:
48
Jim Ingham8ab1a802010-08-26 23:36:03 +000049 class CommandOptions : public Options
50 {
51 public:
52
Greg Claytonf15996e2011-04-07 22:46:35 +000053 CommandOptions (CommandInterpreter &interpreter) :
54 Options(interpreter)
Jim Ingham8ab1a802010-08-26 23:36:03 +000055 {
Greg Clayton143fcc32011-04-13 00:18:08 +000056 // Keep default values of all options in one place: OptionParsingStarting ()
57 OptionParsingStarting ();
Jim Ingham8ab1a802010-08-26 23:36:03 +000058 }
59
60 virtual
61 ~CommandOptions ()
62 {
63 }
64
65 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +000066 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham8ab1a802010-08-26 23:36:03 +000067 {
68 Error error;
69 char short_option = (char) m_getopt_table[option_idx].val;
70
71 switch (short_option)
72 {
73 case 'c':
74 {
75 bool success;
76 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
77 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000078 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000079 if (input_count < -1)
80 m_count = UINT32_MAX;
81 else
82 m_count = input_count;
83 }
84 break;
85 case 's':
86 {
87 bool success;
88 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
89 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000090 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000091 }
92 break;
93 default:
Greg Clayton9c236732011-10-26 00:56:27 +000094 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000095 break;
96
97 }
98 return error;
99 }
100
101 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000102 OptionParsingStarting ()
Jim Ingham8ab1a802010-08-26 23:36:03 +0000103 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000104 m_count = UINT32_MAX;
Jim Ingham8ab1a802010-08-26 23:36:03 +0000105 m_start = 0;
106 }
107
Greg Claytonb3448432011-03-24 21:19:54 +0000108 const OptionDefinition*
Jim Ingham8ab1a802010-08-26 23:36:03 +0000109 GetDefinitions ()
110 {
111 return g_option_table;
112 }
113
114 // Options table: Required for subclasses of Options.
115
Greg Claytonb3448432011-03-24 21:19:54 +0000116 static OptionDefinition g_option_table[];
Jim Ingham8ab1a802010-08-26 23:36:03 +0000117
118 // Instance variables to hold the values for command options.
119 uint32_t m_count;
120 uint32_t m_start;
121 };
122
Greg Clayton238c0a12010-09-18 01:14:36 +0000123 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000124 CommandObjectParsed (interpreter,
125 "thread backtrace",
126 "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.",
127 NULL,
128 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000129 m_options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000130 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000131 CommandArgumentEntry arg;
132 CommandArgumentData thread_idx_arg;
133
134 // Define the first (and only) variant of this arg.
135 thread_idx_arg.arg_type = eArgTypeThreadIndex;
136 thread_idx_arg.arg_repetition = eArgRepeatStar;
137
138 // There is only one variant this argument could be; put it into the argument entry.
139 arg.push_back (thread_idx_arg);
140
141 // Push the data for the first argument into the m_arguments vector.
142 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000143 }
144
145 ~CommandObjectThreadBacktrace()
146 {
147 }
148
Jim Ingham8ab1a802010-08-26 23:36:03 +0000149 virtual Options *
150 GetOptions ()
151 {
152 return &m_options;
153 }
Chris Lattner24943d22010-06-08 16:52:24 +0000154
Jim Inghamda26bd22012-06-08 21:56:10 +0000155protected:
Greg Clayton63094e02010-06-23 01:19:29 +0000156 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000157 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000158 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000159 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000160 Stream &strm = result.GetOutputStream();
161
162 // Don't show source context when doing backtraces.
163 const uint32_t num_frames_with_source = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000164 if (command.GetArgumentCount() == 0)
165 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000166 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000167 Thread *thread = exe_ctx.GetThreadPtr();
168 if (thread)
Chris Lattner24943d22010-06-08 16:52:24 +0000169 {
Johnny Chen2d268cb2011-06-02 18:02:15 +0000170 // Thread::GetStatus() returns the number of frames shown.
Greg Clayton567e7f32011-09-22 04:58:26 +0000171 if (thread->GetStatus (strm,
172 m_options.m_start,
173 m_options.m_count,
174 num_frames_with_source))
Chris Lattner24943d22010-06-08 16:52:24 +0000175 {
176 result.SetStatus (eReturnStatusSuccessFinishResult);
177 }
178 }
179 else
180 {
181 result.AppendError ("invalid thread");
182 result.SetStatus (eReturnStatusFailed);
183 }
184 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000185 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
186 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000187 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghamb9950592012-09-10 20:50:15 +0000188 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Inghameb10f7b2010-08-27 00:58:05 +0000189 uint32_t num_threads = process->GetThreadList().GetSize();
190 for (uint32_t i = 0; i < num_threads; i++)
191 {
192 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
Johnny Chen05750a62011-06-01 23:19:52 +0000193 if (!thread_sp->GetStatus (strm,
194 m_options.m_start,
195 m_options.m_count,
196 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000197 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000198 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
Jim Inghameb10f7b2010-08-27 00:58:05 +0000199 result.SetStatus (eReturnStatusFailed);
200 return false;
201 }
Jim Ingham7868bcc2011-07-26 02:39:59 +0000202
203 if (i < num_threads - 1)
204 result.AppendMessage("");
205
Jim Inghameb10f7b2010-08-27 00:58:05 +0000206 }
207 }
Chris Lattner24943d22010-06-08 16:52:24 +0000208 else
209 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000210 uint32_t num_args = command.GetArgumentCount();
Greg Clayton567e7f32011-09-22 04:58:26 +0000211 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghamb9950592012-09-10 20:50:15 +0000212 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Inghameb10f7b2010-08-27 00:58:05 +0000213 std::vector<ThreadSP> thread_sps;
214
215 for (uint32_t i = 0; i < num_args; i++)
216 {
217 bool success;
218
219 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
220 if (!success)
221 {
222 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
223 result.SetStatus (eReturnStatusFailed);
224 return false;
225 }
226
227 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
228
229 if (!thread_sps[i])
230 {
231 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
232 result.SetStatus (eReturnStatusFailed);
233 return false;
234 }
235
236 }
237
238 for (uint32_t i = 0; i < num_args; i++)
239 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000240 if (!thread_sps[i]->GetStatus (strm,
241 m_options.m_start,
242 m_options.m_count,
243 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000244 {
245 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
246 result.SetStatus (eReturnStatusFailed);
247 return false;
248 }
249
250 if (i < num_args - 1)
251 result.AppendMessage("");
252 }
Chris Lattner24943d22010-06-08 16:52:24 +0000253 }
254 return result.Succeeded();
255 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000256
Jim Ingham8ab1a802010-08-26 23:36:03 +0000257 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000258};
259
Greg Claytonb3448432011-03-24 21:19:54 +0000260OptionDefinition
Jim Ingham8ab1a802010-08-26 23:36:03 +0000261CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
262{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000263{ 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 +0000264{ 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 +0000265{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham8ab1a802010-08-26 23:36:03 +0000266};
Chris Lattner24943d22010-06-08 16:52:24 +0000267
Greg Claytonc0418152010-07-07 17:07:17 +0000268enum StepScope
Chris Lattner24943d22010-06-08 16:52:24 +0000269{
270 eStepScopeSource,
271 eStepScopeInstruction
272};
273
Jim Inghamda26bd22012-06-08 21:56:10 +0000274class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000275{
276public:
277
278 class CommandOptions : public Options
279 {
280 public:
281
Greg Claytonf15996e2011-04-07 22:46:35 +0000282 CommandOptions (CommandInterpreter &interpreter) :
283 Options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000284 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000285 // Keep default values of all options in one place: OptionParsingStarting ()
286 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000287 }
288
289 virtual
290 ~CommandOptions ()
291 {
292 }
293
294 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000295 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000296 {
297 Error error;
298 char short_option = (char) m_getopt_table[option_idx].val;
299
300 switch (short_option)
301 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000302 case 'a':
Chris Lattner24943d22010-06-08 16:52:24 +0000303 {
304 bool success;
305 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
306 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000307 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000308 }
309 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000310
311 case 'm':
Chris Lattner24943d22010-06-08 16:52:24 +0000312 {
Chris Lattner24943d22010-06-08 16:52:24 +0000313 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000314 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000315 }
316 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000317
318 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000319 {
320 m_avoid_regexp.clear();
321 m_avoid_regexp.assign(option_arg);
322 }
323 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000324
325 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000326 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8d3802d2010-10-08 04:20:14 +0000327 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000328
329 }
330 return error;
331 }
332
333 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000334 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000335 {
Chris Lattner24943d22010-06-08 16:52:24 +0000336 m_avoid_no_debug = true;
337 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000338 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000339 }
340
Greg Claytonb3448432011-03-24 21:19:54 +0000341 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000342 GetDefinitions ()
343 {
344 return g_option_table;
345 }
346
347 // Options table: Required for subclasses of Options.
348
Greg Claytonb3448432011-03-24 21:19:54 +0000349 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000350
351 // Instance variables to hold the values for command options.
352 bool m_avoid_no_debug;
353 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000354 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000355 };
356
Greg Clayton238c0a12010-09-18 01:14:36 +0000357 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
358 const char *name,
359 const char *help,
360 const char *syntax,
361 uint32_t flags,
362 StepType step_type,
363 StepScope step_scope) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000364 CommandObjectParsed (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000365 m_step_type (step_type),
366 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000367 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000368 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000369 CommandArgumentEntry arg;
370 CommandArgumentData thread_id_arg;
371
372 // Define the first (and only) variant of this arg.
373 thread_id_arg.arg_type = eArgTypeThreadID;
374 thread_id_arg.arg_repetition = eArgRepeatOptional;
375
376 // There is only one variant this argument could be; put it into the argument entry.
377 arg.push_back (thread_id_arg);
378
379 // Push the data for the first argument into the m_arguments vector.
380 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000381 }
382
383 virtual
384 ~CommandObjectThreadStepWithTypeAndScope ()
385 {
386 }
387
388 virtual
389 Options *
390 GetOptions ()
391 {
392 return &m_options;
393 }
394
Jim Inghamda26bd22012-06-08 21:56:10 +0000395protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000396 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000397 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000398 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000399 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton238c0a12010-09-18 01:14:36 +0000400 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000401
402 if (process == NULL)
403 {
404 result.AppendError ("need a valid process to step");
405 result.SetStatus (eReturnStatusFailed);
406
407 }
408 else
409 {
410 const uint32_t num_threads = process->GetThreadList().GetSize();
411 Thread *thread = NULL;
412
413 if (command.GetArgumentCount() == 0)
414 {
Jim Inghamc8332952010-08-26 21:32:51 +0000415 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000416 if (thread == NULL)
417 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000418 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000419 result.SetStatus (eReturnStatusFailed);
420 return false;
421 }
422 }
423 else
424 {
425 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
426 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
427 if (step_thread_idx == LLDB_INVALID_INDEX32)
428 {
Greg Clayton9c236732011-10-26 00:56:27 +0000429 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +0000430 result.SetStatus (eReturnStatusFailed);
431 return false;
432 }
433 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
434 if (thread == NULL)
435 {
436 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000437 step_thread_idx, num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000438 result.SetStatus (eReturnStatusFailed);
439 return false;
440 }
441 }
442
443 const bool abort_other_plans = false;
444 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
445
446 // This is a bit unfortunate, but not all the commands in this command object support
447 // only while stepping, so I use the bool for them.
448 bool bool_stop_other_threads;
449 if (m_options.m_run_mode == eAllThreads)
450 bool_stop_other_threads = false;
451 else
452 bool_stop_other_threads = true;
453
Jim Ingham88e3de22012-05-03 21:19:36 +0000454 ThreadPlan *new_plan = NULL;
455
Chris Lattner24943d22010-06-08 16:52:24 +0000456 if (m_step_type == eStepTypeInto)
457 {
458 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000459
460 if (frame->HasDebugInformation ())
461 {
462 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
463 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
464 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000465 stop_other_threads,
466 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000467 if (new_plan && !m_options.m_avoid_regexp.empty())
468 {
469 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
470 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
471 }
Chris Lattner24943d22010-06-08 16:52:24 +0000472 }
473 else
474 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Ingham88e3de22012-05-03 21:19:36 +0000475
Chris Lattner24943d22010-06-08 16:52:24 +0000476 }
477 else if (m_step_type == eStepTypeOver)
478 {
479 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000480
481 if (frame->HasDebugInformation())
482 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
483 m_step_type,
484 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
485 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000486 stop_other_threads,
487 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000488 else
489 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
490 abort_other_plans,
491 bool_stop_other_threads);
492
Chris Lattner24943d22010-06-08 16:52:24 +0000493 }
494 else if (m_step_type == eStepTypeTrace)
495 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000496 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000497 }
498 else if (m_step_type == eStepTypeTraceOver)
499 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000500 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000501 }
502 else if (m_step_type == eStepTypeOut)
503 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000504 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
505 NULL,
506 false,
507 bool_stop_other_threads,
508 eVoteYes,
509 eVoteNoOpinion,
510 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000511 }
512 else
513 {
514 result.AppendError ("step type is not supported");
515 result.SetStatus (eReturnStatusFailed);
Jim Ingham88e3de22012-05-03 21:19:36 +0000516 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000517 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000518
519 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
520 // so that they can be interruptible). Then resume the process.
521
522 if (new_plan != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000523 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000524 new_plan->SetIsMasterPlan (true);
525 new_plan->SetOkayToDiscard (false);
526
Jim Inghamc8332952010-08-26 21:32:51 +0000527 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Jim Ingham88e3de22012-05-03 21:19:36 +0000528 process->Resume ();
529
530
531 if (synchronous_execution)
532 {
533 StateType state = process->WaitForProcessToStop (NULL);
534
535 //EventSP event_sp;
536 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
537 //while (! StateIsStoppedState (state))
538 // {
539 // state = process->WaitForStateChangedEvents (NULL, event_sp);
540 // }
541 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
542 result.SetDidChangeProcessState (true);
543 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
544 result.SetStatus (eReturnStatusSuccessFinishNoResult);
545 }
Jim Ingham53628e72012-05-16 00:37:40 +0000546 else
547 {
548 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
549 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000550 }
551 else
552 {
553 result.AppendError ("Couldn't find thread plan to implement step type.");
554 result.SetStatus (eReturnStatusFailed);
Chris Lattner24943d22010-06-08 16:52:24 +0000555 }
556 }
557 return result.Succeeded();
558 }
559
560protected:
561 StepType m_step_type;
562 StepScope m_step_scope;
563 CommandOptions m_options;
564};
565
Greg Claytonb3448432011-03-24 21:19:54 +0000566static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000567g_tri_running_mode[] =
568{
Greg Claytonfe424a92010-09-18 03:37:20 +0000569{ eOnlyThisThread, "this-thread", "Run only this thread"},
570{ eAllThreads, "all-threads", "Run all threads"},
571{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000572{ 0, NULL, NULL }
573};
574
Greg Claytonb3448432011-03-24 21:19:54 +0000575static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000576g_duo_running_mode[] =
577{
Greg Claytonfe424a92010-09-18 03:37:20 +0000578{ eOnlyThisThread, "this-thread", "Run only this thread"},
579{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000580{ 0, NULL, NULL }
581};
582
Greg Claytonb3448432011-03-24 21:19:54 +0000583OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000584CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
585{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000586{ 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."},
587{ 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."},
588{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
589{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000590};
591
592
593//-------------------------------------------------------------------------
594// CommandObjectThreadContinue
595//-------------------------------------------------------------------------
596
Jim Inghamda26bd22012-06-08 21:56:10 +0000597class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000598{
599public:
600
Greg Clayton238c0a12010-09-18 01:14:36 +0000601 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000602 CommandObjectParsed (interpreter,
603 "thread continue",
604 "Continue execution of one or more threads in an active process.",
605 NULL,
606 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +0000607 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000608 CommandArgumentEntry arg;
609 CommandArgumentData thread_idx_arg;
610
611 // Define the first (and only) variant of this arg.
612 thread_idx_arg.arg_type = eArgTypeThreadIndex;
613 thread_idx_arg.arg_repetition = eArgRepeatPlus;
614
615 // There is only one variant this argument could be; put it into the argument entry.
616 arg.push_back (thread_idx_arg);
617
618 // Push the data for the first argument into the m_arguments vector.
619 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000620 }
621
622
623 virtual
624 ~CommandObjectThreadContinue ()
625 {
626 }
627
628 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000629 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000630 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000631 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000632
Greg Clayton238c0a12010-09-18 01:14:36 +0000633 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000634 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000635 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000636 result.SetStatus (eReturnStatusFailed);
637 return false;
638 }
639
Greg Clayton567e7f32011-09-22 04:58:26 +0000640 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000641 if (process == NULL)
642 {
643 result.AppendError ("no process exists. Cannot continue");
644 result.SetStatus (eReturnStatusFailed);
645 return false;
646 }
647
648 StateType state = process->GetState();
649 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
650 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000651 Mutex::Locker locker (process->GetThreadList().GetMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000652 const uint32_t num_threads = process->GetThreadList().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000653 const size_t argc = command.GetArgumentCount();
654 if (argc > 0)
655 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000656 std::vector<Thread *> resume_threads;
Chris Lattner24943d22010-06-08 16:52:24 +0000657 for (uint32_t i=0; i<argc; ++i)
658 {
Jim Inghamd07b4f52012-05-31 20:48:41 +0000659 bool success;
660 const int base = 0;
Greg Claytonedd601a2012-07-03 20:54:16 +0000661 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
662 if (success)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000663 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000664 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
665
666 if (thread)
667 {
668 resume_threads.push_back(thread);
669 }
670 else
671 {
672 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
673 result.SetStatus (eReturnStatusFailed);
674 return false;
675 }
Jim Inghamd07b4f52012-05-31 20:48:41 +0000676 }
Chris Lattner24943d22010-06-08 16:52:24 +0000677 else
Jim Inghamd07b4f52012-05-31 20:48:41 +0000678 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000679 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd07b4f52012-05-31 20:48:41 +0000680 result.SetStatus (eReturnStatusFailed);
681 return false;
682 }
Chris Lattner24943d22010-06-08 16:52:24 +0000683 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000684
685 if (resume_threads.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000686 {
687 result.AppendError ("no valid thread indexes were specified");
688 result.SetStatus (eReturnStatusFailed);
689 return false;
690 }
691 else
692 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000693 if (resume_threads.size() == 1)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000694 result.AppendMessageWithFormat ("Resuming thread: ");
695 else
696 result.AppendMessageWithFormat ("Resuming threads: ");
Greg Claytonedd601a2012-07-03 20:54:16 +0000697
698 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000699 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000700 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
701 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Jim Inghamd07b4f52012-05-31 20:48:41 +0000702
Greg Claytonedd601a2012-07-03 20:54:16 +0000703 if (this_thread_pos != resume_threads.end())
Chris Lattner24943d22010-06-08 16:52:24 +0000704 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000705 resume_threads.erase(this_thread_pos);
706 if (resume_threads.size() > 0)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000707 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
708 else
709 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
710
Chris Lattner24943d22010-06-08 16:52:24 +0000711 thread->SetResumeState (eStateRunning);
712 }
713 else
714 {
715 thread->SetResumeState (eStateSuspended);
716 }
717 }
Greg Clayton444e35b2011-10-19 18:09:39 +0000718 result.AppendMessageWithFormat ("in process %llu\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000719 }
720 }
721 else
722 {
Jim Inghamc8332952010-08-26 21:32:51 +0000723 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000724 if (current_thread == NULL)
725 {
726 result.AppendError ("the process doesn't have a current thread");
727 result.SetStatus (eReturnStatusFailed);
728 return false;
729 }
730 // Set the actions that the threads should each take when resuming
Greg Claytonedd601a2012-07-03 20:54:16 +0000731 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000732 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000733 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000734 if (thread == current_thread)
735 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000736 result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000737 thread->SetResumeState (eStateRunning);
738 }
739 else
740 {
741 thread->SetResumeState (eStateSuspended);
742 }
743 }
744 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000745
Chris Lattner24943d22010-06-08 16:52:24 +0000746 Error error (process->Resume());
747 if (error.Success())
748 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000749 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000750 if (synchronous_execution)
751 {
Greg Claytonbef15832010-07-14 00:18:15 +0000752 state = process->WaitForProcessToStop (NULL);
Greg Claytonedd601a2012-07-03 20:54:16 +0000753
Chris Lattner24943d22010-06-08 16:52:24 +0000754 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +0000755 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +0000756 result.SetStatus (eReturnStatusSuccessFinishNoResult);
757 }
758 else
759 {
760 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
761 }
762 }
763 else
764 {
765 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
766 result.SetStatus (eReturnStatusFailed);
767 }
768 }
769 else
770 {
771 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
772 StateAsCString(state));
773 result.SetStatus (eReturnStatusFailed);
774 }
775
776 return result.Succeeded();
777 }
778
779};
780
781//-------------------------------------------------------------------------
782// CommandObjectThreadUntil
783//-------------------------------------------------------------------------
784
Jim Inghamda26bd22012-06-08 21:56:10 +0000785class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000786{
787public:
788
789 class CommandOptions : public Options
790 {
791 public:
792 uint32_t m_thread_idx;
793 uint32_t m_frame_idx;
794
Greg Claytonf15996e2011-04-07 22:46:35 +0000795 CommandOptions (CommandInterpreter &interpreter) :
796 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000797 m_thread_idx(LLDB_INVALID_THREAD_ID),
798 m_frame_idx(LLDB_INVALID_FRAME_ID)
799 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000800 // Keep default values of all options in one place: OptionParsingStarting ()
801 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000802 }
803
804 virtual
805 ~CommandOptions ()
806 {
807 }
808
809 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000810 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000811 {
812 Error error;
813 char short_option = (char) m_getopt_table[option_idx].val;
814
815 switch (short_option)
816 {
817 case 't':
818 {
Greg Claytonbef15832010-07-14 00:18:15 +0000819 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000820 if (m_thread_idx == LLDB_INVALID_INDEX32)
821 {
Greg Clayton9c236732011-10-26 00:56:27 +0000822 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000823 }
824 }
825 break;
826 case 'f':
827 {
828 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
829 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
830 {
Greg Clayton9c236732011-10-26 00:56:27 +0000831 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000832 }
833 }
834 break;
835 case 'm':
836 {
Chris Lattner24943d22010-06-08 16:52:24 +0000837 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000838 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000839
Greg Clayton61aca5d2011-10-07 18:58:12 +0000840 if (error.Success())
841 {
842 if (run_mode == eAllThreads)
843 m_stop_others = false;
844 else
845 m_stop_others = true;
846 }
Chris Lattner24943d22010-06-08 16:52:24 +0000847 }
848 break;
849 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000850 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000851 break;
852
853 }
854 return error;
855 }
856
857 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000858 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000859 {
Chris Lattner24943d22010-06-08 16:52:24 +0000860 m_thread_idx = LLDB_INVALID_THREAD_ID;
861 m_frame_idx = 0;
862 m_stop_others = false;
863 }
864
Greg Claytonb3448432011-03-24 21:19:54 +0000865 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000866 GetDefinitions ()
867 {
868 return g_option_table;
869 }
870
871 uint32_t m_step_thread_idx;
872 bool m_stop_others;
873
874 // Options table: Required for subclasses of Options.
875
Greg Claytonb3448432011-03-24 21:19:54 +0000876 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000877
878 // Instance variables to hold the values for command options.
879 };
880
Greg Clayton238c0a12010-09-18 01:14:36 +0000881 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000882 CommandObjectParsed (interpreter,
883 "thread until",
884 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
885 NULL,
886 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000887 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000888 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000889 CommandArgumentEntry arg;
890 CommandArgumentData line_num_arg;
891
892 // Define the first (and only) variant of this arg.
893 line_num_arg.arg_type = eArgTypeLineNum;
894 line_num_arg.arg_repetition = eArgRepeatPlain;
895
896 // There is only one variant this argument could be; put it into the argument entry.
897 arg.push_back (line_num_arg);
898
899 // Push the data for the first argument into the m_arguments vector.
900 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000901 }
902
903
904 virtual
905 ~CommandObjectThreadUntil ()
906 {
907 }
908
909 virtual
910 Options *
911 GetOptions ()
912 {
913 return &m_options;
914 }
915
Jim Inghamda26bd22012-06-08 21:56:10 +0000916protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000917 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000918 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000919 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000920 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000921
Greg Clayton238c0a12010-09-18 01:14:36 +0000922 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000923 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000924 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000925 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000926 result.SetStatus (eReturnStatusFailed);
927 return false;
928 }
929
Greg Clayton567e7f32011-09-22 04:58:26 +0000930 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000931 if (process == NULL)
932 {
933 result.AppendError ("need a valid process to step");
934 result.SetStatus (eReturnStatusFailed);
935
936 }
937 else
938 {
939 Thread *thread = NULL;
940 uint32_t line_number;
941
942 if (command.GetArgumentCount() != 1)
943 {
944 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
945 result.SetStatus (eReturnStatusFailed);
946 return false;
947 }
948
949 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
950 if (line_number == UINT32_MAX)
951 {
Greg Clayton9c236732011-10-26 00:56:27 +0000952 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +0000953 result.SetStatus (eReturnStatusFailed);
954 return false;
955 }
956
957 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
958 {
Jim Inghamc8332952010-08-26 21:32:51 +0000959 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000960 }
961 else
962 {
Greg Claytona2243772012-05-31 00:29:20 +0000963 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000964 }
965
966 if (thread == NULL)
967 {
968 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000969 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
970 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000971 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000972 result.SetStatus (eReturnStatusFailed);
973 return false;
974 }
975
Jim Inghamd82bc6d2012-05-11 23:47:32 +0000976 const bool abort_other_plans = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000977
978 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
979 if (frame == NULL)
980 {
981
Jim Inghamb07c62a2011-05-08 00:56:32 +0000982 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
983 m_options.m_frame_idx,
984 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000985 result.SetStatus (eReturnStatusFailed);
986 return false;
987 }
988
Jim Ingham88e3de22012-05-03 21:19:36 +0000989 ThreadPlan *new_plan = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000990
991 if (frame->HasDebugInformation ())
992 {
993 // Finally we got here... Translate the given line number to a bunch of addresses:
994 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
995 LineTable *line_table = NULL;
996 if (sc.comp_unit)
997 line_table = sc.comp_unit->GetLineTable();
998
999 if (line_table == NULL)
1000 {
1001 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1002 m_options.m_frame_idx, m_options.m_thread_idx);
1003 result.SetStatus (eReturnStatusFailed);
1004 return false;
1005 }
1006
1007 LineEntry function_start;
1008 uint32_t index_ptr = 0, end_ptr;
1009 std::vector<addr_t> address_list;
1010
1011 // Find the beginning & end index of the
1012 AddressRange fun_addr_range = sc.function->GetAddressRange();
1013 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1014 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1015
Jim Inghamb07c62a2011-05-08 00:56:32 +00001016 Address fun_end_addr(fun_start_addr.GetSection(),
1017 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00001018 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1019
Jim Inghamb07c62a2011-05-08 00:56:32 +00001020 bool all_in_function = true;
1021
Chris Lattner24943d22010-06-08 16:52:24 +00001022 while (index_ptr <= end_ptr)
1023 {
1024 LineEntry line_entry;
Jim Inghamd6d47972011-09-23 00:54:11 +00001025 const bool exact = false;
1026 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +00001027 if (index_ptr == UINT32_MAX)
1028 break;
1029
Greg Claytoneea26402010-09-14 23:36:40 +00001030 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001031 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001032 {
1033 if (fun_addr_range.ContainsLoadAddress (address, target))
1034 address_list.push_back (address);
1035 else
1036 all_in_function = false;
1037 }
Chris Lattner24943d22010-06-08 16:52:24 +00001038 index_ptr++;
1039 }
1040
Jim Inghamb07c62a2011-05-08 00:56:32 +00001041 if (address_list.size() == 0)
1042 {
1043 if (all_in_function)
1044 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1045 else
1046 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1047
1048 result.SetStatus (eReturnStatusFailed);
1049 return false;
1050 }
1051
1052 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1053 &address_list.front(),
1054 address_list.size(),
1055 m_options.m_stop_others,
1056 thread->GetSelectedFrameIndex ());
Jim Ingham88e3de22012-05-03 21:19:36 +00001057 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1058 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1059 // will resume the original plan.
1060 new_plan->SetIsMasterPlan (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001061 new_plan->SetOkayToDiscard(false);
1062 }
1063 else
1064 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001065 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1066 m_options.m_frame_idx,
1067 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001068 result.SetStatus (eReturnStatusFailed);
1069 return false;
1070
1071 }
1072
Jim Inghamc8332952010-08-26 21:32:51 +00001073 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001074 Error error (process->Resume ());
1075 if (error.Success())
1076 {
Greg Clayton444e35b2011-10-19 18:09:39 +00001077 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001078 if (synchronous_execution)
1079 {
1080 StateType state = process->WaitForProcessToStop (NULL);
1081
1082 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +00001083 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +00001084 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1085 }
1086 else
1087 {
1088 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1089 }
1090 }
1091 else
1092 {
1093 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1094 result.SetStatus (eReturnStatusFailed);
1095 }
1096
1097 }
1098 return result.Succeeded();
1099 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001100
Chris Lattner24943d22010-06-08 16:52:24 +00001101 CommandOptions m_options;
1102
1103};
1104
Greg Claytonb3448432011-03-24 21:19:54 +00001105OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001106CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1107{
Caroline Tice43b014a2010-10-04 22:28:36 +00001108{ 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 +00001109{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1110{ 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"},
1111{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001112};
1113
1114
1115//-------------------------------------------------------------------------
1116// CommandObjectThreadSelect
1117//-------------------------------------------------------------------------
1118
Jim Inghamda26bd22012-06-08 21:56:10 +00001119class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001120{
1121public:
1122
Greg Clayton238c0a12010-09-18 01:14:36 +00001123 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001124 CommandObjectParsed (interpreter,
1125 "thread select",
1126 "Select a thread as the currently active thread.",
1127 NULL,
1128 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001129 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001130 CommandArgumentEntry arg;
1131 CommandArgumentData thread_idx_arg;
1132
1133 // Define the first (and only) variant of this arg.
1134 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1135 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1136
1137 // There is only one variant this argument could be; put it into the argument entry.
1138 arg.push_back (thread_idx_arg);
1139
1140 // Push the data for the first argument into the m_arguments vector.
1141 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001142 }
1143
1144
1145 virtual
1146 ~CommandObjectThreadSelect ()
1147 {
1148 }
1149
Jim Inghamda26bd22012-06-08 21:56:10 +00001150protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001151 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001152 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001153 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001154 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001155 if (process == NULL)
1156 {
1157 result.AppendError ("no process");
1158 result.SetStatus (eReturnStatusFailed);
1159 return false;
1160 }
1161 else if (command.GetArgumentCount() != 1)
1162 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001163 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 +00001164 result.SetStatus (eReturnStatusFailed);
1165 return false;
1166 }
1167
1168 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1169
1170 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1171 if (new_thread == NULL)
1172 {
Greg Clayton9c236732011-10-26 00:56:27 +00001173 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +00001174 result.SetStatus (eReturnStatusFailed);
1175 return false;
1176 }
1177
Jim Inghamc8332952010-08-26 21:32:51 +00001178 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001179 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001180
Greg Claytonabe0fed2011-04-18 08:33:37 +00001181 const uint32_t start_frame = 0;
1182 const uint32_t num_frames = 1;
1183 const uint32_t num_frames_with_source = 1;
1184 new_thread->GetStatus (result.GetOutputStream(),
1185 start_frame,
1186 num_frames,
1187 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001188
1189 return result.Succeeded();
1190 }
1191
1192};
1193
1194
1195//-------------------------------------------------------------------------
1196// CommandObjectThreadList
1197//-------------------------------------------------------------------------
1198
Jim Inghamda26bd22012-06-08 21:56:10 +00001199class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001200{
Greg Clayton63094e02010-06-23 01:19:29 +00001201public:
Chris Lattner24943d22010-06-08 16:52:24 +00001202
Chris Lattner24943d22010-06-08 16:52:24 +00001203
Greg Clayton238c0a12010-09-18 01:14:36 +00001204 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Inghamda26bd22012-06-08 21:56:10 +00001205 CommandObjectParsed (interpreter,
1206 "thread list",
1207 "Show a summary of all current threads in a process.",
1208 "thread list",
1209 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001210 {
Greg Clayton63094e02010-06-23 01:19:29 +00001211 }
Chris Lattner24943d22010-06-08 16:52:24 +00001212
Greg Clayton63094e02010-06-23 01:19:29 +00001213 ~CommandObjectThreadList()
1214 {
1215 }
1216
Jim Inghamda26bd22012-06-08 21:56:10 +00001217protected:
Greg Clayton63094e02010-06-23 01:19:29 +00001218 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001219 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton63094e02010-06-23 01:19:29 +00001220 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001221 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001222 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001223 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001224 Process *process = exe_ctx.GetProcessPtr();
1225 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00001226 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001227 const bool only_threads_with_stop_reason = false;
1228 const uint32_t start_frame = 0;
1229 const uint32_t num_frames = 0;
1230 const uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +00001231 process->GetStatus(strm);
1232 process->GetThreadStatus (strm,
1233 only_threads_with_stop_reason,
1234 start_frame,
1235 num_frames,
1236 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001237 }
1238 else
1239 {
Greg Clayton63094e02010-06-23 01:19:29 +00001240 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001241 result.SetStatus (eReturnStatusFailed);
1242 }
Greg Clayton63094e02010-06-23 01:19:29 +00001243 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001244 }
Greg Clayton63094e02010-06-23 01:19:29 +00001245};
Chris Lattner24943d22010-06-08 16:52:24 +00001246
1247//-------------------------------------------------------------------------
1248// CommandObjectMultiwordThread
1249//-------------------------------------------------------------------------
1250
Greg Clayton63094e02010-06-23 01:19:29 +00001251CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001252 CommandObjectMultiword (interpreter,
1253 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001254 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001255 "thread <subcommand> [<subcommand-options>]")
1256{
Greg Clayton238c0a12010-09-18 01:14:36 +00001257 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1258 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1259 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1260 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1261 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1262 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1263 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001264 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001265 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001266 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001267 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1268 eStepTypeInto,
1269 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001270
Greg Clayton238c0a12010-09-18 01:14:36 +00001271 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1272 interpreter,
1273 "thread step-out",
Jim Ingham1586d972011-12-17 01:35:57 +00001274 "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 +00001275 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001276 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1277 eStepTypeOut,
1278 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001279
Greg Clayton238c0a12010-09-18 01:14:36 +00001280 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1281 interpreter,
1282 "thread step-over",
1283 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001284 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001285 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1286 eStepTypeOver,
1287 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001288
Greg Clayton238c0a12010-09-18 01:14:36 +00001289 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1290 interpreter,
1291 "thread step-inst",
1292 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001293 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001294 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1295 eStepTypeTrace,
1296 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001297
Greg Clayton238c0a12010-09-18 01:14:36 +00001298 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1299 interpreter,
1300 "thread step-inst-over",
1301 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001302 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001303 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1304 eStepTypeTraceOver,
1305 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001306}
1307
1308CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1309{
1310}
1311
1312