blob: 8e4ae8d469ec6e21706d822377ed191352d806f7 [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 {
310 bool found_one = false;
311 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
312 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
313 if (!found_one)
314 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
315 }
316 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000317
318 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000319 {
320 m_avoid_regexp.clear();
321 m_avoid_regexp.assign(option_arg);
322 }
323 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000324
325 default:
326 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
327 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000328
329 }
330 return error;
331 }
332
333 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000334 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000335 {
Chris Lattner24943d22010-06-08 16:52:24 +0000336 m_avoid_no_debug = true;
337 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000338 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000339 }
340
Greg Claytonb3448432011-03-24 21:19:54 +0000341 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000342 GetDefinitions ()
343 {
344 return g_option_table;
345 }
346
347 // Options table: Required for subclasses of Options.
348
Greg Claytonb3448432011-03-24 21:19:54 +0000349 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000350
351 // Instance variables to hold the values for command options.
352 bool m_avoid_no_debug;
353 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000354 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000355 };
356
Greg Clayton238c0a12010-09-18 01:14:36 +0000357 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
358 const char *name,
359 const char *help,
360 const char *syntax,
361 uint32_t flags,
362 StepType step_type,
363 StepScope step_scope) :
364 CommandObject (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000365 m_step_type (step_type),
366 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000367 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000368 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000369 CommandArgumentEntry arg;
370 CommandArgumentData thread_id_arg;
371
372 // Define the first (and only) variant of this arg.
373 thread_id_arg.arg_type = eArgTypeThreadID;
374 thread_id_arg.arg_repetition = eArgRepeatOptional;
375
376 // There is only one variant this argument could be; put it into the argument entry.
377 arg.push_back (thread_id_arg);
378
379 // Push the data for the first argument into the m_arguments vector.
380 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000381 }
382
383 virtual
384 ~CommandObjectThreadStepWithTypeAndScope ()
385 {
386 }
387
388 virtual
389 Options *
390 GetOptions ()
391 {
392 return &m_options;
393 }
394
395 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000396 Execute
397 (
Greg Clayton63094e02010-06-23 01:19:29 +0000398 Args& command,
399 CommandReturnObject &result
400 )
Chris Lattner24943d22010-06-08 16:52:24 +0000401 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000402 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton238c0a12010-09-18 01:14:36 +0000403 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000404
405 if (process == NULL)
406 {
407 result.AppendError ("need a valid process to step");
408 result.SetStatus (eReturnStatusFailed);
409
410 }
411 else
412 {
413 const uint32_t num_threads = process->GetThreadList().GetSize();
414 Thread *thread = NULL;
415
416 if (command.GetArgumentCount() == 0)
417 {
Jim Inghamc8332952010-08-26 21:32:51 +0000418 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000419 if (thread == NULL)
420 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000421 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000422 result.SetStatus (eReturnStatusFailed);
423 return false;
424 }
425 }
426 else
427 {
428 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
429 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
430 if (step_thread_idx == LLDB_INVALID_INDEX32)
431 {
432 result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr);
433 result.SetStatus (eReturnStatusFailed);
434 return false;
435 }
436 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
437 if (thread == NULL)
438 {
439 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000440 step_thread_idx, num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000441 result.SetStatus (eReturnStatusFailed);
442 return false;
443 }
444 }
445
446 const bool abort_other_plans = false;
447 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
448
449 // This is a bit unfortunate, but not all the commands in this command object support
450 // only while stepping, so I use the bool for them.
451 bool bool_stop_other_threads;
452 if (m_options.m_run_mode == eAllThreads)
453 bool_stop_other_threads = false;
454 else
455 bool_stop_other_threads = true;
456
457 if (m_step_type == eStepTypeInto)
458 {
459 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
460 ThreadPlan *new_plan;
461
462 if (frame->HasDebugInformation ())
463 {
464 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
465 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
466 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000467 stop_other_threads,
468 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000469 if (new_plan && !m_options.m_avoid_regexp.empty())
470 {
471 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
472 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
473 }
Chris Lattner24943d22010-06-08 16:52:24 +0000474 }
475 else
476 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
477
Jim Inghamc8332952010-08-26 21:32:51 +0000478 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000479 process->Resume ();
480 }
481 else if (m_step_type == eStepTypeOver)
482 {
483 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
484 ThreadPlan *new_plan;
485
486 if (frame->HasDebugInformation())
487 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
488 m_step_type,
489 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
490 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000491 stop_other_threads,
492 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000493 else
494 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
495 abort_other_plans,
496 bool_stop_other_threads);
497
498 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
499 // Maybe there should be a parameter to control this.
500 new_plan->SetOkayToDiscard(false);
501
Jim Inghamc8332952010-08-26 21:32:51 +0000502 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000503 process->Resume ();
504 }
505 else if (m_step_type == eStepTypeTrace)
506 {
507 thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000508 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000509 process->Resume ();
510 }
511 else if (m_step_type == eStepTypeTraceOver)
512 {
513 thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Jim Inghamc8332952010-08-26 21:32:51 +0000514 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000515 process->Resume ();
516 }
517 else if (m_step_type == eStepTypeOut)
518 {
519 ThreadPlan *new_plan;
520
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000521 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
522 NULL,
523 false,
524 bool_stop_other_threads,
525 eVoteYes,
526 eVoteNoOpinion,
527 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000528 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
529 // Maybe there should be a parameter to control this.
530 new_plan->SetOkayToDiscard(false);
531
Jim Inghamc8332952010-08-26 21:32:51 +0000532 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000533 process->Resume ();
534 }
535 else
536 {
537 result.AppendError ("step type is not supported");
538 result.SetStatus (eReturnStatusFailed);
539 }
540 if (synchronous_execution)
541 {
542 StateType state = process->WaitForProcessToStop (NULL);
543
544 //EventSP event_sp;
545 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
546 //while (! StateIsStoppedState (state))
547 // {
548 // state = process->WaitForStateChangedEvents (NULL, event_sp);
549 // }
Jim Inghamc8332952010-08-26 21:32:51 +0000550 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000551 result.SetDidChangeProcessState (true);
552 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
553 result.SetStatus (eReturnStatusSuccessFinishNoResult);
554 }
555 }
556 return result.Succeeded();
557 }
558
559protected:
560 StepType m_step_type;
561 StepScope m_step_scope;
562 CommandOptions m_options;
563};
564
Greg Claytonb3448432011-03-24 21:19:54 +0000565static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000566g_tri_running_mode[] =
567{
Greg Claytonfe424a92010-09-18 03:37:20 +0000568{ eOnlyThisThread, "this-thread", "Run only this thread"},
569{ eAllThreads, "all-threads", "Run all threads"},
570{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000571{ 0, NULL, NULL }
572};
573
Greg Claytonb3448432011-03-24 21:19:54 +0000574static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000575g_duo_running_mode[] =
576{
Greg Claytonfe424a92010-09-18 03:37:20 +0000577{ eOnlyThisThread, "this-thread", "Run only this thread"},
578{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000579{ 0, NULL, NULL }
580};
581
Greg Claytonb3448432011-03-24 21:19:54 +0000582OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000583CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
584{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000585{ 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."},
586{ 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."},
587{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
588{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000589};
590
591
592//-------------------------------------------------------------------------
593// CommandObjectThreadContinue
594//-------------------------------------------------------------------------
595
596class CommandObjectThreadContinue : public CommandObject
597{
598public:
599
Greg Clayton238c0a12010-09-18 01:14:36 +0000600 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
601 CommandObject (interpreter,
602 "thread continue",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000603 "Continue execution of one or more threads in an active process.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000604 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000605 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
606 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000607 CommandArgumentEntry arg;
608 CommandArgumentData thread_idx_arg;
609
610 // Define the first (and only) variant of this arg.
611 thread_idx_arg.arg_type = eArgTypeThreadIndex;
612 thread_idx_arg.arg_repetition = eArgRepeatPlus;
613
614 // There is only one variant this argument could be; put it into the argument entry.
615 arg.push_back (thread_idx_arg);
616
617 // Push the data for the first argument into the m_arguments vector.
618 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000619 }
620
621
622 virtual
623 ~CommandObjectThreadContinue ()
624 {
625 }
626
627 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000628 Execute
629 (
Greg Clayton63094e02010-06-23 01:19:29 +0000630 Args& command,
631 CommandReturnObject &result
632 )
Chris Lattner24943d22010-06-08 16:52:24 +0000633 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000634 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000635
Greg Clayton238c0a12010-09-18 01:14:36 +0000636 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000637 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000638 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000639 result.SetStatus (eReturnStatusFailed);
640 return false;
641 }
642
Greg Clayton567e7f32011-09-22 04:58:26 +0000643 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000644 if (process == NULL)
645 {
646 result.AppendError ("no process exists. Cannot continue");
647 result.SetStatus (eReturnStatusFailed);
648 return false;
649 }
650
651 StateType state = process->GetState();
652 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
653 {
654 const uint32_t num_threads = process->GetThreadList().GetSize();
655 uint32_t idx;
656 const size_t argc = command.GetArgumentCount();
657 if (argc > 0)
658 {
659 std::vector<uint32_t> resume_thread_indexes;
660 for (uint32_t i=0; i<argc; ++i)
661 {
662 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
663 if (idx < num_threads)
664 resume_thread_indexes.push_back(idx);
665 else
666 result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
667 }
668
669 if (resume_thread_indexes.empty())
670 {
671 result.AppendError ("no valid thread indexes were specified");
672 result.SetStatus (eReturnStatusFailed);
673 return false;
674 }
675 else
676 {
677 result.AppendMessage ("Resuming thread ");
678 for (idx=0; idx<num_threads; ++idx)
679 {
680 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
681 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
682 {
683 result.AppendMessageWithFormat ("%u ", idx);
684 thread->SetResumeState (eStateRunning);
685 }
686 else
687 {
688 thread->SetResumeState (eStateSuspended);
689 }
690 }
691 result.AppendMessageWithFormat ("in process %i\n", process->GetID());
692 }
693 }
694 else
695 {
Jim Inghamc8332952010-08-26 21:32:51 +0000696 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000697 if (current_thread == NULL)
698 {
699 result.AppendError ("the process doesn't have a current thread");
700 result.SetStatus (eReturnStatusFailed);
701 return false;
702 }
703 // Set the actions that the threads should each take when resuming
704 for (idx=0; idx<num_threads; ++idx)
705 {
706 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
707 if (thread == current_thread)
708 {
709 result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID());
710 thread->SetResumeState (eStateRunning);
711 }
712 else
713 {
714 thread->SetResumeState (eStateSuspended);
715 }
716 }
717 }
718
719 Error error (process->Resume());
720 if (error.Success())
721 {
Greg Claytonc1d37752010-10-18 01:45:30 +0000722 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000723 if (synchronous_execution)
724 {
Greg Claytonbef15832010-07-14 00:18:15 +0000725 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000726
727 result.SetDidChangeProcessState (true);
728 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
729 result.SetStatus (eReturnStatusSuccessFinishNoResult);
730 }
731 else
732 {
733 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
734 }
735 }
736 else
737 {
738 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
739 result.SetStatus (eReturnStatusFailed);
740 }
741 }
742 else
743 {
744 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
745 StateAsCString(state));
746 result.SetStatus (eReturnStatusFailed);
747 }
748
749 return result.Succeeded();
750 }
751
752};
753
754//-------------------------------------------------------------------------
755// CommandObjectThreadUntil
756//-------------------------------------------------------------------------
757
758class CommandObjectThreadUntil : public CommandObject
759{
760public:
761
762 class CommandOptions : public Options
763 {
764 public:
765 uint32_t m_thread_idx;
766 uint32_t m_frame_idx;
767
Greg Claytonf15996e2011-04-07 22:46:35 +0000768 CommandOptions (CommandInterpreter &interpreter) :
769 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000770 m_thread_idx(LLDB_INVALID_THREAD_ID),
771 m_frame_idx(LLDB_INVALID_FRAME_ID)
772 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000773 // Keep default values of all options in one place: OptionParsingStarting ()
774 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000775 }
776
777 virtual
778 ~CommandOptions ()
779 {
780 }
781
782 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000783 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000784 {
785 Error error;
786 char short_option = (char) m_getopt_table[option_idx].val;
787
788 switch (short_option)
789 {
790 case 't':
791 {
Greg Claytonbef15832010-07-14 00:18:15 +0000792 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000793 if (m_thread_idx == LLDB_INVALID_INDEX32)
794 {
795 error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg);
796 }
797 }
798 break;
799 case 'f':
800 {
801 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
802 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
803 {
804 error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg);
805 }
806 }
807 break;
808 case 'm':
809 {
810 bool found_one = false;
811 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
812 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
813
814 if (!found_one)
815 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
816 else if (run_mode == eAllThreads)
817 m_stop_others = false;
818 else
819 m_stop_others = true;
820
821 }
822 break;
823 default:
824 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
825 break;
826
827 }
828 return error;
829 }
830
831 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000832 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000833 {
Chris Lattner24943d22010-06-08 16:52:24 +0000834 m_thread_idx = LLDB_INVALID_THREAD_ID;
835 m_frame_idx = 0;
836 m_stop_others = false;
837 }
838
Greg Claytonb3448432011-03-24 21:19:54 +0000839 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000840 GetDefinitions ()
841 {
842 return g_option_table;
843 }
844
845 uint32_t m_step_thread_idx;
846 bool m_stop_others;
847
848 // Options table: Required for subclasses of Options.
849
Greg Claytonb3448432011-03-24 21:19:54 +0000850 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000851
852 // Instance variables to hold the values for command options.
853 };
854
Greg Clayton238c0a12010-09-18 01:14:36 +0000855 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
856 CommandObject (interpreter,
857 "thread until",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000858 "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 +0000859 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000860 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000861 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000862 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000863 CommandArgumentEntry arg;
864 CommandArgumentData line_num_arg;
865
866 // Define the first (and only) variant of this arg.
867 line_num_arg.arg_type = eArgTypeLineNum;
868 line_num_arg.arg_repetition = eArgRepeatPlain;
869
870 // There is only one variant this argument could be; put it into the argument entry.
871 arg.push_back (line_num_arg);
872
873 // Push the data for the first argument into the m_arguments vector.
874 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000875 }
876
877
878 virtual
879 ~CommandObjectThreadUntil ()
880 {
881 }
882
883 virtual
884 Options *
885 GetOptions ()
886 {
887 return &m_options;
888 }
889
890 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000891 Execute
892 (
Greg Clayton63094e02010-06-23 01:19:29 +0000893 Args& command,
894 CommandReturnObject &result
895 )
Chris Lattner24943d22010-06-08 16:52:24 +0000896 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000897 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000898
Greg Clayton238c0a12010-09-18 01:14:36 +0000899 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000900 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000901 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000902 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000903 result.SetStatus (eReturnStatusFailed);
904 return false;
905 }
906
Greg Clayton567e7f32011-09-22 04:58:26 +0000907 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000908 if (process == NULL)
909 {
910 result.AppendError ("need a valid process to step");
911 result.SetStatus (eReturnStatusFailed);
912
913 }
914 else
915 {
916 Thread *thread = NULL;
917 uint32_t line_number;
918
919 if (command.GetArgumentCount() != 1)
920 {
921 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
922 result.SetStatus (eReturnStatusFailed);
923 return false;
924 }
925
926 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
927 if (line_number == UINT32_MAX)
928 {
929 result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
930 result.SetStatus (eReturnStatusFailed);
931 return false;
932 }
933
934 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
935 {
Jim Inghamc8332952010-08-26 21:32:51 +0000936 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000937 }
938 else
939 {
940 thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
941 }
942
943 if (thread == NULL)
944 {
945 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000946 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
947 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000948 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000949 result.SetStatus (eReturnStatusFailed);
950 return false;
951 }
952
953 const bool abort_other_plans = true;
954
955 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
956 if (frame == NULL)
957 {
958
Jim Inghamb07c62a2011-05-08 00:56:32 +0000959 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
960 m_options.m_frame_idx,
961 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000962 result.SetStatus (eReturnStatusFailed);
963 return false;
964 }
965
966 ThreadPlan *new_plan;
967
968 if (frame->HasDebugInformation ())
969 {
970 // Finally we got here... Translate the given line number to a bunch of addresses:
971 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
972 LineTable *line_table = NULL;
973 if (sc.comp_unit)
974 line_table = sc.comp_unit->GetLineTable();
975
976 if (line_table == NULL)
977 {
978 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
979 m_options.m_frame_idx, m_options.m_thread_idx);
980 result.SetStatus (eReturnStatusFailed);
981 return false;
982 }
983
984 LineEntry function_start;
985 uint32_t index_ptr = 0, end_ptr;
986 std::vector<addr_t> address_list;
987
988 // Find the beginning & end index of the
989 AddressRange fun_addr_range = sc.function->GetAddressRange();
990 Address fun_start_addr = fun_addr_range.GetBaseAddress();
991 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
992
Jim Inghamb07c62a2011-05-08 00:56:32 +0000993 Address fun_end_addr(fun_start_addr.GetSection(),
994 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000995 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
996
Jim Inghamb07c62a2011-05-08 00:56:32 +0000997 bool all_in_function = true;
998
Chris Lattner24943d22010-06-08 16:52:24 +0000999 while (index_ptr <= end_ptr)
1000 {
1001 LineEntry line_entry;
Jim Inghamd6d47972011-09-23 00:54:11 +00001002 const bool exact = false;
1003 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +00001004 if (index_ptr == UINT32_MAX)
1005 break;
1006
Greg Claytoneea26402010-09-14 23:36:40 +00001007 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001008 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001009 {
1010 if (fun_addr_range.ContainsLoadAddress (address, target))
1011 address_list.push_back (address);
1012 else
1013 all_in_function = false;
1014 }
Chris Lattner24943d22010-06-08 16:52:24 +00001015 index_ptr++;
1016 }
1017
Jim Inghamb07c62a2011-05-08 00:56:32 +00001018 if (address_list.size() == 0)
1019 {
1020 if (all_in_function)
1021 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1022 else
1023 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1024
1025 result.SetStatus (eReturnStatusFailed);
1026 return false;
1027 }
1028
1029 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1030 &address_list.front(),
1031 address_list.size(),
1032 m_options.m_stop_others,
1033 thread->GetSelectedFrameIndex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001034 new_plan->SetOkayToDiscard(false);
1035 }
1036 else
1037 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001038 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1039 m_options.m_frame_idx,
1040 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001041 result.SetStatus (eReturnStatusFailed);
1042 return false;
1043
1044 }
1045
Jim Inghamc8332952010-08-26 21:32:51 +00001046 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001047 Error error (process->Resume ());
1048 if (error.Success())
1049 {
Greg Claytonc1d37752010-10-18 01:45:30 +00001050 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001051 if (synchronous_execution)
1052 {
1053 StateType state = process->WaitForProcessToStop (NULL);
1054
1055 result.SetDidChangeProcessState (true);
1056 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
1057 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1058 }
1059 else
1060 {
1061 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1062 }
1063 }
1064 else
1065 {
1066 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1067 result.SetStatus (eReturnStatusFailed);
1068 }
1069
1070 }
1071 return result.Succeeded();
1072 }
1073protected:
1074 CommandOptions m_options;
1075
1076};
1077
Greg Claytonb3448432011-03-24 21:19:54 +00001078OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001079CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1080{
Caroline Tice43b014a2010-10-04 22:28:36 +00001081{ 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 +00001082{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1083{ 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"},
1084{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001085};
1086
1087
1088//-------------------------------------------------------------------------
1089// CommandObjectThreadSelect
1090//-------------------------------------------------------------------------
1091
1092class CommandObjectThreadSelect : public CommandObject
1093{
1094public:
1095
Greg Clayton238c0a12010-09-18 01:14:36 +00001096 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1097 CommandObject (interpreter,
1098 "thread select",
1099 "Select a thread as the currently active thread.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001100 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001101 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001102 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001103 CommandArgumentEntry arg;
1104 CommandArgumentData thread_idx_arg;
1105
1106 // Define the first (and only) variant of this arg.
1107 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1108 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1109
1110 // There is only one variant this argument could be; put it into the argument entry.
1111 arg.push_back (thread_idx_arg);
1112
1113 // Push the data for the first argument into the m_arguments vector.
1114 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001115 }
1116
1117
1118 virtual
1119 ~CommandObjectThreadSelect ()
1120 {
1121 }
1122
1123 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001124 Execute
1125 (
Greg Clayton63094e02010-06-23 01:19:29 +00001126 Args& command,
1127 CommandReturnObject &result
1128 )
Chris Lattner24943d22010-06-08 16:52:24 +00001129 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001130 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001131 if (process == NULL)
1132 {
1133 result.AppendError ("no process");
1134 result.SetStatus (eReturnStatusFailed);
1135 return false;
1136 }
1137 else if (command.GetArgumentCount() != 1)
1138 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001139 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 +00001140 result.SetStatus (eReturnStatusFailed);
1141 return false;
1142 }
1143
1144 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1145
1146 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1147 if (new_thread == NULL)
1148 {
1149 result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1150 result.SetStatus (eReturnStatusFailed);
1151 return false;
1152 }
1153
Jim Inghamc8332952010-08-26 21:32:51 +00001154 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001155 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001156
Greg Claytonabe0fed2011-04-18 08:33:37 +00001157 const uint32_t start_frame = 0;
1158 const uint32_t num_frames = 1;
1159 const uint32_t num_frames_with_source = 1;
1160 new_thread->GetStatus (result.GetOutputStream(),
1161 start_frame,
1162 num_frames,
1163 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001164
1165 return result.Succeeded();
1166 }
1167
1168};
1169
1170
1171//-------------------------------------------------------------------------
1172// CommandObjectThreadList
1173//-------------------------------------------------------------------------
1174
Greg Clayton63094e02010-06-23 01:19:29 +00001175class CommandObjectThreadList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001176{
Greg Clayton63094e02010-06-23 01:19:29 +00001177public:
Chris Lattner24943d22010-06-08 16:52:24 +00001178
Chris Lattner24943d22010-06-08 16:52:24 +00001179
Greg Clayton238c0a12010-09-18 01:14:36 +00001180 CommandObjectThreadList (CommandInterpreter &interpreter):
1181 CommandObject (interpreter,
1182 "thread list",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001183 "Show a summary of all current threads in a process.",
Greg Clayton63094e02010-06-23 01:19:29 +00001184 "thread list",
1185 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001186 {
Greg Clayton63094e02010-06-23 01:19:29 +00001187 }
Chris Lattner24943d22010-06-08 16:52:24 +00001188
Greg Clayton63094e02010-06-23 01:19:29 +00001189 ~CommandObjectThreadList()
1190 {
1191 }
1192
1193 bool
1194 Execute
1195 (
Greg Clayton63094e02010-06-23 01:19:29 +00001196 Args& command,
1197 CommandReturnObject &result
1198 )
1199 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001200 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001201 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001202 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001203 Process *process = exe_ctx.GetProcessPtr();
1204 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00001205 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001206 const bool only_threads_with_stop_reason = false;
1207 const uint32_t start_frame = 0;
1208 const uint32_t num_frames = 0;
1209 const uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +00001210 process->GetStatus(strm);
1211 process->GetThreadStatus (strm,
1212 only_threads_with_stop_reason,
1213 start_frame,
1214 num_frames,
1215 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001216 }
1217 else
1218 {
Greg Clayton63094e02010-06-23 01:19:29 +00001219 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001220 result.SetStatus (eReturnStatusFailed);
1221 }
Greg Clayton63094e02010-06-23 01:19:29 +00001222 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001223 }
Greg Clayton63094e02010-06-23 01:19:29 +00001224};
Chris Lattner24943d22010-06-08 16:52:24 +00001225
1226//-------------------------------------------------------------------------
1227// CommandObjectMultiwordThread
1228//-------------------------------------------------------------------------
1229
Greg Clayton63094e02010-06-23 01:19:29 +00001230CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001231 CommandObjectMultiword (interpreter,
1232 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001233 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001234 "thread <subcommand> [<subcommand-options>]")
1235{
Greg Clayton238c0a12010-09-18 01:14:36 +00001236 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1237 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1238 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1239 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1240 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1241 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1242 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001243 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001244 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001245 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001246 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1247 eStepTypeInto,
1248 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001249
Greg Clayton238c0a12010-09-18 01:14:36 +00001250 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1251 interpreter,
1252 "thread step-out",
Peter Collingbourne82ce5402011-06-14 03:55:29 +00001253 "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 +00001254 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001255 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1256 eStepTypeOut,
1257 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001258
Greg Clayton238c0a12010-09-18 01:14:36 +00001259 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1260 interpreter,
1261 "thread step-over",
1262 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001263 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001264 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1265 eStepTypeOver,
1266 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001267
Greg Clayton238c0a12010-09-18 01:14:36 +00001268 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1269 interpreter,
1270 "thread step-inst",
1271 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001272 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001273 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1274 eStepTypeTrace,
1275 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001276
Greg Clayton238c0a12010-09-18 01:14:36 +00001277 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1278 interpreter,
1279 "thread step-inst-over",
1280 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001281 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001282 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1283 eStepTypeTraceOver,
1284 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001285}
1286
1287CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1288{
1289}
1290
1291