blob: 806861976bf3584a9492d6a2e9e90abbc0ae4fa2 [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 Ingham84cdc152010-06-15 19:49:27 +000016#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/State.h"
18#include "lldb/Core/SourceManager.h"
19
Greg Claytoncd548032011-02-01 01:31:41 +000020#include "lldb/Host/Host.h"
21
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
24
25#include "lldb/Target/Process.h"
26#include "lldb/Target/RegisterContext.h"
27#include "lldb/Target/Target.h"
28#include "lldb/Target/Thread.h"
29#include "lldb/Target/ThreadPlan.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030#include "lldb/Target/ThreadPlanStepInstruction.h"
31#include "lldb/Target/ThreadPlanStepOut.h"
32#include "lldb/Target/ThreadPlanStepRange.h"
33#include "lldb/Target/ThreadPlanStepInRange.h"
34#include "lldb/Symbol/LineTable.h"
35#include "lldb/Symbol/LineEntry.h"
36
37using namespace lldb;
38using namespace lldb_private;
39
40
Chris Lattner24943d22010-06-08 16:52:24 +000041//-------------------------------------------------------------------------
42// CommandObjectThreadBacktrace
43//-------------------------------------------------------------------------
44
45class CommandObjectThreadBacktrace : public CommandObject
46{
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)
78 error.SetErrorStringWithFormat("Invalid integer value for option '%c'.\n", short_option);
79 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)
90 error.SetErrorStringWithFormat("Invalid integer value for option '%c'.\n", short_option);
91 }
92 break;
93 default:
94 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
95 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) :
124 CommandObject (interpreter,
125 "thread backtrace",
Caroline Tice31fbb642010-09-08 22:08:58 +0000126 "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.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000127 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000128 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
Greg Clayton63094e02010-06-23 01:19:29 +0000155 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000156 Execute (Args& command, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000157 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000158 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000159 Stream &strm = result.GetOutputStream();
160
161 // Don't show source context when doing backtraces.
162 const uint32_t num_frames_with_source = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000163 if (command.GetArgumentCount() == 0)
164 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000165 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000166 if (exe_ctx.thread)
167 {
Johnny Chen2d268cb2011-06-02 18:02:15 +0000168 // Thread::GetStatus() returns the number of frames shown.
Greg Claytonabe0fed2011-04-18 08:33:37 +0000169 if (exe_ctx.thread->GetStatus (strm,
170 m_options.m_start,
171 m_options.m_count,
172 num_frames_with_source))
Chris Lattner24943d22010-06-08 16:52:24 +0000173 {
174 result.SetStatus (eReturnStatusSuccessFinishResult);
175 }
176 }
177 else
178 {
179 result.AppendError ("invalid thread");
180 result.SetStatus (eReturnStatusFailed);
181 }
182 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000183 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
184 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000185 Process *process = m_interpreter.GetExecutionContext().process;
Jim Inghameb10f7b2010-08-27 00:58:05 +0000186 uint32_t num_threads = process->GetThreadList().GetSize();
187 for (uint32_t i = 0; i < num_threads; i++)
188 {
189 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
Johnny Chen05750a62011-06-01 23:19:52 +0000190 if (!thread_sp->GetStatus (strm,
191 m_options.m_start,
192 m_options.m_count,
193 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000194 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000195 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
Jim Inghameb10f7b2010-08-27 00:58:05 +0000196 result.SetStatus (eReturnStatusFailed);
197 return false;
198 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000199 }
200 }
Chris Lattner24943d22010-06-08 16:52:24 +0000201 else
202 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000203 uint32_t num_args = command.GetArgumentCount();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000204 Process *process = m_interpreter.GetExecutionContext().process;
Jim Inghameb10f7b2010-08-27 00:58:05 +0000205 std::vector<ThreadSP> thread_sps;
206
207 for (uint32_t i = 0; i < num_args; i++)
208 {
209 bool success;
210
211 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
212 if (!success)
213 {
214 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
215 result.SetStatus (eReturnStatusFailed);
216 return false;
217 }
218
219 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
220
221 if (!thread_sps[i])
222 {
223 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
224 result.SetStatus (eReturnStatusFailed);
225 return false;
226 }
227
228 }
229
230 for (uint32_t i = 0; i < num_args; i++)
231 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000232 if (!thread_sps[i]->GetStatus (strm,
233 m_options.m_start,
234 m_options.m_count,
235 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000236 {
237 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
238 result.SetStatus (eReturnStatusFailed);
239 return false;
240 }
241
242 if (i < num_args - 1)
243 result.AppendMessage("");
244 }
Chris Lattner24943d22010-06-08 16:52:24 +0000245 }
246 return result.Succeeded();
247 }
248protected:
Jim Ingham8ab1a802010-08-26 23:36:03 +0000249 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000250};
251
Greg Claytonb3448432011-03-24 21:19:54 +0000252OptionDefinition
Jim Ingham8ab1a802010-08-26 23:36:03 +0000253CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
254{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000255{ 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 +0000256{ 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 +0000257{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham8ab1a802010-08-26 23:36:03 +0000258};
Chris Lattner24943d22010-06-08 16:52:24 +0000259
Greg Claytonc0418152010-07-07 17:07:17 +0000260enum StepScope
Chris Lattner24943d22010-06-08 16:52:24 +0000261{
262 eStepScopeSource,
263 eStepScopeInstruction
264};
265
266class CommandObjectThreadStepWithTypeAndScope : public CommandObject
267{
268public:
269
270 class CommandOptions : public Options
271 {
272 public:
273
Greg Claytonf15996e2011-04-07 22:46:35 +0000274 CommandOptions (CommandInterpreter &interpreter) :
275 Options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000276 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000277 // Keep default values of all options in one place: OptionParsingStarting ()
278 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000279 }
280
281 virtual
282 ~CommandOptions ()
283 {
284 }
285
286 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000287 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000288 {
289 Error error;
290 char short_option = (char) m_getopt_table[option_idx].val;
291
292 switch (short_option)
293 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000294 case 'a':
Chris Lattner24943d22010-06-08 16:52:24 +0000295 {
296 bool success;
297 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
298 if (!success)
299 error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
300 }
301 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000302
303 case 'm':
Chris Lattner24943d22010-06-08 16:52:24 +0000304 {
305 bool found_one = false;
306 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
307 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
308 if (!found_one)
309 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
310 }
311 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000312
313 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000314 {
315 m_avoid_regexp.clear();
316 m_avoid_regexp.assign(option_arg);
317 }
318 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000319
320 default:
321 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
322 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000323
324 }
325 return error;
326 }
327
328 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000329 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000330 {
Chris Lattner24943d22010-06-08 16:52:24 +0000331 m_avoid_no_debug = true;
332 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000333 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000334 }
335
Greg Claytonb3448432011-03-24 21:19:54 +0000336 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000337 GetDefinitions ()
338 {
339 return g_option_table;
340 }
341
342 // Options table: Required for subclasses of Options.
343
Greg Claytonb3448432011-03-24 21:19:54 +0000344 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000345
346 // Instance variables to hold the values for command options.
347 bool m_avoid_no_debug;
348 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000349 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000350 };
351
Greg Clayton238c0a12010-09-18 01:14:36 +0000352 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
353 const char *name,
354 const char *help,
355 const char *syntax,
356 uint32_t flags,
357 StepType step_type,
358 StepScope step_scope) :
359 CommandObject (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000360 m_step_type (step_type),
361 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000362 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000363 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000364 CommandArgumentEntry arg;
365 CommandArgumentData thread_id_arg;
366
367 // Define the first (and only) variant of this arg.
368 thread_id_arg.arg_type = eArgTypeThreadID;
369 thread_id_arg.arg_repetition = eArgRepeatOptional;
370
371 // There is only one variant this argument could be; put it into the argument entry.
372 arg.push_back (thread_id_arg);
373
374 // Push the data for the first argument into the m_arguments vector.
375 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000376 }
377
378 virtual
379 ~CommandObjectThreadStepWithTypeAndScope ()
380 {
381 }
382
383 virtual
384 Options *
385 GetOptions ()
386 {
387 return &m_options;
388 }
389
390 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000391 Execute
392 (
Greg Clayton63094e02010-06-23 01:19:29 +0000393 Args& command,
394 CommandReturnObject &result
395 )
Chris Lattner24943d22010-06-08 16:52:24 +0000396 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000397 Process *process = m_interpreter.GetExecutionContext().process;
Greg Clayton238c0a12010-09-18 01:14:36 +0000398 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000399
400 if (process == NULL)
401 {
402 result.AppendError ("need a valid process to step");
403 result.SetStatus (eReturnStatusFailed);
404
405 }
406 else
407 {
408 const uint32_t num_threads = process->GetThreadList().GetSize();
409 Thread *thread = NULL;
410
411 if (command.GetArgumentCount() == 0)
412 {
Jim Inghamc8332952010-08-26 21:32:51 +0000413 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000414 if (thread == NULL)
415 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000416 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000417 result.SetStatus (eReturnStatusFailed);
418 return false;
419 }
420 }
421 else
422 {
423 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
424 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
425 if (step_thread_idx == LLDB_INVALID_INDEX32)
426 {
427 result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr);
428 result.SetStatus (eReturnStatusFailed);
429 return false;
430 }
431 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
432 if (thread == NULL)
433 {
434 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
435 step_thread_idx, 0, num_threads);
436 result.SetStatus (eReturnStatusFailed);
437 return false;
438 }
439 }
440
441 const bool abort_other_plans = false;
442 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
443
444 // This is a bit unfortunate, but not all the commands in this command object support
445 // only while stepping, so I use the bool for them.
446 bool bool_stop_other_threads;
447 if (m_options.m_run_mode == eAllThreads)
448 bool_stop_other_threads = false;
449 else
450 bool_stop_other_threads = true;
451
452 if (m_step_type == eStepTypeInto)
453 {
454 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
455 ThreadPlan *new_plan;
456
457 if (frame->HasDebugInformation ())
458 {
459 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
460 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
461 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000462 stop_other_threads,
463 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000464 if (new_plan && !m_options.m_avoid_regexp.empty())
465 {
466 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
467 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
468 }
Chris Lattner24943d22010-06-08 16:52:24 +0000469 }
470 else
471 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
472
Jim Inghamc8332952010-08-26 21:32:51 +0000473 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000474 process->Resume ();
475 }
476 else if (m_step_type == eStepTypeOver)
477 {
478 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
479 ThreadPlan *new_plan;
480
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
493 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
494 // Maybe there should be a parameter to control this.
495 new_plan->SetOkayToDiscard(false);
496
Jim Inghamc8332952010-08-26 21:32:51 +0000497 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000498 process->Resume ();
499 }
500 else if (m_step_type == eStepTypeTrace)
501 {
502 thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000503 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000504 process->Resume ();
505 }
506 else if (m_step_type == eStepTypeTraceOver)
507 {
508 thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000509 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000510 process->Resume ();
511 }
512 else if (m_step_type == eStepTypeOut)
513 {
514 ThreadPlan *new_plan;
515
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000516 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
517 NULL,
518 false,
519 bool_stop_other_threads,
520 eVoteYes,
521 eVoteNoOpinion,
522 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000523 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
524 // Maybe there should be a parameter to control this.
525 new_plan->SetOkayToDiscard(false);
526
Jim Inghamc8332952010-08-26 21:32:51 +0000527 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000528 process->Resume ();
529 }
530 else
531 {
532 result.AppendError ("step type is not supported");
533 result.SetStatus (eReturnStatusFailed);
534 }
535 if (synchronous_execution)
536 {
537 StateType state = process->WaitForProcessToStop (NULL);
538
539 //EventSP event_sp;
540 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
541 //while (! StateIsStoppedState (state))
542 // {
543 // state = process->WaitForStateChangedEvents (NULL, event_sp);
544 // }
Jim Inghamc8332952010-08-26 21:32:51 +0000545 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000546 result.SetDidChangeProcessState (true);
547 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
548 result.SetStatus (eReturnStatusSuccessFinishNoResult);
549 }
550 }
551 return result.Succeeded();
552 }
553
554protected:
555 StepType m_step_type;
556 StepScope m_step_scope;
557 CommandOptions m_options;
558};
559
Greg Claytonb3448432011-03-24 21:19:54 +0000560static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000561g_tri_running_mode[] =
562{
Greg Claytonfe424a92010-09-18 03:37:20 +0000563{ eOnlyThisThread, "this-thread", "Run only this thread"},
564{ eAllThreads, "all-threads", "Run all threads"},
565{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000566{ 0, NULL, NULL }
567};
568
Greg Claytonb3448432011-03-24 21:19:54 +0000569static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000570g_duo_running_mode[] =
571{
Greg Claytonfe424a92010-09-18 03:37:20 +0000572{ eOnlyThisThread, "this-thread", "Run only this thread"},
573{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000574{ 0, NULL, NULL }
575};
576
Greg Claytonb3448432011-03-24 21:19:54 +0000577OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000578CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
579{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000580{ 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."},
581{ 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."},
582{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
583{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000584};
585
586
587//-------------------------------------------------------------------------
588// CommandObjectThreadContinue
589//-------------------------------------------------------------------------
590
591class CommandObjectThreadContinue : public CommandObject
592{
593public:
594
Greg Clayton238c0a12010-09-18 01:14:36 +0000595 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
596 CommandObject (interpreter,
597 "thread continue",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000598 "Continue execution of one or more threads in an active process.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000599 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000600 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
601 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000602 CommandArgumentEntry arg;
603 CommandArgumentData thread_idx_arg;
604
605 // Define the first (and only) variant of this arg.
606 thread_idx_arg.arg_type = eArgTypeThreadIndex;
607 thread_idx_arg.arg_repetition = eArgRepeatPlus;
608
609 // There is only one variant this argument could be; put it into the argument entry.
610 arg.push_back (thread_idx_arg);
611
612 // Push the data for the first argument into the m_arguments vector.
613 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000614 }
615
616
617 virtual
618 ~CommandObjectThreadContinue ()
619 {
620 }
621
622 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000623 Execute
624 (
Greg Clayton63094e02010-06-23 01:19:29 +0000625 Args& command,
626 CommandReturnObject &result
627 )
Chris Lattner24943d22010-06-08 16:52:24 +0000628 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000629 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000630
Greg Clayton238c0a12010-09-18 01:14:36 +0000631 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000632 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000633 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000634 result.SetStatus (eReturnStatusFailed);
635 return false;
636 }
637
Greg Claytonb72d0f02011-04-12 05:54:46 +0000638 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000639 if (process == NULL)
640 {
641 result.AppendError ("no process exists. Cannot continue");
642 result.SetStatus (eReturnStatusFailed);
643 return false;
644 }
645
646 StateType state = process->GetState();
647 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
648 {
649 const uint32_t num_threads = process->GetThreadList().GetSize();
650 uint32_t idx;
651 const size_t argc = command.GetArgumentCount();
652 if (argc > 0)
653 {
654 std::vector<uint32_t> resume_thread_indexes;
655 for (uint32_t i=0; i<argc; ++i)
656 {
657 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
658 if (idx < num_threads)
659 resume_thread_indexes.push_back(idx);
660 else
661 result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
662 }
663
664 if (resume_thread_indexes.empty())
665 {
666 result.AppendError ("no valid thread indexes were specified");
667 result.SetStatus (eReturnStatusFailed);
668 return false;
669 }
670 else
671 {
672 result.AppendMessage ("Resuming thread ");
673 for (idx=0; idx<num_threads; ++idx)
674 {
675 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
676 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
677 {
678 result.AppendMessageWithFormat ("%u ", idx);
679 thread->SetResumeState (eStateRunning);
680 }
681 else
682 {
683 thread->SetResumeState (eStateSuspended);
684 }
685 }
686 result.AppendMessageWithFormat ("in process %i\n", process->GetID());
687 }
688 }
689 else
690 {
Jim Inghamc8332952010-08-26 21:32:51 +0000691 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000692 if (current_thread == NULL)
693 {
694 result.AppendError ("the process doesn't have a current thread");
695 result.SetStatus (eReturnStatusFailed);
696 return false;
697 }
698 // Set the actions that the threads should each take when resuming
699 for (idx=0; idx<num_threads; ++idx)
700 {
701 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
702 if (thread == current_thread)
703 {
704 result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID());
705 thread->SetResumeState (eStateRunning);
706 }
707 else
708 {
709 thread->SetResumeState (eStateSuspended);
710 }
711 }
712 }
713
714 Error error (process->Resume());
715 if (error.Success())
716 {
Greg Claytonc1d37752010-10-18 01:45:30 +0000717 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000718 if (synchronous_execution)
719 {
Greg Claytonbef15832010-07-14 00:18:15 +0000720 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000721
722 result.SetDidChangeProcessState (true);
723 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
724 result.SetStatus (eReturnStatusSuccessFinishNoResult);
725 }
726 else
727 {
728 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
729 }
730 }
731 else
732 {
733 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
734 result.SetStatus (eReturnStatusFailed);
735 }
736 }
737 else
738 {
739 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
740 StateAsCString(state));
741 result.SetStatus (eReturnStatusFailed);
742 }
743
744 return result.Succeeded();
745 }
746
747};
748
749//-------------------------------------------------------------------------
750// CommandObjectThreadUntil
751//-------------------------------------------------------------------------
752
753class CommandObjectThreadUntil : public CommandObject
754{
755public:
756
757 class CommandOptions : public Options
758 {
759 public:
760 uint32_t m_thread_idx;
761 uint32_t m_frame_idx;
762
Greg Claytonf15996e2011-04-07 22:46:35 +0000763 CommandOptions (CommandInterpreter &interpreter) :
764 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000765 m_thread_idx(LLDB_INVALID_THREAD_ID),
766 m_frame_idx(LLDB_INVALID_FRAME_ID)
767 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000768 // Keep default values of all options in one place: OptionParsingStarting ()
769 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000770 }
771
772 virtual
773 ~CommandOptions ()
774 {
775 }
776
777 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000778 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000779 {
780 Error error;
781 char short_option = (char) m_getopt_table[option_idx].val;
782
783 switch (short_option)
784 {
785 case 't':
786 {
Greg Claytonbef15832010-07-14 00:18:15 +0000787 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000788 if (m_thread_idx == LLDB_INVALID_INDEX32)
789 {
790 error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg);
791 }
792 }
793 break;
794 case 'f':
795 {
796 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
797 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
798 {
799 error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg);
800 }
801 }
802 break;
803 case 'm':
804 {
805 bool found_one = false;
806 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
807 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
808
809 if (!found_one)
810 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
811 else if (run_mode == eAllThreads)
812 m_stop_others = false;
813 else
814 m_stop_others = true;
815
816 }
817 break;
818 default:
819 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
820 break;
821
822 }
823 return error;
824 }
825
826 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000827 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000828 {
Chris Lattner24943d22010-06-08 16:52:24 +0000829 m_thread_idx = LLDB_INVALID_THREAD_ID;
830 m_frame_idx = 0;
831 m_stop_others = false;
832 }
833
Greg Claytonb3448432011-03-24 21:19:54 +0000834 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000835 GetDefinitions ()
836 {
837 return g_option_table;
838 }
839
840 uint32_t m_step_thread_idx;
841 bool m_stop_others;
842
843 // Options table: Required for subclasses of Options.
844
Greg Claytonb3448432011-03-24 21:19:54 +0000845 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000846
847 // Instance variables to hold the values for command options.
848 };
849
Greg Clayton238c0a12010-09-18 01:14:36 +0000850 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
851 CommandObject (interpreter,
852 "thread until",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000853 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000854 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000855 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000856 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000857 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000858 CommandArgumentEntry arg;
859 CommandArgumentData line_num_arg;
860
861 // Define the first (and only) variant of this arg.
862 line_num_arg.arg_type = eArgTypeLineNum;
863 line_num_arg.arg_repetition = eArgRepeatPlain;
864
865 // There is only one variant this argument could be; put it into the argument entry.
866 arg.push_back (line_num_arg);
867
868 // Push the data for the first argument into the m_arguments vector.
869 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000870 }
871
872
873 virtual
874 ~CommandObjectThreadUntil ()
875 {
876 }
877
878 virtual
879 Options *
880 GetOptions ()
881 {
882 return &m_options;
883 }
884
885 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000886 Execute
887 (
Greg Clayton63094e02010-06-23 01:19:29 +0000888 Args& command,
889 CommandReturnObject &result
890 )
Chris Lattner24943d22010-06-08 16:52:24 +0000891 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000892 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000893
Greg Clayton238c0a12010-09-18 01:14:36 +0000894 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000895 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000896 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000897 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000898 result.SetStatus (eReturnStatusFailed);
899 return false;
900 }
901
Greg Claytonb72d0f02011-04-12 05:54:46 +0000902 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000903 if (process == NULL)
904 {
905 result.AppendError ("need a valid process to step");
906 result.SetStatus (eReturnStatusFailed);
907
908 }
909 else
910 {
911 Thread *thread = NULL;
912 uint32_t line_number;
913
914 if (command.GetArgumentCount() != 1)
915 {
916 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
917 result.SetStatus (eReturnStatusFailed);
918 return false;
919 }
920
921 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
922 if (line_number == UINT32_MAX)
923 {
924 result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
925 result.SetStatus (eReturnStatusFailed);
926 return false;
927 }
928
929 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
930 {
Jim Inghamc8332952010-08-26 21:32:51 +0000931 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000932 }
933 else
934 {
935 thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
936 }
937
938 if (thread == NULL)
939 {
940 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000941 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
942 m_options.m_thread_idx,
943 0,
944 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000945 result.SetStatus (eReturnStatusFailed);
946 return false;
947 }
948
949 const bool abort_other_plans = true;
950
951 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
952 if (frame == NULL)
953 {
954
Jim Inghamb07c62a2011-05-08 00:56:32 +0000955 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
956 m_options.m_frame_idx,
957 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000958 result.SetStatus (eReturnStatusFailed);
959 return false;
960 }
961
962 ThreadPlan *new_plan;
963
964 if (frame->HasDebugInformation ())
965 {
966 // Finally we got here... Translate the given line number to a bunch of addresses:
967 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
968 LineTable *line_table = NULL;
969 if (sc.comp_unit)
970 line_table = sc.comp_unit->GetLineTable();
971
972 if (line_table == NULL)
973 {
974 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
975 m_options.m_frame_idx, m_options.m_thread_idx);
976 result.SetStatus (eReturnStatusFailed);
977 return false;
978 }
979
980 LineEntry function_start;
981 uint32_t index_ptr = 0, end_ptr;
982 std::vector<addr_t> address_list;
983
984 // Find the beginning & end index of the
985 AddressRange fun_addr_range = sc.function->GetAddressRange();
986 Address fun_start_addr = fun_addr_range.GetBaseAddress();
987 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
988
Jim Inghamb07c62a2011-05-08 00:56:32 +0000989 Address fun_end_addr(fun_start_addr.GetSection(),
990 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000991 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
992
Jim Inghamb07c62a2011-05-08 00:56:32 +0000993 bool all_in_function = true;
994
Chris Lattner24943d22010-06-08 16:52:24 +0000995 while (index_ptr <= end_ptr)
996 {
997 LineEntry line_entry;
998 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry);
999 if (index_ptr == UINT32_MAX)
1000 break;
1001
Greg Claytoneea26402010-09-14 23:36:40 +00001002 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001003 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001004 {
1005 if (fun_addr_range.ContainsLoadAddress (address, target))
1006 address_list.push_back (address);
1007 else
1008 all_in_function = false;
1009 }
Chris Lattner24943d22010-06-08 16:52:24 +00001010 index_ptr++;
1011 }
1012
Jim Inghamb07c62a2011-05-08 00:56:32 +00001013 if (address_list.size() == 0)
1014 {
1015 if (all_in_function)
1016 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1017 else
1018 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1019
1020 result.SetStatus (eReturnStatusFailed);
1021 return false;
1022 }
1023
1024 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1025 &address_list.front(),
1026 address_list.size(),
1027 m_options.m_stop_others,
1028 thread->GetSelectedFrameIndex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001029 new_plan->SetOkayToDiscard(false);
1030 }
1031 else
1032 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001033 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1034 m_options.m_frame_idx,
1035 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001036 result.SetStatus (eReturnStatusFailed);
1037 return false;
1038
1039 }
1040
Jim Inghamc8332952010-08-26 21:32:51 +00001041 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001042 Error error (process->Resume ());
1043 if (error.Success())
1044 {
Greg Claytonc1d37752010-10-18 01:45:30 +00001045 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001046 if (synchronous_execution)
1047 {
1048 StateType state = process->WaitForProcessToStop (NULL);
1049
1050 result.SetDidChangeProcessState (true);
1051 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
1052 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1053 }
1054 else
1055 {
1056 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1057 }
1058 }
1059 else
1060 {
1061 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1062 result.SetStatus (eReturnStatusFailed);
1063 }
1064
1065 }
1066 return result.Succeeded();
1067 }
1068protected:
1069 CommandOptions m_options;
1070
1071};
1072
Greg Claytonb3448432011-03-24 21:19:54 +00001073OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001074CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1075{
Caroline Tice43b014a2010-10-04 22:28:36 +00001076{ 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 +00001077{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1078{ 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"},
1079{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001080};
1081
1082
1083//-------------------------------------------------------------------------
1084// CommandObjectThreadSelect
1085//-------------------------------------------------------------------------
1086
1087class CommandObjectThreadSelect : public CommandObject
1088{
1089public:
1090
Greg Clayton238c0a12010-09-18 01:14:36 +00001091 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1092 CommandObject (interpreter,
1093 "thread select",
1094 "Select a thread as the currently active thread.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001095 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001096 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001097 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001098 CommandArgumentEntry arg;
1099 CommandArgumentData thread_idx_arg;
1100
1101 // Define the first (and only) variant of this arg.
1102 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1103 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1104
1105 // There is only one variant this argument could be; put it into the argument entry.
1106 arg.push_back (thread_idx_arg);
1107
1108 // Push the data for the first argument into the m_arguments vector.
1109 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001110 }
1111
1112
1113 virtual
1114 ~CommandObjectThreadSelect ()
1115 {
1116 }
1117
1118 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001119 Execute
1120 (
Greg Clayton63094e02010-06-23 01:19:29 +00001121 Args& command,
1122 CommandReturnObject &result
1123 )
Chris Lattner24943d22010-06-08 16:52:24 +00001124 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001125 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +00001126 if (process == NULL)
1127 {
1128 result.AppendError ("no process");
1129 result.SetStatus (eReturnStatusFailed);
1130 return false;
1131 }
1132 else if (command.GetArgumentCount() != 1)
1133 {
1134 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1135 result.SetStatus (eReturnStatusFailed);
1136 return false;
1137 }
1138
1139 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1140
1141 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1142 if (new_thread == NULL)
1143 {
1144 result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1145 result.SetStatus (eReturnStatusFailed);
1146 return false;
1147 }
1148
Jim Inghamc8332952010-08-26 21:32:51 +00001149 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001150 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001151
Greg Claytonabe0fed2011-04-18 08:33:37 +00001152 const uint32_t start_frame = 0;
1153 const uint32_t num_frames = 1;
1154 const uint32_t num_frames_with_source = 1;
1155 new_thread->GetStatus (result.GetOutputStream(),
1156 start_frame,
1157 num_frames,
1158 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001159
1160 return result.Succeeded();
1161 }
1162
1163};
1164
1165
1166//-------------------------------------------------------------------------
1167// CommandObjectThreadList
1168//-------------------------------------------------------------------------
1169
Greg Clayton63094e02010-06-23 01:19:29 +00001170class CommandObjectThreadList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001171{
Greg Clayton63094e02010-06-23 01:19:29 +00001172public:
Chris Lattner24943d22010-06-08 16:52:24 +00001173
Chris Lattner24943d22010-06-08 16:52:24 +00001174
Greg Clayton238c0a12010-09-18 01:14:36 +00001175 CommandObjectThreadList (CommandInterpreter &interpreter):
1176 CommandObject (interpreter,
1177 "thread list",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001178 "Show a summary of all current threads in a process.",
Greg Clayton63094e02010-06-23 01:19:29 +00001179 "thread list",
1180 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001181 {
Greg Clayton63094e02010-06-23 01:19:29 +00001182 }
Chris Lattner24943d22010-06-08 16:52:24 +00001183
Greg Clayton63094e02010-06-23 01:19:29 +00001184 ~CommandObjectThreadList()
1185 {
1186 }
1187
1188 bool
1189 Execute
1190 (
Greg Clayton63094e02010-06-23 01:19:29 +00001191 Args& command,
1192 CommandReturnObject &result
1193 )
1194 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001195 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001196 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001197 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton63094e02010-06-23 01:19:29 +00001198 if (exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +00001199 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001200 const bool only_threads_with_stop_reason = false;
1201 const uint32_t start_frame = 0;
1202 const uint32_t num_frames = 0;
1203 const uint32_t num_frames_with_source = 0;
1204 exe_ctx.process->GetStatus(strm);
1205 exe_ctx.process->GetThreadStatus (strm,
1206 only_threads_with_stop_reason,
1207 start_frame,
1208 num_frames,
1209 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001210 }
1211 else
1212 {
Greg Clayton63094e02010-06-23 01:19:29 +00001213 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001214 result.SetStatus (eReturnStatusFailed);
1215 }
Greg Clayton63094e02010-06-23 01:19:29 +00001216 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001217 }
Greg Clayton63094e02010-06-23 01:19:29 +00001218};
Chris Lattner24943d22010-06-08 16:52:24 +00001219
1220//-------------------------------------------------------------------------
1221// CommandObjectMultiwordThread
1222//-------------------------------------------------------------------------
1223
Greg Clayton63094e02010-06-23 01:19:29 +00001224CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001225 CommandObjectMultiword (interpreter,
1226 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001227 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001228 "thread <subcommand> [<subcommand-options>]")
1229{
Greg Clayton238c0a12010-09-18 01:14:36 +00001230 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1231 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1232 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1233 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1234 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1235 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1236 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001237 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001238 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001239 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001240 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1241 eStepTypeInto,
1242 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001243
Greg Clayton238c0a12010-09-18 01:14:36 +00001244 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1245 interpreter,
1246 "thread step-out",
1247 "Finish executing the current fucntion and return to its call site in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001248 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001249 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1250 eStepTypeOut,
1251 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001252
Greg Clayton238c0a12010-09-18 01:14:36 +00001253 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1254 interpreter,
1255 "thread step-over",
1256 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001257 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001258 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1259 eStepTypeOver,
1260 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001261
Greg Clayton238c0a12010-09-18 01:14:36 +00001262 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1263 interpreter,
1264 "thread step-inst",
1265 "Single step one instruction 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 eStepTypeTrace,
1269 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001270
Greg Clayton238c0a12010-09-18 01:14:36 +00001271 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1272 interpreter,
1273 "thread step-inst-over",
1274 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001275 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001276 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1277 eStepTypeTraceOver,
1278 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001279}
1280
1281CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1282{
1283}
1284
1285