blob: c7bf27622f83a278e41a43dce7f792b42472737c [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());
Greg Clayton567e7f32011-09-22 04:58:26 +0000166 Thread *thread = exe_ctx.GetThreadPtr();
167 if (thread)
Chris Lattner24943d22010-06-08 16:52:24 +0000168 {
Johnny Chen2d268cb2011-06-02 18:02:15 +0000169 // Thread::GetStatus() returns the number of frames shown.
Greg Clayton567e7f32011-09-22 04:58:26 +0000170 if (thread->GetStatus (strm,
171 m_options.m_start,
172 m_options.m_count,
173 num_frames_with_source))
Chris Lattner24943d22010-06-08 16:52:24 +0000174 {
175 result.SetStatus (eReturnStatusSuccessFinishResult);
176 }
177 }
178 else
179 {
180 result.AppendError ("invalid thread");
181 result.SetStatus (eReturnStatusFailed);
182 }
183 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000184 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
185 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000186 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghameb10f7b2010-08-27 00:58:05 +0000187 uint32_t num_threads = process->GetThreadList().GetSize();
188 for (uint32_t i = 0; i < num_threads; i++)
189 {
190 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
Johnny Chen05750a62011-06-01 23:19:52 +0000191 if (!thread_sp->GetStatus (strm,
192 m_options.m_start,
193 m_options.m_count,
194 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000195 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000196 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
Jim Inghameb10f7b2010-08-27 00:58:05 +0000197 result.SetStatus (eReturnStatusFailed);
198 return false;
199 }
Jim Ingham7868bcc2011-07-26 02:39:59 +0000200
201 if (i < num_threads - 1)
202 result.AppendMessage("");
203
Jim Inghameb10f7b2010-08-27 00:58:05 +0000204 }
205 }
Chris Lattner24943d22010-06-08 16:52:24 +0000206 else
207 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000208 uint32_t num_args = command.GetArgumentCount();
Greg Clayton567e7f32011-09-22 04:58:26 +0000209 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghameb10f7b2010-08-27 00:58:05 +0000210 std::vector<ThreadSP> thread_sps;
211
212 for (uint32_t i = 0; i < num_args; i++)
213 {
214 bool success;
215
216 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
217 if (!success)
218 {
219 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
220 result.SetStatus (eReturnStatusFailed);
221 return false;
222 }
223
224 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
225
226 if (!thread_sps[i])
227 {
228 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
229 result.SetStatus (eReturnStatusFailed);
230 return false;
231 }
232
233 }
234
235 for (uint32_t i = 0; i < num_args; i++)
236 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000237 if (!thread_sps[i]->GetStatus (strm,
238 m_options.m_start,
239 m_options.m_count,
240 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000241 {
242 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
243 result.SetStatus (eReturnStatusFailed);
244 return false;
245 }
246
247 if (i < num_args - 1)
248 result.AppendMessage("");
249 }
Chris Lattner24943d22010-06-08 16:52:24 +0000250 }
251 return result.Succeeded();
252 }
253protected:
Jim Ingham8ab1a802010-08-26 23:36:03 +0000254 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000255};
256
Greg Claytonb3448432011-03-24 21:19:54 +0000257OptionDefinition
Jim Ingham8ab1a802010-08-26 23:36:03 +0000258CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
259{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000260{ 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 +0000261{ 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 +0000262{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham8ab1a802010-08-26 23:36:03 +0000263};
Chris Lattner24943d22010-06-08 16:52:24 +0000264
Greg Claytonc0418152010-07-07 17:07:17 +0000265enum StepScope
Chris Lattner24943d22010-06-08 16:52:24 +0000266{
267 eStepScopeSource,
268 eStepScopeInstruction
269};
270
271class CommandObjectThreadStepWithTypeAndScope : public CommandObject
272{
273public:
274
275 class CommandOptions : public Options
276 {
277 public:
278
Greg Claytonf15996e2011-04-07 22:46:35 +0000279 CommandOptions (CommandInterpreter &interpreter) :
280 Options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000281 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000282 // Keep default values of all options in one place: OptionParsingStarting ()
283 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000284 }
285
286 virtual
287 ~CommandOptions ()
288 {
289 }
290
291 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000292 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000293 {
294 Error error;
295 char short_option = (char) m_getopt_table[option_idx].val;
296
297 switch (short_option)
298 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000299 case 'a':
Chris Lattner24943d22010-06-08 16:52:24 +0000300 {
301 bool success;
302 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
303 if (!success)
304 error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
305 }
306 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000307
308 case 'm':
Chris Lattner24943d22010-06-08 16:52:24 +0000309 {
Chris Lattner24943d22010-06-08 16:52:24 +0000310 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000311 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000312 }
313 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000314
315 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000316 {
317 m_avoid_regexp.clear();
318 m_avoid_regexp.assign(option_arg);
319 }
320 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000321
322 default:
323 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
324 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000325
326 }
327 return error;
328 }
329
330 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000331 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000332 {
Chris Lattner24943d22010-06-08 16:52:24 +0000333 m_avoid_no_debug = true;
334 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000335 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000336 }
337
Greg Claytonb3448432011-03-24 21:19:54 +0000338 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000339 GetDefinitions ()
340 {
341 return g_option_table;
342 }
343
344 // Options table: Required for subclasses of Options.
345
Greg Claytonb3448432011-03-24 21:19:54 +0000346 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000347
348 // Instance variables to hold the values for command options.
349 bool m_avoid_no_debug;
350 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000351 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000352 };
353
Greg Clayton238c0a12010-09-18 01:14:36 +0000354 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
355 const char *name,
356 const char *help,
357 const char *syntax,
358 uint32_t flags,
359 StepType step_type,
360 StepScope step_scope) :
361 CommandObject (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000362 m_step_type (step_type),
363 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000364 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000365 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000366 CommandArgumentEntry arg;
367 CommandArgumentData thread_id_arg;
368
369 // Define the first (and only) variant of this arg.
370 thread_id_arg.arg_type = eArgTypeThreadID;
371 thread_id_arg.arg_repetition = eArgRepeatOptional;
372
373 // There is only one variant this argument could be; put it into the argument entry.
374 arg.push_back (thread_id_arg);
375
376 // Push the data for the first argument into the m_arguments vector.
377 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000378 }
379
380 virtual
381 ~CommandObjectThreadStepWithTypeAndScope ()
382 {
383 }
384
385 virtual
386 Options *
387 GetOptions ()
388 {
389 return &m_options;
390 }
391
392 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000393 Execute
394 (
Greg Clayton63094e02010-06-23 01:19:29 +0000395 Args& command,
396 CommandReturnObject &result
397 )
Chris Lattner24943d22010-06-08 16:52:24 +0000398 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000399 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton238c0a12010-09-18 01:14:36 +0000400 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000401
402 if (process == NULL)
403 {
404 result.AppendError ("need a valid process to step");
405 result.SetStatus (eReturnStatusFailed);
406
407 }
408 else
409 {
410 const uint32_t num_threads = process->GetThreadList().GetSize();
411 Thread *thread = NULL;
412
413 if (command.GetArgumentCount() == 0)
414 {
Jim Inghamc8332952010-08-26 21:32:51 +0000415 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000416 if (thread == NULL)
417 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000418 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000419 result.SetStatus (eReturnStatusFailed);
420 return false;
421 }
422 }
423 else
424 {
425 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
426 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
427 if (step_thread_idx == LLDB_INVALID_INDEX32)
428 {
429 result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr);
430 result.SetStatus (eReturnStatusFailed);
431 return false;
432 }
433 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
434 if (thread == NULL)
435 {
436 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000437 step_thread_idx, num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000438 result.SetStatus (eReturnStatusFailed);
439 return false;
440 }
441 }
442
443 const bool abort_other_plans = false;
444 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
445
446 // This is a bit unfortunate, but not all the commands in this command object support
447 // only while stepping, so I use the bool for them.
448 bool bool_stop_other_threads;
449 if (m_options.m_run_mode == eAllThreads)
450 bool_stop_other_threads = false;
451 else
452 bool_stop_other_threads = true;
453
454 if (m_step_type == eStepTypeInto)
455 {
456 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
457 ThreadPlan *new_plan;
458
459 if (frame->HasDebugInformation ())
460 {
461 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
462 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
463 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000464 stop_other_threads,
465 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000466 if (new_plan && !m_options.m_avoid_regexp.empty())
467 {
468 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
469 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
470 }
Chris Lattner24943d22010-06-08 16:52:24 +0000471 }
472 else
473 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
474
Jim Inghamc8332952010-08-26 21:32:51 +0000475 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000476 process->Resume ();
477 }
478 else if (m_step_type == eStepTypeOver)
479 {
480 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
481 ThreadPlan *new_plan;
482
483 if (frame->HasDebugInformation())
484 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
485 m_step_type,
486 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
487 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000488 stop_other_threads,
489 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000490 else
491 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
492 abort_other_plans,
493 bool_stop_other_threads);
494
495 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
496 // Maybe there should be a parameter to control this.
497 new_plan->SetOkayToDiscard(false);
498
Jim Inghamc8332952010-08-26 21:32:51 +0000499 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000500 process->Resume ();
501 }
502 else if (m_step_type == eStepTypeTrace)
503 {
504 thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000505 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000506 process->Resume ();
507 }
508 else if (m_step_type == eStepTypeTraceOver)
509 {
510 thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000511 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000512 process->Resume ();
513 }
514 else if (m_step_type == eStepTypeOut)
515 {
516 ThreadPlan *new_plan;
517
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000518 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
519 NULL,
520 false,
521 bool_stop_other_threads,
522 eVoteYes,
523 eVoteNoOpinion,
524 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000525 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
526 // Maybe there should be a parameter to control this.
527 new_plan->SetOkayToDiscard(false);
528
Jim Inghamc8332952010-08-26 21:32:51 +0000529 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000530 process->Resume ();
531 }
532 else
533 {
534 result.AppendError ("step type is not supported");
535 result.SetStatus (eReturnStatusFailed);
536 }
537 if (synchronous_execution)
538 {
539 StateType state = process->WaitForProcessToStop (NULL);
540
541 //EventSP event_sp;
542 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
543 //while (! StateIsStoppedState (state))
544 // {
545 // state = process->WaitForStateChangedEvents (NULL, event_sp);
546 // }
Jim Inghamc8332952010-08-26 21:32:51 +0000547 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000548 result.SetDidChangeProcessState (true);
549 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
550 result.SetStatus (eReturnStatusSuccessFinishNoResult);
551 }
552 }
553 return result.Succeeded();
554 }
555
556protected:
557 StepType m_step_type;
558 StepScope m_step_scope;
559 CommandOptions m_options;
560};
561
Greg Claytonb3448432011-03-24 21:19:54 +0000562static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000563g_tri_running_mode[] =
564{
Greg Claytonfe424a92010-09-18 03:37:20 +0000565{ eOnlyThisThread, "this-thread", "Run only this thread"},
566{ eAllThreads, "all-threads", "Run all threads"},
567{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000568{ 0, NULL, NULL }
569};
570
Greg Claytonb3448432011-03-24 21:19:54 +0000571static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000572g_duo_running_mode[] =
573{
Greg Claytonfe424a92010-09-18 03:37:20 +0000574{ eOnlyThisThread, "this-thread", "Run only this thread"},
575{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000576{ 0, NULL, NULL }
577};
578
Greg Claytonb3448432011-03-24 21:19:54 +0000579OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000580CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
581{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000582{ 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."},
583{ 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."},
584{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
585{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000586};
587
588
589//-------------------------------------------------------------------------
590// CommandObjectThreadContinue
591//-------------------------------------------------------------------------
592
593class CommandObjectThreadContinue : public CommandObject
594{
595public:
596
Greg Clayton238c0a12010-09-18 01:14:36 +0000597 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
598 CommandObject (interpreter,
599 "thread continue",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000600 "Continue execution of one or more threads in an active process.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000601 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000602 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
603 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000604 CommandArgumentEntry arg;
605 CommandArgumentData thread_idx_arg;
606
607 // Define the first (and only) variant of this arg.
608 thread_idx_arg.arg_type = eArgTypeThreadIndex;
609 thread_idx_arg.arg_repetition = eArgRepeatPlus;
610
611 // There is only one variant this argument could be; put it into the argument entry.
612 arg.push_back (thread_idx_arg);
613
614 // Push the data for the first argument into the m_arguments vector.
615 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000616 }
617
618
619 virtual
620 ~CommandObjectThreadContinue ()
621 {
622 }
623
624 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000625 Execute
626 (
Greg Clayton63094e02010-06-23 01:19:29 +0000627 Args& command,
628 CommandReturnObject &result
629 )
Chris Lattner24943d22010-06-08 16:52:24 +0000630 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000631 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000632
Greg Clayton238c0a12010-09-18 01:14:36 +0000633 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000634 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000635 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000636 result.SetStatus (eReturnStatusFailed);
637 return false;
638 }
639
Greg Clayton567e7f32011-09-22 04:58:26 +0000640 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000641 if (process == NULL)
642 {
643 result.AppendError ("no process exists. Cannot continue");
644 result.SetStatus (eReturnStatusFailed);
645 return false;
646 }
647
648 StateType state = process->GetState();
649 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
650 {
651 const uint32_t num_threads = process->GetThreadList().GetSize();
652 uint32_t idx;
653 const size_t argc = command.GetArgumentCount();
654 if (argc > 0)
655 {
656 std::vector<uint32_t> resume_thread_indexes;
657 for (uint32_t i=0; i<argc; ++i)
658 {
659 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
660 if (idx < num_threads)
661 resume_thread_indexes.push_back(idx);
662 else
663 result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
664 }
665
666 if (resume_thread_indexes.empty())
667 {
668 result.AppendError ("no valid thread indexes were specified");
669 result.SetStatus (eReturnStatusFailed);
670 return false;
671 }
672 else
673 {
674 result.AppendMessage ("Resuming thread ");
675 for (idx=0; idx<num_threads; ++idx)
676 {
677 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
678 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
679 {
680 result.AppendMessageWithFormat ("%u ", idx);
681 thread->SetResumeState (eStateRunning);
682 }
683 else
684 {
685 thread->SetResumeState (eStateSuspended);
686 }
687 }
688 result.AppendMessageWithFormat ("in process %i\n", process->GetID());
689 }
690 }
691 else
692 {
Jim Inghamc8332952010-08-26 21:32:51 +0000693 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000694 if (current_thread == NULL)
695 {
696 result.AppendError ("the process doesn't have a current thread");
697 result.SetStatus (eReturnStatusFailed);
698 return false;
699 }
700 // Set the actions that the threads should each take when resuming
701 for (idx=0; idx<num_threads; ++idx)
702 {
703 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
704 if (thread == current_thread)
705 {
706 result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID());
707 thread->SetResumeState (eStateRunning);
708 }
709 else
710 {
711 thread->SetResumeState (eStateSuspended);
712 }
713 }
714 }
715
716 Error error (process->Resume());
717 if (error.Success())
718 {
Greg Claytonc1d37752010-10-18 01:45:30 +0000719 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000720 if (synchronous_execution)
721 {
Greg Claytonbef15832010-07-14 00:18:15 +0000722 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000723
724 result.SetDidChangeProcessState (true);
725 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
726 result.SetStatus (eReturnStatusSuccessFinishNoResult);
727 }
728 else
729 {
730 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
731 }
732 }
733 else
734 {
735 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
736 result.SetStatus (eReturnStatusFailed);
737 }
738 }
739 else
740 {
741 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
742 StateAsCString(state));
743 result.SetStatus (eReturnStatusFailed);
744 }
745
746 return result.Succeeded();
747 }
748
749};
750
751//-------------------------------------------------------------------------
752// CommandObjectThreadUntil
753//-------------------------------------------------------------------------
754
755class CommandObjectThreadUntil : public CommandObject
756{
757public:
758
759 class CommandOptions : public Options
760 {
761 public:
762 uint32_t m_thread_idx;
763 uint32_t m_frame_idx;
764
Greg Claytonf15996e2011-04-07 22:46:35 +0000765 CommandOptions (CommandInterpreter &interpreter) :
766 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000767 m_thread_idx(LLDB_INVALID_THREAD_ID),
768 m_frame_idx(LLDB_INVALID_FRAME_ID)
769 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000770 // Keep default values of all options in one place: OptionParsingStarting ()
771 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000772 }
773
774 virtual
775 ~CommandOptions ()
776 {
777 }
778
779 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000780 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000781 {
782 Error error;
783 char short_option = (char) m_getopt_table[option_idx].val;
784
785 switch (short_option)
786 {
787 case 't':
788 {
Greg Claytonbef15832010-07-14 00:18:15 +0000789 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000790 if (m_thread_idx == LLDB_INVALID_INDEX32)
791 {
792 error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg);
793 }
794 }
795 break;
796 case 'f':
797 {
798 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
799 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
800 {
801 error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg);
802 }
803 }
804 break;
805 case 'm':
806 {
Chris Lattner24943d22010-06-08 16:52:24 +0000807 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000808 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000809
Greg Clayton61aca5d2011-10-07 18:58:12 +0000810 if (error.Success())
811 {
812 if (run_mode == eAllThreads)
813 m_stop_others = false;
814 else
815 m_stop_others = true;
816 }
Chris Lattner24943d22010-06-08 16:52:24 +0000817 }
818 break;
819 default:
820 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
821 break;
822
823 }
824 return error;
825 }
826
827 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000828 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000829 {
Chris Lattner24943d22010-06-08 16:52:24 +0000830 m_thread_idx = LLDB_INVALID_THREAD_ID;
831 m_frame_idx = 0;
832 m_stop_others = false;
833 }
834
Greg Claytonb3448432011-03-24 21:19:54 +0000835 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000836 GetDefinitions ()
837 {
838 return g_option_table;
839 }
840
841 uint32_t m_step_thread_idx;
842 bool m_stop_others;
843
844 // Options table: Required for subclasses of Options.
845
Greg Claytonb3448432011-03-24 21:19:54 +0000846 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000847
848 // Instance variables to hold the values for command options.
849 };
850
Greg Clayton238c0a12010-09-18 01:14:36 +0000851 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
852 CommandObject (interpreter,
853 "thread until",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000854 "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 +0000855 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000856 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000857 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000858 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000859 CommandArgumentEntry arg;
860 CommandArgumentData line_num_arg;
861
862 // Define the first (and only) variant of this arg.
863 line_num_arg.arg_type = eArgTypeLineNum;
864 line_num_arg.arg_repetition = eArgRepeatPlain;
865
866 // There is only one variant this argument could be; put it into the argument entry.
867 arg.push_back (line_num_arg);
868
869 // Push the data for the first argument into the m_arguments vector.
870 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000871 }
872
873
874 virtual
875 ~CommandObjectThreadUntil ()
876 {
877 }
878
879 virtual
880 Options *
881 GetOptions ()
882 {
883 return &m_options;
884 }
885
886 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000887 Execute
888 (
Greg Clayton63094e02010-06-23 01:19:29 +0000889 Args& command,
890 CommandReturnObject &result
891 )
Chris Lattner24943d22010-06-08 16:52:24 +0000892 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000893 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000894
Greg Clayton238c0a12010-09-18 01:14:36 +0000895 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000896 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000897 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000898 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000899 result.SetStatus (eReturnStatusFailed);
900 return false;
901 }
902
Greg Clayton567e7f32011-09-22 04:58:26 +0000903 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000904 if (process == NULL)
905 {
906 result.AppendError ("need a valid process to step");
907 result.SetStatus (eReturnStatusFailed);
908
909 }
910 else
911 {
912 Thread *thread = NULL;
913 uint32_t line_number;
914
915 if (command.GetArgumentCount() != 1)
916 {
917 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
918 result.SetStatus (eReturnStatusFailed);
919 return false;
920 }
921
922 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
923 if (line_number == UINT32_MAX)
924 {
925 result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
926 result.SetStatus (eReturnStatusFailed);
927 return false;
928 }
929
930 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
931 {
Jim Inghamc8332952010-08-26 21:32:51 +0000932 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000933 }
934 else
935 {
936 thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
937 }
938
939 if (thread == NULL)
940 {
941 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000942 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
943 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000944 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000945 result.SetStatus (eReturnStatusFailed);
946 return false;
947 }
948
949 const bool abort_other_plans = true;
950
951 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
952 if (frame == NULL)
953 {
954
Jim Inghamb07c62a2011-05-08 00:56:32 +0000955 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
956 m_options.m_frame_idx,
957 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000958 result.SetStatus (eReturnStatusFailed);
959 return false;
960 }
961
962 ThreadPlan *new_plan;
963
964 if (frame->HasDebugInformation ())
965 {
966 // Finally we got here... Translate the given line number to a bunch of addresses:
967 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
968 LineTable *line_table = NULL;
969 if (sc.comp_unit)
970 line_table = sc.comp_unit->GetLineTable();
971
972 if (line_table == NULL)
973 {
974 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
975 m_options.m_frame_idx, m_options.m_thread_idx);
976 result.SetStatus (eReturnStatusFailed);
977 return false;
978 }
979
980 LineEntry function_start;
981 uint32_t index_ptr = 0, end_ptr;
982 std::vector<addr_t> address_list;
983
984 // Find the beginning & end index of the
985 AddressRange fun_addr_range = sc.function->GetAddressRange();
986 Address fun_start_addr = fun_addr_range.GetBaseAddress();
987 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
988
Jim Inghamb07c62a2011-05-08 00:56:32 +0000989 Address fun_end_addr(fun_start_addr.GetSection(),
990 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000991 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
992
Jim Inghamb07c62a2011-05-08 00:56:32 +0000993 bool all_in_function = true;
994
Chris Lattner24943d22010-06-08 16:52:24 +0000995 while (index_ptr <= end_ptr)
996 {
997 LineEntry line_entry;
Jim Inghamd6d47972011-09-23 00:54:11 +0000998 const bool exact = false;
999 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +00001000 if (index_ptr == UINT32_MAX)
1001 break;
1002
Greg Claytoneea26402010-09-14 23:36:40 +00001003 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001004 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001005 {
1006 if (fun_addr_range.ContainsLoadAddress (address, target))
1007 address_list.push_back (address);
1008 else
1009 all_in_function = false;
1010 }
Chris Lattner24943d22010-06-08 16:52:24 +00001011 index_ptr++;
1012 }
1013
Jim Inghamb07c62a2011-05-08 00:56:32 +00001014 if (address_list.size() == 0)
1015 {
1016 if (all_in_function)
1017 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1018 else
1019 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1020
1021 result.SetStatus (eReturnStatusFailed);
1022 return false;
1023 }
1024
1025 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1026 &address_list.front(),
1027 address_list.size(),
1028 m_options.m_stop_others,
1029 thread->GetSelectedFrameIndex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001030 new_plan->SetOkayToDiscard(false);
1031 }
1032 else
1033 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001034 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1035 m_options.m_frame_idx,
1036 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001037 result.SetStatus (eReturnStatusFailed);
1038 return false;
1039
1040 }
1041
Jim Inghamc8332952010-08-26 21:32:51 +00001042 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001043 Error error (process->Resume ());
1044 if (error.Success())
1045 {
Greg Claytonc1d37752010-10-18 01:45:30 +00001046 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001047 if (synchronous_execution)
1048 {
1049 StateType state = process->WaitForProcessToStop (NULL);
1050
1051 result.SetDidChangeProcessState (true);
1052 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
1053 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1054 }
1055 else
1056 {
1057 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1058 }
1059 }
1060 else
1061 {
1062 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1063 result.SetStatus (eReturnStatusFailed);
1064 }
1065
1066 }
1067 return result.Succeeded();
1068 }
1069protected:
1070 CommandOptions m_options;
1071
1072};
1073
Greg Claytonb3448432011-03-24 21:19:54 +00001074OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001075CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1076{
Caroline Tice43b014a2010-10-04 22:28:36 +00001077{ 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 +00001078{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1079{ 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"},
1080{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001081};
1082
1083
1084//-------------------------------------------------------------------------
1085// CommandObjectThreadSelect
1086//-------------------------------------------------------------------------
1087
1088class CommandObjectThreadSelect : public CommandObject
1089{
1090public:
1091
Greg Clayton238c0a12010-09-18 01:14:36 +00001092 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1093 CommandObject (interpreter,
1094 "thread select",
1095 "Select a thread as the currently active thread.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001096 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001097 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001098 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001099 CommandArgumentEntry arg;
1100 CommandArgumentData thread_idx_arg;
1101
1102 // Define the first (and only) variant of this arg.
1103 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1104 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1105
1106 // There is only one variant this argument could be; put it into the argument entry.
1107 arg.push_back (thread_idx_arg);
1108
1109 // Push the data for the first argument into the m_arguments vector.
1110 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001111 }
1112
1113
1114 virtual
1115 ~CommandObjectThreadSelect ()
1116 {
1117 }
1118
1119 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001120 Execute
1121 (
Greg Clayton63094e02010-06-23 01:19:29 +00001122 Args& command,
1123 CommandReturnObject &result
1124 )
Chris Lattner24943d22010-06-08 16:52:24 +00001125 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001126 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001127 if (process == NULL)
1128 {
1129 result.AppendError ("no process");
1130 result.SetStatus (eReturnStatusFailed);
1131 return false;
1132 }
1133 else if (command.GetArgumentCount() != 1)
1134 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001135 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 +00001136 result.SetStatus (eReturnStatusFailed);
1137 return false;
1138 }
1139
1140 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1141
1142 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1143 if (new_thread == NULL)
1144 {
1145 result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1146 result.SetStatus (eReturnStatusFailed);
1147 return false;
1148 }
1149
Jim Inghamc8332952010-08-26 21:32:51 +00001150 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001151 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001152
Greg Claytonabe0fed2011-04-18 08:33:37 +00001153 const uint32_t start_frame = 0;
1154 const uint32_t num_frames = 1;
1155 const uint32_t num_frames_with_source = 1;
1156 new_thread->GetStatus (result.GetOutputStream(),
1157 start_frame,
1158 num_frames,
1159 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001160
1161 return result.Succeeded();
1162 }
1163
1164};
1165
1166
1167//-------------------------------------------------------------------------
1168// CommandObjectThreadList
1169//-------------------------------------------------------------------------
1170
Greg Clayton63094e02010-06-23 01:19:29 +00001171class CommandObjectThreadList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001172{
Greg Clayton63094e02010-06-23 01:19:29 +00001173public:
Chris Lattner24943d22010-06-08 16:52:24 +00001174
Chris Lattner24943d22010-06-08 16:52:24 +00001175
Greg Clayton238c0a12010-09-18 01:14:36 +00001176 CommandObjectThreadList (CommandInterpreter &interpreter):
1177 CommandObject (interpreter,
1178 "thread list",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001179 "Show a summary of all current threads in a process.",
Greg Clayton63094e02010-06-23 01:19:29 +00001180 "thread list",
1181 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001182 {
Greg Clayton63094e02010-06-23 01:19:29 +00001183 }
Chris Lattner24943d22010-06-08 16:52:24 +00001184
Greg Clayton63094e02010-06-23 01:19:29 +00001185 ~CommandObjectThreadList()
1186 {
1187 }
1188
1189 bool
1190 Execute
1191 (
Greg Clayton63094e02010-06-23 01:19:29 +00001192 Args& command,
1193 CommandReturnObject &result
1194 )
1195 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001196 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001197 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001198 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001199 Process *process = exe_ctx.GetProcessPtr();
1200 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00001201 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001202 const bool only_threads_with_stop_reason = false;
1203 const uint32_t start_frame = 0;
1204 const uint32_t num_frames = 0;
1205 const uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +00001206 process->GetStatus(strm);
1207 process->GetThreadStatus (strm,
1208 only_threads_with_stop_reason,
1209 start_frame,
1210 num_frames,
1211 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001212 }
1213 else
1214 {
Greg Clayton63094e02010-06-23 01:19:29 +00001215 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001216 result.SetStatus (eReturnStatusFailed);
1217 }
Greg Clayton63094e02010-06-23 01:19:29 +00001218 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001219 }
Greg Clayton63094e02010-06-23 01:19:29 +00001220};
Chris Lattner24943d22010-06-08 16:52:24 +00001221
1222//-------------------------------------------------------------------------
1223// CommandObjectMultiwordThread
1224//-------------------------------------------------------------------------
1225
Greg Clayton63094e02010-06-23 01:19:29 +00001226CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001227 CommandObjectMultiword (interpreter,
1228 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001229 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001230 "thread <subcommand> [<subcommand-options>]")
1231{
Greg Clayton238c0a12010-09-18 01:14:36 +00001232 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1233 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1234 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1235 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1236 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1237 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1238 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001239 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001240 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001241 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001242 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1243 eStepTypeInto,
1244 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001245
Greg Clayton238c0a12010-09-18 01:14:36 +00001246 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1247 interpreter,
1248 "thread step-out",
Peter Collingbourne82ce5402011-06-14 03:55:29 +00001249 "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 +00001250 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001251 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1252 eStepTypeOut,
1253 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001254
Greg Clayton238c0a12010-09-18 01:14:36 +00001255 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1256 interpreter,
1257 "thread step-over",
1258 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001259 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001260 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1261 eStepTypeOver,
1262 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001263
Greg Clayton238c0a12010-09-18 01:14:36 +00001264 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1265 interpreter,
1266 "thread step-inst",
1267 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001268 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001269 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1270 eStepTypeTrace,
1271 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001272
Greg Clayton238c0a12010-09-18 01:14:36 +00001273 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1274 interpreter,
1275 "thread step-inst-over",
1276 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001277 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001278 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1279 eStepTypeTraceOver,
1280 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001281}
1282
1283CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1284{
1285}
1286
1287