blob: dfcf75023d5bfafbb3af82395ecb67d532d75093 [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 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000168 if (exe_ctx.thread->GetStatus (strm,
169 m_options.m_start,
170 m_options.m_count,
171 num_frames_with_source))
Chris Lattner24943d22010-06-08 16:52:24 +0000172 {
173 result.SetStatus (eReturnStatusSuccessFinishResult);
174 }
175 }
176 else
177 {
178 result.AppendError ("invalid thread");
179 result.SetStatus (eReturnStatusFailed);
180 }
181 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000182 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
183 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000184 Process *process = m_interpreter.GetExecutionContext().process;
Jim Inghameb10f7b2010-08-27 00:58:05 +0000185 uint32_t num_threads = process->GetThreadList().GetSize();
186 for (uint32_t i = 0; i < num_threads; i++)
187 {
188 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
Johnny Chen05750a62011-06-01 23:19:52 +0000189 if (!thread_sp->GetStatus (strm,
190 m_options.m_start,
191 m_options.m_count,
192 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000193 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000194 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
Jim Inghameb10f7b2010-08-27 00:58:05 +0000195 result.SetStatus (eReturnStatusFailed);
196 return false;
197 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000198 }
199 }
Chris Lattner24943d22010-06-08 16:52:24 +0000200 else
201 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000202 uint32_t num_args = command.GetArgumentCount();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000203 Process *process = m_interpreter.GetExecutionContext().process;
Jim Inghameb10f7b2010-08-27 00:58:05 +0000204 std::vector<ThreadSP> thread_sps;
205
206 for (uint32_t i = 0; i < num_args; i++)
207 {
208 bool success;
209
210 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
211 if (!success)
212 {
213 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
214 result.SetStatus (eReturnStatusFailed);
215 return false;
216 }
217
218 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
219
220 if (!thread_sps[i])
221 {
222 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
223 result.SetStatus (eReturnStatusFailed);
224 return false;
225 }
226
227 }
228
229 for (uint32_t i = 0; i < num_args; i++)
230 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000231 if (!thread_sps[i]->GetStatus (strm,
232 m_options.m_start,
233 m_options.m_count,
234 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000235 {
236 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
237 result.SetStatus (eReturnStatusFailed);
238 return false;
239 }
240
241 if (i < num_args - 1)
242 result.AppendMessage("");
243 }
Chris Lattner24943d22010-06-08 16:52:24 +0000244 }
245 return result.Succeeded();
246 }
247protected:
Jim Ingham8ab1a802010-08-26 23:36:03 +0000248 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000249};
250
Greg Claytonb3448432011-03-24 21:19:54 +0000251OptionDefinition
Jim Ingham8ab1a802010-08-26 23:36:03 +0000252CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
253{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000254{ 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 +0000255{ 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 +0000256{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham8ab1a802010-08-26 23:36:03 +0000257};
Chris Lattner24943d22010-06-08 16:52:24 +0000258
Greg Claytonc0418152010-07-07 17:07:17 +0000259enum StepScope
Chris Lattner24943d22010-06-08 16:52:24 +0000260{
261 eStepScopeSource,
262 eStepScopeInstruction
263};
264
265class CommandObjectThreadStepWithTypeAndScope : public CommandObject
266{
267public:
268
269 class CommandOptions : public Options
270 {
271 public:
272
Greg Claytonf15996e2011-04-07 22:46:35 +0000273 CommandOptions (CommandInterpreter &interpreter) :
274 Options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000275 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000276 // Keep default values of all options in one place: OptionParsingStarting ()
277 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000278 }
279
280 virtual
281 ~CommandOptions ()
282 {
283 }
284
285 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000286 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000287 {
288 Error error;
289 char short_option = (char) m_getopt_table[option_idx].val;
290
291 switch (short_option)
292 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000293 case 'a':
Chris Lattner24943d22010-06-08 16:52:24 +0000294 {
295 bool success;
296 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
297 if (!success)
298 error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
299 }
300 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000301
302 case 'm':
Chris Lattner24943d22010-06-08 16:52:24 +0000303 {
304 bool found_one = false;
305 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
306 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
307 if (!found_one)
308 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
309 }
310 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000311
312 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000313 {
314 m_avoid_regexp.clear();
315 m_avoid_regexp.assign(option_arg);
316 }
317 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000318
319 default:
320 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
321 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000322
323 }
324 return error;
325 }
326
327 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000328 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000329 {
Chris Lattner24943d22010-06-08 16:52:24 +0000330 m_avoid_no_debug = true;
331 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000332 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000333 }
334
Greg Claytonb3448432011-03-24 21:19:54 +0000335 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000336 GetDefinitions ()
337 {
338 return g_option_table;
339 }
340
341 // Options table: Required for subclasses of Options.
342
Greg Claytonb3448432011-03-24 21:19:54 +0000343 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000344
345 // Instance variables to hold the values for command options.
346 bool m_avoid_no_debug;
347 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000348 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000349 };
350
Greg Clayton238c0a12010-09-18 01:14:36 +0000351 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
352 const char *name,
353 const char *help,
354 const char *syntax,
355 uint32_t flags,
356 StepType step_type,
357 StepScope step_scope) :
358 CommandObject (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000359 m_step_type (step_type),
360 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000361 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000362 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000363 CommandArgumentEntry arg;
364 CommandArgumentData thread_id_arg;
365
366 // Define the first (and only) variant of this arg.
367 thread_id_arg.arg_type = eArgTypeThreadID;
368 thread_id_arg.arg_repetition = eArgRepeatOptional;
369
370 // There is only one variant this argument could be; put it into the argument entry.
371 arg.push_back (thread_id_arg);
372
373 // Push the data for the first argument into the m_arguments vector.
374 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000375 }
376
377 virtual
378 ~CommandObjectThreadStepWithTypeAndScope ()
379 {
380 }
381
382 virtual
383 Options *
384 GetOptions ()
385 {
386 return &m_options;
387 }
388
389 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000390 Execute
391 (
Greg Clayton63094e02010-06-23 01:19:29 +0000392 Args& command,
393 CommandReturnObject &result
394 )
Chris Lattner24943d22010-06-08 16:52:24 +0000395 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000396 Process *process = m_interpreter.GetExecutionContext().process;
Greg Clayton238c0a12010-09-18 01:14:36 +0000397 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000398
399 if (process == NULL)
400 {
401 result.AppendError ("need a valid process to step");
402 result.SetStatus (eReturnStatusFailed);
403
404 }
405 else
406 {
407 const uint32_t num_threads = process->GetThreadList().GetSize();
408 Thread *thread = NULL;
409
410 if (command.GetArgumentCount() == 0)
411 {
Jim Inghamc8332952010-08-26 21:32:51 +0000412 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000413 if (thread == NULL)
414 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000415 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000416 result.SetStatus (eReturnStatusFailed);
417 return false;
418 }
419 }
420 else
421 {
422 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
423 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
424 if (step_thread_idx == LLDB_INVALID_INDEX32)
425 {
426 result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr);
427 result.SetStatus (eReturnStatusFailed);
428 return false;
429 }
430 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
431 if (thread == NULL)
432 {
433 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
434 step_thread_idx, 0, num_threads);
435 result.SetStatus (eReturnStatusFailed);
436 return false;
437 }
438 }
439
440 const bool abort_other_plans = false;
441 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
442
443 // This is a bit unfortunate, but not all the commands in this command object support
444 // only while stepping, so I use the bool for them.
445 bool bool_stop_other_threads;
446 if (m_options.m_run_mode == eAllThreads)
447 bool_stop_other_threads = false;
448 else
449 bool_stop_other_threads = true;
450
451 if (m_step_type == eStepTypeInto)
452 {
453 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
454 ThreadPlan *new_plan;
455
456 if (frame->HasDebugInformation ())
457 {
458 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
459 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
460 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000461 stop_other_threads,
462 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000463 if (new_plan && !m_options.m_avoid_regexp.empty())
464 {
465 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
466 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
467 }
Chris Lattner24943d22010-06-08 16:52:24 +0000468 }
469 else
470 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
471
Jim Inghamc8332952010-08-26 21:32:51 +0000472 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000473 process->Resume ();
474 }
475 else if (m_step_type == eStepTypeOver)
476 {
477 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
478 ThreadPlan *new_plan;
479
480 if (frame->HasDebugInformation())
481 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
482 m_step_type,
483 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
484 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000485 stop_other_threads,
486 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000487 else
488 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
489 abort_other_plans,
490 bool_stop_other_threads);
491
492 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
493 // Maybe there should be a parameter to control this.
494 new_plan->SetOkayToDiscard(false);
495
Jim Inghamc8332952010-08-26 21:32:51 +0000496 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000497 process->Resume ();
498 }
499 else if (m_step_type == eStepTypeTrace)
500 {
501 thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000502 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000503 process->Resume ();
504 }
505 else if (m_step_type == eStepTypeTraceOver)
506 {
507 thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000508 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000509 process->Resume ();
510 }
511 else if (m_step_type == eStepTypeOut)
512 {
513 ThreadPlan *new_plan;
514
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000515 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
516 NULL,
517 false,
518 bool_stop_other_threads,
519 eVoteYes,
520 eVoteNoOpinion,
521 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000522 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
523 // Maybe there should be a parameter to control this.
524 new_plan->SetOkayToDiscard(false);
525
Jim Inghamc8332952010-08-26 21:32:51 +0000526 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000527 process->Resume ();
528 }
529 else
530 {
531 result.AppendError ("step type is not supported");
532 result.SetStatus (eReturnStatusFailed);
533 }
534 if (synchronous_execution)
535 {
536 StateType state = process->WaitForProcessToStop (NULL);
537
538 //EventSP event_sp;
539 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
540 //while (! StateIsStoppedState (state))
541 // {
542 // state = process->WaitForStateChangedEvents (NULL, event_sp);
543 // }
Jim Inghamc8332952010-08-26 21:32:51 +0000544 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000545 result.SetDidChangeProcessState (true);
546 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
547 result.SetStatus (eReturnStatusSuccessFinishNoResult);
548 }
549 }
550 return result.Succeeded();
551 }
552
553protected:
554 StepType m_step_type;
555 StepScope m_step_scope;
556 CommandOptions m_options;
557};
558
Greg Claytonb3448432011-03-24 21:19:54 +0000559static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000560g_tri_running_mode[] =
561{
Greg Claytonfe424a92010-09-18 03:37:20 +0000562{ eOnlyThisThread, "this-thread", "Run only this thread"},
563{ eAllThreads, "all-threads", "Run all threads"},
564{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000565{ 0, NULL, NULL }
566};
567
Greg Claytonb3448432011-03-24 21:19:54 +0000568static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000569g_duo_running_mode[] =
570{
Greg Claytonfe424a92010-09-18 03:37:20 +0000571{ eOnlyThisThread, "this-thread", "Run only this thread"},
572{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000573{ 0, NULL, NULL }
574};
575
Greg Claytonb3448432011-03-24 21:19:54 +0000576OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000577CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
578{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000579{ 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."},
580{ 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."},
581{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
582{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000583};
584
585
586//-------------------------------------------------------------------------
587// CommandObjectThreadContinue
588//-------------------------------------------------------------------------
589
590class CommandObjectThreadContinue : public CommandObject
591{
592public:
593
Greg Clayton238c0a12010-09-18 01:14:36 +0000594 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
595 CommandObject (interpreter,
596 "thread continue",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000597 "Continue execution of one or more threads in an active process.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000598 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000599 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
600 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000601 CommandArgumentEntry arg;
602 CommandArgumentData thread_idx_arg;
603
604 // Define the first (and only) variant of this arg.
605 thread_idx_arg.arg_type = eArgTypeThreadIndex;
606 thread_idx_arg.arg_repetition = eArgRepeatPlus;
607
608 // There is only one variant this argument could be; put it into the argument entry.
609 arg.push_back (thread_idx_arg);
610
611 // Push the data for the first argument into the m_arguments vector.
612 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000613 }
614
615
616 virtual
617 ~CommandObjectThreadContinue ()
618 {
619 }
620
621 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000622 Execute
623 (
Greg Clayton63094e02010-06-23 01:19:29 +0000624 Args& command,
625 CommandReturnObject &result
626 )
Chris Lattner24943d22010-06-08 16:52:24 +0000627 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000628 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000629
Greg Clayton238c0a12010-09-18 01:14:36 +0000630 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000631 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000632 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000633 result.SetStatus (eReturnStatusFailed);
634 return false;
635 }
636
Greg Claytonb72d0f02011-04-12 05:54:46 +0000637 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000638 if (process == NULL)
639 {
640 result.AppendError ("no process exists. Cannot continue");
641 result.SetStatus (eReturnStatusFailed);
642 return false;
643 }
644
645 StateType state = process->GetState();
646 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
647 {
648 const uint32_t num_threads = process->GetThreadList().GetSize();
649 uint32_t idx;
650 const size_t argc = command.GetArgumentCount();
651 if (argc > 0)
652 {
653 std::vector<uint32_t> resume_thread_indexes;
654 for (uint32_t i=0; i<argc; ++i)
655 {
656 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
657 if (idx < num_threads)
658 resume_thread_indexes.push_back(idx);
659 else
660 result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
661 }
662
663 if (resume_thread_indexes.empty())
664 {
665 result.AppendError ("no valid thread indexes were specified");
666 result.SetStatus (eReturnStatusFailed);
667 return false;
668 }
669 else
670 {
671 result.AppendMessage ("Resuming thread ");
672 for (idx=0; idx<num_threads; ++idx)
673 {
674 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
675 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
676 {
677 result.AppendMessageWithFormat ("%u ", idx);
678 thread->SetResumeState (eStateRunning);
679 }
680 else
681 {
682 thread->SetResumeState (eStateSuspended);
683 }
684 }
685 result.AppendMessageWithFormat ("in process %i\n", process->GetID());
686 }
687 }
688 else
689 {
Jim Inghamc8332952010-08-26 21:32:51 +0000690 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000691 if (current_thread == NULL)
692 {
693 result.AppendError ("the process doesn't have a current thread");
694 result.SetStatus (eReturnStatusFailed);
695 return false;
696 }
697 // Set the actions that the threads should each take when resuming
698 for (idx=0; idx<num_threads; ++idx)
699 {
700 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
701 if (thread == current_thread)
702 {
703 result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID());
704 thread->SetResumeState (eStateRunning);
705 }
706 else
707 {
708 thread->SetResumeState (eStateSuspended);
709 }
710 }
711 }
712
713 Error error (process->Resume());
714 if (error.Success())
715 {
Greg Claytonc1d37752010-10-18 01:45:30 +0000716 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000717 if (synchronous_execution)
718 {
Greg Claytonbef15832010-07-14 00:18:15 +0000719 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000720
721 result.SetDidChangeProcessState (true);
722 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
723 result.SetStatus (eReturnStatusSuccessFinishNoResult);
724 }
725 else
726 {
727 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
728 }
729 }
730 else
731 {
732 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
733 result.SetStatus (eReturnStatusFailed);
734 }
735 }
736 else
737 {
738 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
739 StateAsCString(state));
740 result.SetStatus (eReturnStatusFailed);
741 }
742
743 return result.Succeeded();
744 }
745
746};
747
748//-------------------------------------------------------------------------
749// CommandObjectThreadUntil
750//-------------------------------------------------------------------------
751
752class CommandObjectThreadUntil : public CommandObject
753{
754public:
755
756 class CommandOptions : public Options
757 {
758 public:
759 uint32_t m_thread_idx;
760 uint32_t m_frame_idx;
761
Greg Claytonf15996e2011-04-07 22:46:35 +0000762 CommandOptions (CommandInterpreter &interpreter) :
763 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000764 m_thread_idx(LLDB_INVALID_THREAD_ID),
765 m_frame_idx(LLDB_INVALID_FRAME_ID)
766 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000767 // Keep default values of all options in one place: OptionParsingStarting ()
768 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000769 }
770
771 virtual
772 ~CommandOptions ()
773 {
774 }
775
776 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000777 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000778 {
779 Error error;
780 char short_option = (char) m_getopt_table[option_idx].val;
781
782 switch (short_option)
783 {
784 case 't':
785 {
Greg Claytonbef15832010-07-14 00:18:15 +0000786 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000787 if (m_thread_idx == LLDB_INVALID_INDEX32)
788 {
789 error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg);
790 }
791 }
792 break;
793 case 'f':
794 {
795 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
796 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
797 {
798 error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg);
799 }
800 }
801 break;
802 case 'm':
803 {
804 bool found_one = false;
805 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
806 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
807
808 if (!found_one)
809 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
810 else if (run_mode == eAllThreads)
811 m_stop_others = false;
812 else
813 m_stop_others = true;
814
815 }
816 break;
817 default:
818 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
819 break;
820
821 }
822 return error;
823 }
824
825 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000826 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000827 {
Chris Lattner24943d22010-06-08 16:52:24 +0000828 m_thread_idx = LLDB_INVALID_THREAD_ID;
829 m_frame_idx = 0;
830 m_stop_others = false;
831 }
832
Greg Claytonb3448432011-03-24 21:19:54 +0000833 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000834 GetDefinitions ()
835 {
836 return g_option_table;
837 }
838
839 uint32_t m_step_thread_idx;
840 bool m_stop_others;
841
842 // Options table: Required for subclasses of Options.
843
Greg Claytonb3448432011-03-24 21:19:54 +0000844 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000845
846 // Instance variables to hold the values for command options.
847 };
848
Greg Clayton238c0a12010-09-18 01:14:36 +0000849 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
850 CommandObject (interpreter,
851 "thread until",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000852 "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 +0000853 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000854 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000855 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000856 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000857 CommandArgumentEntry arg;
858 CommandArgumentData line_num_arg;
859
860 // Define the first (and only) variant of this arg.
861 line_num_arg.arg_type = eArgTypeLineNum;
862 line_num_arg.arg_repetition = eArgRepeatPlain;
863
864 // There is only one variant this argument could be; put it into the argument entry.
865 arg.push_back (line_num_arg);
866
867 // Push the data for the first argument into the m_arguments vector.
868 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000869 }
870
871
872 virtual
873 ~CommandObjectThreadUntil ()
874 {
875 }
876
877 virtual
878 Options *
879 GetOptions ()
880 {
881 return &m_options;
882 }
883
884 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000885 Execute
886 (
Greg Clayton63094e02010-06-23 01:19:29 +0000887 Args& command,
888 CommandReturnObject &result
889 )
Chris Lattner24943d22010-06-08 16:52:24 +0000890 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000891 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000892
Greg Clayton238c0a12010-09-18 01:14:36 +0000893 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000894 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000895 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000896 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000897 result.SetStatus (eReturnStatusFailed);
898 return false;
899 }
900
Greg Claytonb72d0f02011-04-12 05:54:46 +0000901 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000902 if (process == NULL)
903 {
904 result.AppendError ("need a valid process to step");
905 result.SetStatus (eReturnStatusFailed);
906
907 }
908 else
909 {
910 Thread *thread = NULL;
911 uint32_t line_number;
912
913 if (command.GetArgumentCount() != 1)
914 {
915 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
916 result.SetStatus (eReturnStatusFailed);
917 return false;
918 }
919
920 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
921 if (line_number == UINT32_MAX)
922 {
923 result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
924 result.SetStatus (eReturnStatusFailed);
925 return false;
926 }
927
928 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
929 {
Jim Inghamc8332952010-08-26 21:32:51 +0000930 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000931 }
932 else
933 {
934 thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
935 }
936
937 if (thread == NULL)
938 {
939 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000940 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
941 m_options.m_thread_idx,
942 0,
943 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000944 result.SetStatus (eReturnStatusFailed);
945 return false;
946 }
947
948 const bool abort_other_plans = true;
949
950 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
951 if (frame == NULL)
952 {
953
Jim Inghamb07c62a2011-05-08 00:56:32 +0000954 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
955 m_options.m_frame_idx,
956 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000957 result.SetStatus (eReturnStatusFailed);
958 return false;
959 }
960
961 ThreadPlan *new_plan;
962
963 if (frame->HasDebugInformation ())
964 {
965 // Finally we got here... Translate the given line number to a bunch of addresses:
966 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
967 LineTable *line_table = NULL;
968 if (sc.comp_unit)
969 line_table = sc.comp_unit->GetLineTable();
970
971 if (line_table == NULL)
972 {
973 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
974 m_options.m_frame_idx, m_options.m_thread_idx);
975 result.SetStatus (eReturnStatusFailed);
976 return false;
977 }
978
979 LineEntry function_start;
980 uint32_t index_ptr = 0, end_ptr;
981 std::vector<addr_t> address_list;
982
983 // Find the beginning & end index of the
984 AddressRange fun_addr_range = sc.function->GetAddressRange();
985 Address fun_start_addr = fun_addr_range.GetBaseAddress();
986 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
987
Jim Inghamb07c62a2011-05-08 00:56:32 +0000988 Address fun_end_addr(fun_start_addr.GetSection(),
989 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000990 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
991
Jim Inghamb07c62a2011-05-08 00:56:32 +0000992 bool all_in_function = true;
993
Chris Lattner24943d22010-06-08 16:52:24 +0000994 while (index_ptr <= end_ptr)
995 {
996 LineEntry line_entry;
997 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry);
998 if (index_ptr == UINT32_MAX)
999 break;
1000
Greg Claytoneea26402010-09-14 23:36:40 +00001001 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001002 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001003 {
1004 if (fun_addr_range.ContainsLoadAddress (address, target))
1005 address_list.push_back (address);
1006 else
1007 all_in_function = false;
1008 }
Chris Lattner24943d22010-06-08 16:52:24 +00001009 index_ptr++;
1010 }
1011
Jim Inghamb07c62a2011-05-08 00:56:32 +00001012 if (address_list.size() == 0)
1013 {
1014 if (all_in_function)
1015 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1016 else
1017 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1018
1019 result.SetStatus (eReturnStatusFailed);
1020 return false;
1021 }
1022
1023 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1024 &address_list.front(),
1025 address_list.size(),
1026 m_options.m_stop_others,
1027 thread->GetSelectedFrameIndex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001028 new_plan->SetOkayToDiscard(false);
1029 }
1030 else
1031 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001032 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1033 m_options.m_frame_idx,
1034 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001035 result.SetStatus (eReturnStatusFailed);
1036 return false;
1037
1038 }
1039
Jim Inghamc8332952010-08-26 21:32:51 +00001040 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001041 Error error (process->Resume ());
1042 if (error.Success())
1043 {
Greg Claytonc1d37752010-10-18 01:45:30 +00001044 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001045 if (synchronous_execution)
1046 {
1047 StateType state = process->WaitForProcessToStop (NULL);
1048
1049 result.SetDidChangeProcessState (true);
1050 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
1051 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1052 }
1053 else
1054 {
1055 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1056 }
1057 }
1058 else
1059 {
1060 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1061 result.SetStatus (eReturnStatusFailed);
1062 }
1063
1064 }
1065 return result.Succeeded();
1066 }
1067protected:
1068 CommandOptions m_options;
1069
1070};
1071
Greg Claytonb3448432011-03-24 21:19:54 +00001072OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001073CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1074{
Caroline Tice43b014a2010-10-04 22:28:36 +00001075{ 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 +00001076{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1077{ 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"},
1078{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001079};
1080
1081
1082//-------------------------------------------------------------------------
1083// CommandObjectThreadSelect
1084//-------------------------------------------------------------------------
1085
1086class CommandObjectThreadSelect : public CommandObject
1087{
1088public:
1089
Greg Clayton238c0a12010-09-18 01:14:36 +00001090 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1091 CommandObject (interpreter,
1092 "thread select",
1093 "Select a thread as the currently active thread.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001094 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001095 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001096 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001097 CommandArgumentEntry arg;
1098 CommandArgumentData thread_idx_arg;
1099
1100 // Define the first (and only) variant of this arg.
1101 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1102 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1103
1104 // There is only one variant this argument could be; put it into the argument entry.
1105 arg.push_back (thread_idx_arg);
1106
1107 // Push the data for the first argument into the m_arguments vector.
1108 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001109 }
1110
1111
1112 virtual
1113 ~CommandObjectThreadSelect ()
1114 {
1115 }
1116
1117 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001118 Execute
1119 (
Greg Clayton63094e02010-06-23 01:19:29 +00001120 Args& command,
1121 CommandReturnObject &result
1122 )
Chris Lattner24943d22010-06-08 16:52:24 +00001123 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001124 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +00001125 if (process == NULL)
1126 {
1127 result.AppendError ("no process");
1128 result.SetStatus (eReturnStatusFailed);
1129 return false;
1130 }
1131 else if (command.GetArgumentCount() != 1)
1132 {
1133 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1134 result.SetStatus (eReturnStatusFailed);
1135 return false;
1136 }
1137
1138 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1139
1140 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1141 if (new_thread == NULL)
1142 {
1143 result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1144 result.SetStatus (eReturnStatusFailed);
1145 return false;
1146 }
1147
Jim Inghamc8332952010-08-26 21:32:51 +00001148 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001149 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001150
Greg Claytonabe0fed2011-04-18 08:33:37 +00001151 const uint32_t start_frame = 0;
1152 const uint32_t num_frames = 1;
1153 const uint32_t num_frames_with_source = 1;
1154 new_thread->GetStatus (result.GetOutputStream(),
1155 start_frame,
1156 num_frames,
1157 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001158
1159 return result.Succeeded();
1160 }
1161
1162};
1163
1164
1165//-------------------------------------------------------------------------
1166// CommandObjectThreadList
1167//-------------------------------------------------------------------------
1168
Greg Clayton63094e02010-06-23 01:19:29 +00001169class CommandObjectThreadList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001170{
Greg Clayton63094e02010-06-23 01:19:29 +00001171public:
Chris Lattner24943d22010-06-08 16:52:24 +00001172
Chris Lattner24943d22010-06-08 16:52:24 +00001173
Greg Clayton238c0a12010-09-18 01:14:36 +00001174 CommandObjectThreadList (CommandInterpreter &interpreter):
1175 CommandObject (interpreter,
1176 "thread list",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001177 "Show a summary of all current threads in a process.",
Greg Clayton63094e02010-06-23 01:19:29 +00001178 "thread list",
1179 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001180 {
Greg Clayton63094e02010-06-23 01:19:29 +00001181 }
Chris Lattner24943d22010-06-08 16:52:24 +00001182
Greg Clayton63094e02010-06-23 01:19:29 +00001183 ~CommandObjectThreadList()
1184 {
1185 }
1186
1187 bool
1188 Execute
1189 (
Greg Clayton63094e02010-06-23 01:19:29 +00001190 Args& command,
1191 CommandReturnObject &result
1192 )
1193 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001194 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001195 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001196 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton63094e02010-06-23 01:19:29 +00001197 if (exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +00001198 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001199 const bool only_threads_with_stop_reason = false;
1200 const uint32_t start_frame = 0;
1201 const uint32_t num_frames = 0;
1202 const uint32_t num_frames_with_source = 0;
1203 exe_ctx.process->GetStatus(strm);
1204 exe_ctx.process->GetThreadStatus (strm,
1205 only_threads_with_stop_reason,
1206 start_frame,
1207 num_frames,
1208 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001209 }
1210 else
1211 {
Greg Clayton63094e02010-06-23 01:19:29 +00001212 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001213 result.SetStatus (eReturnStatusFailed);
1214 }
Greg Clayton63094e02010-06-23 01:19:29 +00001215 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001216 }
Greg Clayton63094e02010-06-23 01:19:29 +00001217};
Chris Lattner24943d22010-06-08 16:52:24 +00001218
1219//-------------------------------------------------------------------------
1220// CommandObjectMultiwordThread
1221//-------------------------------------------------------------------------
1222
Greg Clayton63094e02010-06-23 01:19:29 +00001223CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001224 CommandObjectMultiword (interpreter,
1225 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001226 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001227 "thread <subcommand> [<subcommand-options>]")
1228{
Greg Clayton238c0a12010-09-18 01:14:36 +00001229 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1230 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1231 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1232 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1233 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1234 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1235 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001236 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001237 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001238 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001239 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1240 eStepTypeInto,
1241 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001242
Greg Clayton238c0a12010-09-18 01:14:36 +00001243 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1244 interpreter,
1245 "thread step-out",
1246 "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 +00001247 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001248 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1249 eStepTypeOut,
1250 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001251
Greg Clayton238c0a12010-09-18 01:14:36 +00001252 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1253 interpreter,
1254 "thread step-over",
1255 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001256 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001257 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1258 eStepTypeOver,
1259 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001260
Greg Clayton238c0a12010-09-18 01:14:36 +00001261 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1262 interpreter,
1263 "thread step-inst",
1264 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001265 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001266 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1267 eStepTypeTrace,
1268 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001269
Greg Clayton238c0a12010-09-18 01:14:36 +00001270 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1271 interpreter,
1272 "thread step-inst-over",
1273 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001274 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001275 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1276 eStepTypeTraceOver,
1277 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001278}
1279
1280CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1281{
1282}
1283
1284