blob: 292b963ab2aaca3e8b866f11ec139a13f008ab3a [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 Ingham7868bcc2011-07-26 02:39:59 +0000199
200 if (i < num_threads - 1)
201 result.AppendMessage("");
202
Jim Inghameb10f7b2010-08-27 00:58:05 +0000203 }
204 }
Chris Lattner24943d22010-06-08 16:52:24 +0000205 else
206 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000207 uint32_t num_args = command.GetArgumentCount();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000208 Process *process = m_interpreter.GetExecutionContext().process;
Jim Inghameb10f7b2010-08-27 00:58:05 +0000209 std::vector<ThreadSP> thread_sps;
210
211 for (uint32_t i = 0; i < num_args; i++)
212 {
213 bool success;
214
215 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
216 if (!success)
217 {
218 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
219 result.SetStatus (eReturnStatusFailed);
220 return false;
221 }
222
223 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
224
225 if (!thread_sps[i])
226 {
227 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
228 result.SetStatus (eReturnStatusFailed);
229 return false;
230 }
231
232 }
233
234 for (uint32_t i = 0; i < num_args; i++)
235 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000236 if (!thread_sps[i]->GetStatus (strm,
237 m_options.m_start,
238 m_options.m_count,
239 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000240 {
241 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
242 result.SetStatus (eReturnStatusFailed);
243 return false;
244 }
245
246 if (i < num_args - 1)
247 result.AppendMessage("");
248 }
Chris Lattner24943d22010-06-08 16:52:24 +0000249 }
250 return result.Succeeded();
251 }
252protected:
Jim Ingham8ab1a802010-08-26 23:36:03 +0000253 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000254};
255
Greg Claytonb3448432011-03-24 21:19:54 +0000256OptionDefinition
Jim Ingham8ab1a802010-08-26 23:36:03 +0000257CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
258{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000259{ 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 +0000260{ 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 +0000261{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham8ab1a802010-08-26 23:36:03 +0000262};
Chris Lattner24943d22010-06-08 16:52:24 +0000263
Greg Claytonc0418152010-07-07 17:07:17 +0000264enum StepScope
Chris Lattner24943d22010-06-08 16:52:24 +0000265{
266 eStepScopeSource,
267 eStepScopeInstruction
268};
269
270class CommandObjectThreadStepWithTypeAndScope : public CommandObject
271{
272public:
273
274 class CommandOptions : public Options
275 {
276 public:
277
Greg Claytonf15996e2011-04-07 22:46:35 +0000278 CommandOptions (CommandInterpreter &interpreter) :
279 Options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000280 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000281 // Keep default values of all options in one place: OptionParsingStarting ()
282 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000283 }
284
285 virtual
286 ~CommandOptions ()
287 {
288 }
289
290 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000291 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000292 {
293 Error error;
294 char short_option = (char) m_getopt_table[option_idx].val;
295
296 switch (short_option)
297 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000298 case 'a':
Chris Lattner24943d22010-06-08 16:52:24 +0000299 {
300 bool success;
301 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
302 if (!success)
303 error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
304 }
305 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000306
307 case 'm':
Chris Lattner24943d22010-06-08 16:52:24 +0000308 {
309 bool found_one = false;
310 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
311 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
312 if (!found_one)
313 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
314 }
315 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000316
317 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000318 {
319 m_avoid_regexp.clear();
320 m_avoid_regexp.assign(option_arg);
321 }
322 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000323
324 default:
325 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
326 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000327
328 }
329 return error;
330 }
331
332 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000333 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000334 {
Chris Lattner24943d22010-06-08 16:52:24 +0000335 m_avoid_no_debug = true;
336 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000337 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000338 }
339
Greg Claytonb3448432011-03-24 21:19:54 +0000340 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000341 GetDefinitions ()
342 {
343 return g_option_table;
344 }
345
346 // Options table: Required for subclasses of Options.
347
Greg Claytonb3448432011-03-24 21:19:54 +0000348 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000349
350 // Instance variables to hold the values for command options.
351 bool m_avoid_no_debug;
352 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000353 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000354 };
355
Greg Clayton238c0a12010-09-18 01:14:36 +0000356 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
357 const char *name,
358 const char *help,
359 const char *syntax,
360 uint32_t flags,
361 StepType step_type,
362 StepScope step_scope) :
363 CommandObject (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000364 m_step_type (step_type),
365 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000366 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000367 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000368 CommandArgumentEntry arg;
369 CommandArgumentData thread_id_arg;
370
371 // Define the first (and only) variant of this arg.
372 thread_id_arg.arg_type = eArgTypeThreadID;
373 thread_id_arg.arg_repetition = eArgRepeatOptional;
374
375 // There is only one variant this argument could be; put it into the argument entry.
376 arg.push_back (thread_id_arg);
377
378 // Push the data for the first argument into the m_arguments vector.
379 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000380 }
381
382 virtual
383 ~CommandObjectThreadStepWithTypeAndScope ()
384 {
385 }
386
387 virtual
388 Options *
389 GetOptions ()
390 {
391 return &m_options;
392 }
393
394 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000395 Execute
396 (
Greg Clayton63094e02010-06-23 01:19:29 +0000397 Args& command,
398 CommandReturnObject &result
399 )
Chris Lattner24943d22010-06-08 16:52:24 +0000400 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000401 Process *process = m_interpreter.GetExecutionContext().process;
Greg Clayton238c0a12010-09-18 01:14:36 +0000402 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000403
404 if (process == NULL)
405 {
406 result.AppendError ("need a valid process to step");
407 result.SetStatus (eReturnStatusFailed);
408
409 }
410 else
411 {
412 const uint32_t num_threads = process->GetThreadList().GetSize();
413 Thread *thread = NULL;
414
415 if (command.GetArgumentCount() == 0)
416 {
Jim Inghamc8332952010-08-26 21:32:51 +0000417 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000418 if (thread == NULL)
419 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000420 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000421 result.SetStatus (eReturnStatusFailed);
422 return false;
423 }
424 }
425 else
426 {
427 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
428 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
429 if (step_thread_idx == LLDB_INVALID_INDEX32)
430 {
431 result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr);
432 result.SetStatus (eReturnStatusFailed);
433 return false;
434 }
435 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
436 if (thread == NULL)
437 {
438 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000439 step_thread_idx, num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000440 result.SetStatus (eReturnStatusFailed);
441 return false;
442 }
443 }
444
445 const bool abort_other_plans = false;
446 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
447
448 // This is a bit unfortunate, but not all the commands in this command object support
449 // only while stepping, so I use the bool for them.
450 bool bool_stop_other_threads;
451 if (m_options.m_run_mode == eAllThreads)
452 bool_stop_other_threads = false;
453 else
454 bool_stop_other_threads = true;
455
456 if (m_step_type == eStepTypeInto)
457 {
458 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
459 ThreadPlan *new_plan;
460
461 if (frame->HasDebugInformation ())
462 {
463 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
464 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
465 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000466 stop_other_threads,
467 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000468 if (new_plan && !m_options.m_avoid_regexp.empty())
469 {
470 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
471 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
472 }
Chris Lattner24943d22010-06-08 16:52:24 +0000473 }
474 else
475 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
476
Jim Inghamc8332952010-08-26 21:32:51 +0000477 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000478 process->Resume ();
479 }
480 else if (m_step_type == eStepTypeOver)
481 {
482 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
483 ThreadPlan *new_plan;
484
485 if (frame->HasDebugInformation())
486 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
487 m_step_type,
488 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
489 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000490 stop_other_threads,
491 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000492 else
493 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
494 abort_other_plans,
495 bool_stop_other_threads);
496
497 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
498 // Maybe there should be a parameter to control this.
499 new_plan->SetOkayToDiscard(false);
500
Jim Inghamc8332952010-08-26 21:32:51 +0000501 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000502 process->Resume ();
503 }
504 else if (m_step_type == eStepTypeTrace)
505 {
506 thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000507 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000508 process->Resume ();
509 }
510 else if (m_step_type == eStepTypeTraceOver)
511 {
512 thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000513 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000514 process->Resume ();
515 }
516 else if (m_step_type == eStepTypeOut)
517 {
518 ThreadPlan *new_plan;
519
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000520 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
521 NULL,
522 false,
523 bool_stop_other_threads,
524 eVoteYes,
525 eVoteNoOpinion,
526 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000527 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
528 // Maybe there should be a parameter to control this.
529 new_plan->SetOkayToDiscard(false);
530
Jim Inghamc8332952010-08-26 21:32:51 +0000531 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000532 process->Resume ();
533 }
534 else
535 {
536 result.AppendError ("step type is not supported");
537 result.SetStatus (eReturnStatusFailed);
538 }
539 if (synchronous_execution)
540 {
541 StateType state = process->WaitForProcessToStop (NULL);
542
543 //EventSP event_sp;
544 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
545 //while (! StateIsStoppedState (state))
546 // {
547 // state = process->WaitForStateChangedEvents (NULL, event_sp);
548 // }
Jim Inghamc8332952010-08-26 21:32:51 +0000549 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000550 result.SetDidChangeProcessState (true);
551 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
552 result.SetStatus (eReturnStatusSuccessFinishNoResult);
553 }
554 }
555 return result.Succeeded();
556 }
557
558protected:
559 StepType m_step_type;
560 StepScope m_step_scope;
561 CommandOptions m_options;
562};
563
Greg Claytonb3448432011-03-24 21:19:54 +0000564static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000565g_tri_running_mode[] =
566{
Greg Claytonfe424a92010-09-18 03:37:20 +0000567{ eOnlyThisThread, "this-thread", "Run only this thread"},
568{ eAllThreads, "all-threads", "Run all threads"},
569{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000570{ 0, NULL, NULL }
571};
572
Greg Claytonb3448432011-03-24 21:19:54 +0000573static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000574g_duo_running_mode[] =
575{
Greg Claytonfe424a92010-09-18 03:37:20 +0000576{ eOnlyThisThread, "this-thread", "Run only this thread"},
577{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000578{ 0, NULL, NULL }
579};
580
Greg Claytonb3448432011-03-24 21:19:54 +0000581OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000582CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
583{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000584{ 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."},
585{ 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."},
586{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
587{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000588};
589
590
591//-------------------------------------------------------------------------
592// CommandObjectThreadContinue
593//-------------------------------------------------------------------------
594
595class CommandObjectThreadContinue : public CommandObject
596{
597public:
598
Greg Clayton238c0a12010-09-18 01:14:36 +0000599 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
600 CommandObject (interpreter,
601 "thread continue",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000602 "Continue execution of one or more threads in an active process.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000603 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000604 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
605 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000606 CommandArgumentEntry arg;
607 CommandArgumentData thread_idx_arg;
608
609 // Define the first (and only) variant of this arg.
610 thread_idx_arg.arg_type = eArgTypeThreadIndex;
611 thread_idx_arg.arg_repetition = eArgRepeatPlus;
612
613 // There is only one variant this argument could be; put it into the argument entry.
614 arg.push_back (thread_idx_arg);
615
616 // Push the data for the first argument into the m_arguments vector.
617 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000618 }
619
620
621 virtual
622 ~CommandObjectThreadContinue ()
623 {
624 }
625
626 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000627 Execute
628 (
Greg Clayton63094e02010-06-23 01:19:29 +0000629 Args& command,
630 CommandReturnObject &result
631 )
Chris Lattner24943d22010-06-08 16:52:24 +0000632 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000633 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000634
Greg Clayton238c0a12010-09-18 01:14:36 +0000635 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000636 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000637 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000638 result.SetStatus (eReturnStatusFailed);
639 return false;
640 }
641
Greg Claytonb72d0f02011-04-12 05:54:46 +0000642 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000643 if (process == NULL)
644 {
645 result.AppendError ("no process exists. Cannot continue");
646 result.SetStatus (eReturnStatusFailed);
647 return false;
648 }
649
650 StateType state = process->GetState();
651 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
652 {
653 const uint32_t num_threads = process->GetThreadList().GetSize();
654 uint32_t idx;
655 const size_t argc = command.GetArgumentCount();
656 if (argc > 0)
657 {
658 std::vector<uint32_t> resume_thread_indexes;
659 for (uint32_t i=0; i<argc; ++i)
660 {
661 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
662 if (idx < num_threads)
663 resume_thread_indexes.push_back(idx);
664 else
665 result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
666 }
667
668 if (resume_thread_indexes.empty())
669 {
670 result.AppendError ("no valid thread indexes were specified");
671 result.SetStatus (eReturnStatusFailed);
672 return false;
673 }
674 else
675 {
676 result.AppendMessage ("Resuming thread ");
677 for (idx=0; idx<num_threads; ++idx)
678 {
679 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
680 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
681 {
682 result.AppendMessageWithFormat ("%u ", idx);
683 thread->SetResumeState (eStateRunning);
684 }
685 else
686 {
687 thread->SetResumeState (eStateSuspended);
688 }
689 }
690 result.AppendMessageWithFormat ("in process %i\n", process->GetID());
691 }
692 }
693 else
694 {
Jim Inghamc8332952010-08-26 21:32:51 +0000695 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000696 if (current_thread == NULL)
697 {
698 result.AppendError ("the process doesn't have a current thread");
699 result.SetStatus (eReturnStatusFailed);
700 return false;
701 }
702 // Set the actions that the threads should each take when resuming
703 for (idx=0; idx<num_threads; ++idx)
704 {
705 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
706 if (thread == current_thread)
707 {
708 result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID());
709 thread->SetResumeState (eStateRunning);
710 }
711 else
712 {
713 thread->SetResumeState (eStateSuspended);
714 }
715 }
716 }
717
718 Error error (process->Resume());
719 if (error.Success())
720 {
Greg Claytonc1d37752010-10-18 01:45:30 +0000721 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000722 if (synchronous_execution)
723 {
Greg Claytonbef15832010-07-14 00:18:15 +0000724 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000725
726 result.SetDidChangeProcessState (true);
727 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
728 result.SetStatus (eReturnStatusSuccessFinishNoResult);
729 }
730 else
731 {
732 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
733 }
734 }
735 else
736 {
737 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
738 result.SetStatus (eReturnStatusFailed);
739 }
740 }
741 else
742 {
743 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
744 StateAsCString(state));
745 result.SetStatus (eReturnStatusFailed);
746 }
747
748 return result.Succeeded();
749 }
750
751};
752
753//-------------------------------------------------------------------------
754// CommandObjectThreadUntil
755//-------------------------------------------------------------------------
756
757class CommandObjectThreadUntil : public CommandObject
758{
759public:
760
761 class CommandOptions : public Options
762 {
763 public:
764 uint32_t m_thread_idx;
765 uint32_t m_frame_idx;
766
Greg Claytonf15996e2011-04-07 22:46:35 +0000767 CommandOptions (CommandInterpreter &interpreter) :
768 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000769 m_thread_idx(LLDB_INVALID_THREAD_ID),
770 m_frame_idx(LLDB_INVALID_FRAME_ID)
771 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000772 // Keep default values of all options in one place: OptionParsingStarting ()
773 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000774 }
775
776 virtual
777 ~CommandOptions ()
778 {
779 }
780
781 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000782 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000783 {
784 Error error;
785 char short_option = (char) m_getopt_table[option_idx].val;
786
787 switch (short_option)
788 {
789 case 't':
790 {
Greg Claytonbef15832010-07-14 00:18:15 +0000791 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000792 if (m_thread_idx == LLDB_INVALID_INDEX32)
793 {
794 error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg);
795 }
796 }
797 break;
798 case 'f':
799 {
800 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
801 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
802 {
803 error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg);
804 }
805 }
806 break;
807 case 'm':
808 {
809 bool found_one = false;
810 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
811 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
812
813 if (!found_one)
814 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
815 else if (run_mode == eAllThreads)
816 m_stop_others = false;
817 else
818 m_stop_others = true;
819
820 }
821 break;
822 default:
823 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
824 break;
825
826 }
827 return error;
828 }
829
830 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000831 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000832 {
Chris Lattner24943d22010-06-08 16:52:24 +0000833 m_thread_idx = LLDB_INVALID_THREAD_ID;
834 m_frame_idx = 0;
835 m_stop_others = false;
836 }
837
Greg Claytonb3448432011-03-24 21:19:54 +0000838 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000839 GetDefinitions ()
840 {
841 return g_option_table;
842 }
843
844 uint32_t m_step_thread_idx;
845 bool m_stop_others;
846
847 // Options table: Required for subclasses of Options.
848
Greg Claytonb3448432011-03-24 21:19:54 +0000849 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000850
851 // Instance variables to hold the values for command options.
852 };
853
Greg Clayton238c0a12010-09-18 01:14:36 +0000854 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
855 CommandObject (interpreter,
856 "thread until",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000857 "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 +0000858 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000859 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000860 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000861 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000862 CommandArgumentEntry arg;
863 CommandArgumentData line_num_arg;
864
865 // Define the first (and only) variant of this arg.
866 line_num_arg.arg_type = eArgTypeLineNum;
867 line_num_arg.arg_repetition = eArgRepeatPlain;
868
869 // There is only one variant this argument could be; put it into the argument entry.
870 arg.push_back (line_num_arg);
871
872 // Push the data for the first argument into the m_arguments vector.
873 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000874 }
875
876
877 virtual
878 ~CommandObjectThreadUntil ()
879 {
880 }
881
882 virtual
883 Options *
884 GetOptions ()
885 {
886 return &m_options;
887 }
888
889 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000890 Execute
891 (
Greg Clayton63094e02010-06-23 01:19:29 +0000892 Args& command,
893 CommandReturnObject &result
894 )
Chris Lattner24943d22010-06-08 16:52:24 +0000895 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000896 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000897
Greg Clayton238c0a12010-09-18 01:14:36 +0000898 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000899 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000900 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000901 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000902 result.SetStatus (eReturnStatusFailed);
903 return false;
904 }
905
Greg Claytonb72d0f02011-04-12 05:54:46 +0000906 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000907 if (process == NULL)
908 {
909 result.AppendError ("need a valid process to step");
910 result.SetStatus (eReturnStatusFailed);
911
912 }
913 else
914 {
915 Thread *thread = NULL;
916 uint32_t line_number;
917
918 if (command.GetArgumentCount() != 1)
919 {
920 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
921 result.SetStatus (eReturnStatusFailed);
922 return false;
923 }
924
925 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
926 if (line_number == UINT32_MAX)
927 {
928 result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
929 result.SetStatus (eReturnStatusFailed);
930 return false;
931 }
932
933 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
934 {
Jim Inghamc8332952010-08-26 21:32:51 +0000935 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000936 }
937 else
938 {
939 thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
940 }
941
942 if (thread == NULL)
943 {
944 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000945 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
946 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000947 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000948 result.SetStatus (eReturnStatusFailed);
949 return false;
950 }
951
952 const bool abort_other_plans = true;
953
954 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
955 if (frame == NULL)
956 {
957
Jim Inghamb07c62a2011-05-08 00:56:32 +0000958 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
959 m_options.m_frame_idx,
960 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000961 result.SetStatus (eReturnStatusFailed);
962 return false;
963 }
964
965 ThreadPlan *new_plan;
966
967 if (frame->HasDebugInformation ())
968 {
969 // Finally we got here... Translate the given line number to a bunch of addresses:
970 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
971 LineTable *line_table = NULL;
972 if (sc.comp_unit)
973 line_table = sc.comp_unit->GetLineTable();
974
975 if (line_table == NULL)
976 {
977 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
978 m_options.m_frame_idx, m_options.m_thread_idx);
979 result.SetStatus (eReturnStatusFailed);
980 return false;
981 }
982
983 LineEntry function_start;
984 uint32_t index_ptr = 0, end_ptr;
985 std::vector<addr_t> address_list;
986
987 // Find the beginning & end index of the
988 AddressRange fun_addr_range = sc.function->GetAddressRange();
989 Address fun_start_addr = fun_addr_range.GetBaseAddress();
990 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
991
Jim Inghamb07c62a2011-05-08 00:56:32 +0000992 Address fun_end_addr(fun_start_addr.GetSection(),
993 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000994 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
995
Jim Inghamb07c62a2011-05-08 00:56:32 +0000996 bool all_in_function = true;
997
Chris Lattner24943d22010-06-08 16:52:24 +0000998 while (index_ptr <= end_ptr)
999 {
1000 LineEntry line_entry;
1001 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry);
1002 if (index_ptr == UINT32_MAX)
1003 break;
1004
Greg Claytoneea26402010-09-14 23:36:40 +00001005 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001006 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001007 {
1008 if (fun_addr_range.ContainsLoadAddress (address, target))
1009 address_list.push_back (address);
1010 else
1011 all_in_function = false;
1012 }
Chris Lattner24943d22010-06-08 16:52:24 +00001013 index_ptr++;
1014 }
1015
Jim Inghamb07c62a2011-05-08 00:56:32 +00001016 if (address_list.size() == 0)
1017 {
1018 if (all_in_function)
1019 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1020 else
1021 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1022
1023 result.SetStatus (eReturnStatusFailed);
1024 return false;
1025 }
1026
1027 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1028 &address_list.front(),
1029 address_list.size(),
1030 m_options.m_stop_others,
1031 thread->GetSelectedFrameIndex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001032 new_plan->SetOkayToDiscard(false);
1033 }
1034 else
1035 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001036 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1037 m_options.m_frame_idx,
1038 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001039 result.SetStatus (eReturnStatusFailed);
1040 return false;
1041
1042 }
1043
Jim Inghamc8332952010-08-26 21:32:51 +00001044 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001045 Error error (process->Resume ());
1046 if (error.Success())
1047 {
Greg Claytonc1d37752010-10-18 01:45:30 +00001048 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001049 if (synchronous_execution)
1050 {
1051 StateType state = process->WaitForProcessToStop (NULL);
1052
1053 result.SetDidChangeProcessState (true);
1054 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
1055 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1056 }
1057 else
1058 {
1059 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1060 }
1061 }
1062 else
1063 {
1064 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1065 result.SetStatus (eReturnStatusFailed);
1066 }
1067
1068 }
1069 return result.Succeeded();
1070 }
1071protected:
1072 CommandOptions m_options;
1073
1074};
1075
Greg Claytonb3448432011-03-24 21:19:54 +00001076OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001077CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1078{
Caroline Tice43b014a2010-10-04 22:28:36 +00001079{ 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 +00001080{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1081{ 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"},
1082{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001083};
1084
1085
1086//-------------------------------------------------------------------------
1087// CommandObjectThreadSelect
1088//-------------------------------------------------------------------------
1089
1090class CommandObjectThreadSelect : public CommandObject
1091{
1092public:
1093
Greg Clayton238c0a12010-09-18 01:14:36 +00001094 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1095 CommandObject (interpreter,
1096 "thread select",
1097 "Select a thread as the currently active thread.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001098 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001099 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001100 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001101 CommandArgumentEntry arg;
1102 CommandArgumentData thread_idx_arg;
1103
1104 // Define the first (and only) variant of this arg.
1105 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1106 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1107
1108 // There is only one variant this argument could be; put it into the argument entry.
1109 arg.push_back (thread_idx_arg);
1110
1111 // Push the data for the first argument into the m_arguments vector.
1112 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001113 }
1114
1115
1116 virtual
1117 ~CommandObjectThreadSelect ()
1118 {
1119 }
1120
1121 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001122 Execute
1123 (
Greg Clayton63094e02010-06-23 01:19:29 +00001124 Args& command,
1125 CommandReturnObject &result
1126 )
Chris Lattner24943d22010-06-08 16:52:24 +00001127 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001128 Process *process = m_interpreter.GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +00001129 if (process == NULL)
1130 {
1131 result.AppendError ("no process");
1132 result.SetStatus (eReturnStatusFailed);
1133 return false;
1134 }
1135 else if (command.GetArgumentCount() != 1)
1136 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001137 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001138 result.SetStatus (eReturnStatusFailed);
1139 return false;
1140 }
1141
1142 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1143
1144 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1145 if (new_thread == NULL)
1146 {
1147 result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1148 result.SetStatus (eReturnStatusFailed);
1149 return false;
1150 }
1151
Jim Inghamc8332952010-08-26 21:32:51 +00001152 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001153 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001154
Greg Claytonabe0fed2011-04-18 08:33:37 +00001155 const uint32_t start_frame = 0;
1156 const uint32_t num_frames = 1;
1157 const uint32_t num_frames_with_source = 1;
1158 new_thread->GetStatus (result.GetOutputStream(),
1159 start_frame,
1160 num_frames,
1161 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001162
1163 return result.Succeeded();
1164 }
1165
1166};
1167
1168
1169//-------------------------------------------------------------------------
1170// CommandObjectThreadList
1171//-------------------------------------------------------------------------
1172
Greg Clayton63094e02010-06-23 01:19:29 +00001173class CommandObjectThreadList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001174{
Greg Clayton63094e02010-06-23 01:19:29 +00001175public:
Chris Lattner24943d22010-06-08 16:52:24 +00001176
Chris Lattner24943d22010-06-08 16:52:24 +00001177
Greg Clayton238c0a12010-09-18 01:14:36 +00001178 CommandObjectThreadList (CommandInterpreter &interpreter):
1179 CommandObject (interpreter,
1180 "thread list",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001181 "Show a summary of all current threads in a process.",
Greg Clayton63094e02010-06-23 01:19:29 +00001182 "thread list",
1183 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001184 {
Greg Clayton63094e02010-06-23 01:19:29 +00001185 }
Chris Lattner24943d22010-06-08 16:52:24 +00001186
Greg Clayton63094e02010-06-23 01:19:29 +00001187 ~CommandObjectThreadList()
1188 {
1189 }
1190
1191 bool
1192 Execute
1193 (
Greg Clayton63094e02010-06-23 01:19:29 +00001194 Args& command,
1195 CommandReturnObject &result
1196 )
1197 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001198 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001199 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001200 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton63094e02010-06-23 01:19:29 +00001201 if (exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +00001202 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001203 const bool only_threads_with_stop_reason = false;
1204 const uint32_t start_frame = 0;
1205 const uint32_t num_frames = 0;
1206 const uint32_t num_frames_with_source = 0;
1207 exe_ctx.process->GetStatus(strm);
1208 exe_ctx.process->GetThreadStatus (strm,
1209 only_threads_with_stop_reason,
1210 start_frame,
1211 num_frames,
1212 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001213 }
1214 else
1215 {
Greg Clayton63094e02010-06-23 01:19:29 +00001216 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001217 result.SetStatus (eReturnStatusFailed);
1218 }
Greg Clayton63094e02010-06-23 01:19:29 +00001219 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001220 }
Greg Clayton63094e02010-06-23 01:19:29 +00001221};
Chris Lattner24943d22010-06-08 16:52:24 +00001222
1223//-------------------------------------------------------------------------
1224// CommandObjectMultiwordThread
1225//-------------------------------------------------------------------------
1226
Greg Clayton63094e02010-06-23 01:19:29 +00001227CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001228 CommandObjectMultiword (interpreter,
1229 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001230 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001231 "thread <subcommand> [<subcommand-options>]")
1232{
Greg Clayton238c0a12010-09-18 01:14:36 +00001233 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1234 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1235 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1236 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1237 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1238 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1239 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001240 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001241 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001242 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001243 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1244 eStepTypeInto,
1245 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001246
Greg Clayton238c0a12010-09-18 01:14:36 +00001247 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1248 interpreter,
1249 "thread step-out",
Peter Collingbourne82ce5402011-06-14 03:55:29 +00001250 "Finish executing the current function and return to its call site in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001251 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001252 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1253 eStepTypeOut,
1254 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001255
Greg Clayton238c0a12010-09-18 01:14:36 +00001256 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1257 interpreter,
1258 "thread step-over",
1259 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001260 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001261 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1262 eStepTypeOver,
1263 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001264
Greg Clayton238c0a12010-09-18 01:14:36 +00001265 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1266 interpreter,
1267 "thread step-inst",
1268 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001269 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001270 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1271 eStepTypeTrace,
1272 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001273
Greg Clayton238c0a12010-09-18 01:14:36 +00001274 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1275 interpreter,
1276 "thread step-inst-over",
1277 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001278 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001279 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1280 eStepTypeTraceOver,
1281 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001282}
1283
1284CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1285{
1286}
1287
1288