blob: f8deebc9ee1cd1b1c8eca7e5923f374923bd7a84 [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
Jim Inghamda26bd22012-06-08 21:56:10 +000045class CommandObjectThreadBacktrace : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +000046{
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)
Greg Clayton9c236732011-10-26 00:56:27 +000078 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000079 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)
Greg Clayton9c236732011-10-26 00:56:27 +000090 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000091 }
92 break;
93 default:
Greg Clayton9c236732011-10-26 00:56:27 +000094 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Ingham8ab1a802010-08-26 23:36:03 +000095 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) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000124 CommandObjectParsed (interpreter,
125 "thread backtrace",
126 "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.",
127 NULL,
128 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
Jim Inghamda26bd22012-06-08 21:56:10 +0000155protected:
Greg Clayton63094e02010-06-23 01:19:29 +0000156 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000157 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000158 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000159 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000160 Stream &strm = result.GetOutputStream();
161
162 // Don't show source context when doing backtraces.
163 const uint32_t num_frames_with_source = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000164 if (command.GetArgumentCount() == 0)
165 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000166 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000167 Thread *thread = exe_ctx.GetThreadPtr();
168 if (thread)
Chris Lattner24943d22010-06-08 16:52:24 +0000169 {
Johnny Chen2d268cb2011-06-02 18:02:15 +0000170 // Thread::GetStatus() returns the number of frames shown.
Greg Clayton567e7f32011-09-22 04:58:26 +0000171 if (thread->GetStatus (strm,
172 m_options.m_start,
173 m_options.m_count,
174 num_frames_with_source))
Chris Lattner24943d22010-06-08 16:52:24 +0000175 {
176 result.SetStatus (eReturnStatusSuccessFinishResult);
177 }
178 }
179 else
180 {
181 result.AppendError ("invalid thread");
182 result.SetStatus (eReturnStatusFailed);
183 }
184 }
Jim Inghameb10f7b2010-08-27 00:58:05 +0000185 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
186 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000187 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghameb10f7b2010-08-27 00:58:05 +0000188 uint32_t num_threads = process->GetThreadList().GetSize();
189 for (uint32_t i = 0; i < num_threads; i++)
190 {
191 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
Johnny Chen05750a62011-06-01 23:19:52 +0000192 if (!thread_sp->GetStatus (strm,
193 m_options.m_start,
194 m_options.m_count,
195 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000196 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000197 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
Jim Inghameb10f7b2010-08-27 00:58:05 +0000198 result.SetStatus (eReturnStatusFailed);
199 return false;
200 }
Jim Ingham7868bcc2011-07-26 02:39:59 +0000201
202 if (i < num_threads - 1)
203 result.AppendMessage("");
204
Jim Inghameb10f7b2010-08-27 00:58:05 +0000205 }
206 }
Chris Lattner24943d22010-06-08 16:52:24 +0000207 else
208 {
Jim Inghameb10f7b2010-08-27 00:58:05 +0000209 uint32_t num_args = command.GetArgumentCount();
Greg Clayton567e7f32011-09-22 04:58:26 +0000210 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Jim Inghameb10f7b2010-08-27 00:58:05 +0000211 std::vector<ThreadSP> thread_sps;
212
213 for (uint32_t i = 0; i < num_args; i++)
214 {
215 bool success;
216
217 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
218 if (!success)
219 {
220 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
221 result.SetStatus (eReturnStatusFailed);
222 return false;
223 }
224
225 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
226
227 if (!thread_sps[i])
228 {
229 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
230 result.SetStatus (eReturnStatusFailed);
231 return false;
232 }
233
234 }
235
236 for (uint32_t i = 0; i < num_args; i++)
237 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000238 if (!thread_sps[i]->GetStatus (strm,
239 m_options.m_start,
240 m_options.m_count,
241 num_frames_with_source))
Jim Inghameb10f7b2010-08-27 00:58:05 +0000242 {
243 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
244 result.SetStatus (eReturnStatusFailed);
245 return false;
246 }
247
248 if (i < num_args - 1)
249 result.AppendMessage("");
250 }
Chris Lattner24943d22010-06-08 16:52:24 +0000251 }
252 return result.Succeeded();
253 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000254
Jim Ingham8ab1a802010-08-26 23:36:03 +0000255 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000256};
257
Greg Claytonb3448432011-03-24 21:19:54 +0000258OptionDefinition
Jim Ingham8ab1a802010-08-26 23:36:03 +0000259CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
260{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000261{ 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 +0000262{ 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 +0000263{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham8ab1a802010-08-26 23:36:03 +0000264};
Chris Lattner24943d22010-06-08 16:52:24 +0000265
Greg Claytonc0418152010-07-07 17:07:17 +0000266enum StepScope
Chris Lattner24943d22010-06-08 16:52:24 +0000267{
268 eStepScopeSource,
269 eStepScopeInstruction
270};
271
Jim Inghamda26bd22012-06-08 21:56:10 +0000272class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000273{
274public:
275
276 class CommandOptions : public Options
277 {
278 public:
279
Greg Claytonf15996e2011-04-07 22:46:35 +0000280 CommandOptions (CommandInterpreter &interpreter) :
281 Options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000282 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000283 // Keep default values of all options in one place: OptionParsingStarting ()
284 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000285 }
286
287 virtual
288 ~CommandOptions ()
289 {
290 }
291
292 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000293 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000294 {
295 Error error;
296 char short_option = (char) m_getopt_table[option_idx].val;
297
298 switch (short_option)
299 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000300 case 'a':
Chris Lattner24943d22010-06-08 16:52:24 +0000301 {
302 bool success;
303 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
304 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000305 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000306 }
307 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000308
309 case 'm':
Chris Lattner24943d22010-06-08 16:52:24 +0000310 {
Chris Lattner24943d22010-06-08 16:52:24 +0000311 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000312 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000313 }
314 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000315
316 case 'r':
Jim Ingham809ab9b2010-07-10 02:27:39 +0000317 {
318 m_avoid_regexp.clear();
319 m_avoid_regexp.assign(option_arg);
320 }
321 break;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000322
323 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000324 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8d3802d2010-10-08 04:20:14 +0000325 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000326
327 }
328 return error;
329 }
330
331 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000332 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000333 {
Chris Lattner24943d22010-06-08 16:52:24 +0000334 m_avoid_no_debug = true;
335 m_run_mode = eOnlyDuringStepping;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000336 m_avoid_regexp.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000337 }
338
Greg Claytonb3448432011-03-24 21:19:54 +0000339 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000340 GetDefinitions ()
341 {
342 return g_option_table;
343 }
344
345 // Options table: Required for subclasses of Options.
346
Greg Claytonb3448432011-03-24 21:19:54 +0000347 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000348
349 // Instance variables to hold the values for command options.
350 bool m_avoid_no_debug;
351 RunMode m_run_mode;
Jim Ingham809ab9b2010-07-10 02:27:39 +0000352 std::string m_avoid_regexp;
Chris Lattner24943d22010-06-08 16:52:24 +0000353 };
354
Greg Clayton238c0a12010-09-18 01:14:36 +0000355 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
356 const char *name,
357 const char *help,
358 const char *syntax,
359 uint32_t flags,
360 StepType step_type,
361 StepScope step_scope) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000362 CommandObjectParsed (interpreter, name, help, syntax, flags),
Chris Lattner24943d22010-06-08 16:52:24 +0000363 m_step_type (step_type),
364 m_step_scope (step_scope),
Greg Claytonf15996e2011-04-07 22:46:35 +0000365 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000366 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000367 CommandArgumentEntry arg;
368 CommandArgumentData thread_id_arg;
369
370 // Define the first (and only) variant of this arg.
371 thread_id_arg.arg_type = eArgTypeThreadID;
372 thread_id_arg.arg_repetition = eArgRepeatOptional;
373
374 // There is only one variant this argument could be; put it into the argument entry.
375 arg.push_back (thread_id_arg);
376
377 // Push the data for the first argument into the m_arguments vector.
378 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000379 }
380
381 virtual
382 ~CommandObjectThreadStepWithTypeAndScope ()
383 {
384 }
385
386 virtual
387 Options *
388 GetOptions ()
389 {
390 return &m_options;
391 }
392
Jim Inghamda26bd22012-06-08 21:56:10 +0000393protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000394 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000395 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000396 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000397 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton238c0a12010-09-18 01:14:36 +0000398 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner24943d22010-06-08 16:52:24 +0000399
400 if (process == NULL)
401 {
402 result.AppendError ("need a valid process to step");
403 result.SetStatus (eReturnStatusFailed);
404
405 }
406 else
407 {
408 const uint32_t num_threads = process->GetThreadList().GetSize();
409 Thread *thread = NULL;
410
411 if (command.GetArgumentCount() == 0)
412 {
Jim Inghamc8332952010-08-26 21:32:51 +0000413 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000414 if (thread == NULL)
415 {
Jim Ingham8ab1a802010-08-26 23:36:03 +0000416 result.AppendError ("no selected thread in process");
Chris Lattner24943d22010-06-08 16:52:24 +0000417 result.SetStatus (eReturnStatusFailed);
418 return false;
419 }
420 }
421 else
422 {
423 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
424 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
425 if (step_thread_idx == LLDB_INVALID_INDEX32)
426 {
Greg Clayton9c236732011-10-26 00:56:27 +0000427 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +0000428 result.SetStatus (eReturnStatusFailed);
429 return false;
430 }
431 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
432 if (thread == NULL)
433 {
434 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000435 step_thread_idx, num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000436 result.SetStatus (eReturnStatusFailed);
437 return false;
438 }
439 }
440
441 const bool abort_other_plans = false;
442 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
443
444 // This is a bit unfortunate, but not all the commands in this command object support
445 // only while stepping, so I use the bool for them.
446 bool bool_stop_other_threads;
447 if (m_options.m_run_mode == eAllThreads)
448 bool_stop_other_threads = false;
449 else
450 bool_stop_other_threads = true;
451
Jim Ingham88e3de22012-05-03 21:19:36 +0000452 ThreadPlan *new_plan = NULL;
453
Chris Lattner24943d22010-06-08 16:52:24 +0000454 if (m_step_type == eStepTypeInto)
455 {
456 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000457
458 if (frame->HasDebugInformation ())
459 {
460 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
461 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
462 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000463 stop_other_threads,
464 m_options.m_avoid_no_debug);
Jim Ingham809ab9b2010-07-10 02:27:39 +0000465 if (new_plan && !m_options.m_avoid_regexp.empty())
466 {
467 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
468 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
469 }
Chris Lattner24943d22010-06-08 16:52:24 +0000470 }
471 else
472 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Jim Ingham88e3de22012-05-03 21:19:36 +0000473
Chris Lattner24943d22010-06-08 16:52:24 +0000474 }
475 else if (m_step_type == eStepTypeOver)
476 {
477 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000478
479 if (frame->HasDebugInformation())
480 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
481 m_step_type,
482 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
483 frame->GetSymbolContext(eSymbolContextEverything),
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000484 stop_other_threads,
485 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000486 else
487 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
488 abort_other_plans,
489 bool_stop_other_threads);
490
Chris Lattner24943d22010-06-08 16:52:24 +0000491 }
492 else if (m_step_type == eStepTypeTrace)
493 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000494 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000495 }
496 else if (m_step_type == eStepTypeTraceOver)
497 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000498 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000499 }
500 else if (m_step_type == eStepTypeOut)
501 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000502 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
503 NULL,
504 false,
505 bool_stop_other_threads,
506 eVoteYes,
507 eVoteNoOpinion,
508 thread->GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000509 }
510 else
511 {
512 result.AppendError ("step type is not supported");
513 result.SetStatus (eReturnStatusFailed);
Jim Ingham88e3de22012-05-03 21:19:36 +0000514 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000515 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000516
517 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
518 // so that they can be interruptible). Then resume the process.
519
520 if (new_plan != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000521 {
Jim Ingham88e3de22012-05-03 21:19:36 +0000522 new_plan->SetIsMasterPlan (true);
523 new_plan->SetOkayToDiscard (false);
524
Jim Inghamc8332952010-08-26 21:32:51 +0000525 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Jim Ingham88e3de22012-05-03 21:19:36 +0000526 process->Resume ();
527
528
529 if (synchronous_execution)
530 {
531 StateType state = process->WaitForProcessToStop (NULL);
532
533 //EventSP event_sp;
534 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
535 //while (! StateIsStoppedState (state))
536 // {
537 // state = process->WaitForStateChangedEvents (NULL, event_sp);
538 // }
539 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
540 result.SetDidChangeProcessState (true);
541 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
542 result.SetStatus (eReturnStatusSuccessFinishNoResult);
543 }
Jim Ingham53628e72012-05-16 00:37:40 +0000544 else
545 {
546 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
547 }
Jim Ingham88e3de22012-05-03 21:19:36 +0000548 }
549 else
550 {
551 result.AppendError ("Couldn't find thread plan to implement step type.");
552 result.SetStatus (eReturnStatusFailed);
Chris Lattner24943d22010-06-08 16:52:24 +0000553 }
554 }
555 return result.Succeeded();
556 }
557
558protected:
559 StepType m_step_type;
560 StepScope m_step_scope;
561 CommandOptions m_options;
562};
563
Greg Claytonb3448432011-03-24 21:19:54 +0000564static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000565g_tri_running_mode[] =
566{
Greg Claytonfe424a92010-09-18 03:37:20 +0000567{ eOnlyThisThread, "this-thread", "Run only this thread"},
568{ eAllThreads, "all-threads", "Run all threads"},
569{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner24943d22010-06-08 16:52:24 +0000570{ 0, NULL, NULL }
571};
572
Greg Claytonb3448432011-03-24 21:19:54 +0000573static OptionEnumValueElement
Chris Lattner24943d22010-06-08 16:52:24 +0000574g_duo_running_mode[] =
575{
Greg Claytonfe424a92010-09-18 03:37:20 +0000576{ eOnlyThisThread, "this-thread", "Run only this thread"},
577{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner24943d22010-06-08 16:52:24 +0000578{ 0, NULL, NULL }
579};
580
Greg Claytonb3448432011-03-24 21:19:54 +0000581OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000582CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
583{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000584{ LLDB_OPT_SET_1, false, "avoid-no-debug", 'a', required_argument, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether step-in will step over functions with no debug information."},
585{ LLDB_OPT_SET_1, false, "run-mode", 'm', required_argument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
586{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
587{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000588};
589
590
591//-------------------------------------------------------------------------
592// CommandObjectThreadContinue
593//-------------------------------------------------------------------------
594
Jim Inghamda26bd22012-06-08 21:56:10 +0000595class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000596{
597public:
598
Greg Clayton238c0a12010-09-18 01:14:36 +0000599 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000600 CommandObjectParsed (interpreter,
601 "thread continue",
602 "Continue execution of one or more threads in an active process.",
603 NULL,
604 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +0000605 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000606 CommandArgumentEntry arg;
607 CommandArgumentData thread_idx_arg;
608
609 // Define the first (and only) variant of this arg.
610 thread_idx_arg.arg_type = eArgTypeThreadIndex;
611 thread_idx_arg.arg_repetition = eArgRepeatPlus;
612
613 // There is only one variant this argument could be; put it into the argument entry.
614 arg.push_back (thread_idx_arg);
615
616 // Push the data for the first argument into the m_arguments vector.
617 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000618 }
619
620
621 virtual
622 ~CommandObjectThreadContinue ()
623 {
624 }
625
626 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000627 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000628 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000629 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000630
Greg Clayton238c0a12010-09-18 01:14:36 +0000631 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000632 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000633 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000634 result.SetStatus (eReturnStatusFailed);
635 return false;
636 }
637
Greg Clayton567e7f32011-09-22 04:58:26 +0000638 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000639 if (process == NULL)
640 {
641 result.AppendError ("no process exists. Cannot continue");
642 result.SetStatus (eReturnStatusFailed);
643 return false;
644 }
645
646 StateType state = process->GetState();
647 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
648 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000649 Mutex::Locker locker (process->GetThreadList().GetMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000650 const uint32_t num_threads = process->GetThreadList().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000651 const size_t argc = command.GetArgumentCount();
652 if (argc > 0)
653 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000654 std::vector<Thread *> resume_threads;
Chris Lattner24943d22010-06-08 16:52:24 +0000655 for (uint32_t i=0; i<argc; ++i)
656 {
Jim Inghamd07b4f52012-05-31 20:48:41 +0000657 bool success;
658 const int base = 0;
Greg Claytonedd601a2012-07-03 20:54:16 +0000659 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
660 if (success)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000661 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000662 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
663
664 if (thread)
665 {
666 resume_threads.push_back(thread);
667 }
668 else
669 {
670 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
671 result.SetStatus (eReturnStatusFailed);
672 return false;
673 }
Jim Inghamd07b4f52012-05-31 20:48:41 +0000674 }
Chris Lattner24943d22010-06-08 16:52:24 +0000675 else
Jim Inghamd07b4f52012-05-31 20:48:41 +0000676 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000677 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd07b4f52012-05-31 20:48:41 +0000678 result.SetStatus (eReturnStatusFailed);
679 return false;
680 }
Chris Lattner24943d22010-06-08 16:52:24 +0000681 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000682
683 if (resume_threads.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000684 {
685 result.AppendError ("no valid thread indexes were specified");
686 result.SetStatus (eReturnStatusFailed);
687 return false;
688 }
689 else
690 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000691 if (resume_threads.size() == 1)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000692 result.AppendMessageWithFormat ("Resuming thread: ");
693 else
694 result.AppendMessageWithFormat ("Resuming threads: ");
Greg Claytonedd601a2012-07-03 20:54:16 +0000695
696 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000697 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000698 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
699 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Jim Inghamd07b4f52012-05-31 20:48:41 +0000700
Greg Claytonedd601a2012-07-03 20:54:16 +0000701 if (this_thread_pos != resume_threads.end())
Chris Lattner24943d22010-06-08 16:52:24 +0000702 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000703 resume_threads.erase(this_thread_pos);
704 if (resume_threads.size() > 0)
Jim Inghamd07b4f52012-05-31 20:48:41 +0000705 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
706 else
707 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
708
Chris Lattner24943d22010-06-08 16:52:24 +0000709 thread->SetResumeState (eStateRunning);
710 }
711 else
712 {
713 thread->SetResumeState (eStateSuspended);
714 }
715 }
Greg Clayton444e35b2011-10-19 18:09:39 +0000716 result.AppendMessageWithFormat ("in process %llu\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000717 }
718 }
719 else
720 {
Jim Inghamc8332952010-08-26 21:32:51 +0000721 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000722 if (current_thread == NULL)
723 {
724 result.AppendError ("the process doesn't have a current thread");
725 result.SetStatus (eReturnStatusFailed);
726 return false;
727 }
728 // Set the actions that the threads should each take when resuming
Greg Claytonedd601a2012-07-03 20:54:16 +0000729 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000730 {
Greg Claytonedd601a2012-07-03 20:54:16 +0000731 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000732 if (thread == current_thread)
733 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000734 result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000735 thread->SetResumeState (eStateRunning);
736 }
737 else
738 {
739 thread->SetResumeState (eStateSuspended);
740 }
741 }
742 }
Greg Claytonedd601a2012-07-03 20:54:16 +0000743
Chris Lattner24943d22010-06-08 16:52:24 +0000744 Error error (process->Resume());
745 if (error.Success())
746 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000747 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000748 if (synchronous_execution)
749 {
Greg Claytonbef15832010-07-14 00:18:15 +0000750 state = process->WaitForProcessToStop (NULL);
Greg Claytonedd601a2012-07-03 20:54:16 +0000751
Chris Lattner24943d22010-06-08 16:52:24 +0000752 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +0000753 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +0000754 result.SetStatus (eReturnStatusSuccessFinishNoResult);
755 }
756 else
757 {
758 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
759 }
760 }
761 else
762 {
763 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
764 result.SetStatus (eReturnStatusFailed);
765 }
766 }
767 else
768 {
769 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
770 StateAsCString(state));
771 result.SetStatus (eReturnStatusFailed);
772 }
773
774 return result.Succeeded();
775 }
776
777};
778
779//-------------------------------------------------------------------------
780// CommandObjectThreadUntil
781//-------------------------------------------------------------------------
782
Jim Inghamda26bd22012-06-08 21:56:10 +0000783class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000784{
785public:
786
787 class CommandOptions : public Options
788 {
789 public:
790 uint32_t m_thread_idx;
791 uint32_t m_frame_idx;
792
Greg Claytonf15996e2011-04-07 22:46:35 +0000793 CommandOptions (CommandInterpreter &interpreter) :
794 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000795 m_thread_idx(LLDB_INVALID_THREAD_ID),
796 m_frame_idx(LLDB_INVALID_FRAME_ID)
797 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000798 // Keep default values of all options in one place: OptionParsingStarting ()
799 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000800 }
801
802 virtual
803 ~CommandOptions ()
804 {
805 }
806
807 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000808 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000809 {
810 Error error;
811 char short_option = (char) m_getopt_table[option_idx].val;
812
813 switch (short_option)
814 {
815 case 't':
816 {
Greg Claytonbef15832010-07-14 00:18:15 +0000817 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000818 if (m_thread_idx == LLDB_INVALID_INDEX32)
819 {
Greg Clayton9c236732011-10-26 00:56:27 +0000820 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000821 }
822 }
823 break;
824 case 'f':
825 {
826 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
827 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
828 {
Greg Clayton9c236732011-10-26 00:56:27 +0000829 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000830 }
831 }
832 break;
833 case 'm':
834 {
Chris Lattner24943d22010-06-08 16:52:24 +0000835 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000836 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000837
Greg Clayton61aca5d2011-10-07 18:58:12 +0000838 if (error.Success())
839 {
840 if (run_mode == eAllThreads)
841 m_stop_others = false;
842 else
843 m_stop_others = true;
844 }
Chris Lattner24943d22010-06-08 16:52:24 +0000845 }
846 break;
847 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000848 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000849 break;
850
851 }
852 return error;
853 }
854
855 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000856 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000857 {
Chris Lattner24943d22010-06-08 16:52:24 +0000858 m_thread_idx = LLDB_INVALID_THREAD_ID;
859 m_frame_idx = 0;
860 m_stop_others = false;
861 }
862
Greg Claytonb3448432011-03-24 21:19:54 +0000863 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000864 GetDefinitions ()
865 {
866 return g_option_table;
867 }
868
869 uint32_t m_step_thread_idx;
870 bool m_stop_others;
871
872 // Options table: Required for subclasses of Options.
873
Greg Claytonb3448432011-03-24 21:19:54 +0000874 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000875
876 // Instance variables to hold the values for command options.
877 };
878
Greg Clayton238c0a12010-09-18 01:14:36 +0000879 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000880 CommandObjectParsed (interpreter,
881 "thread until",
882 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
883 NULL,
884 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000885 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000886 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000887 CommandArgumentEntry arg;
888 CommandArgumentData line_num_arg;
889
890 // Define the first (and only) variant of this arg.
891 line_num_arg.arg_type = eArgTypeLineNum;
892 line_num_arg.arg_repetition = eArgRepeatPlain;
893
894 // There is only one variant this argument could be; put it into the argument entry.
895 arg.push_back (line_num_arg);
896
897 // Push the data for the first argument into the m_arguments vector.
898 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000899 }
900
901
902 virtual
903 ~CommandObjectThreadUntil ()
904 {
905 }
906
907 virtual
908 Options *
909 GetOptions ()
910 {
911 return &m_options;
912 }
913
Jim Inghamda26bd22012-06-08 21:56:10 +0000914protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000915 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000916 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000917 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000918 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000919
Greg Clayton238c0a12010-09-18 01:14:36 +0000920 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000921 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000922 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000923 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000924 result.SetStatus (eReturnStatusFailed);
925 return false;
926 }
927
Greg Clayton567e7f32011-09-22 04:58:26 +0000928 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000929 if (process == NULL)
930 {
931 result.AppendError ("need a valid process to step");
932 result.SetStatus (eReturnStatusFailed);
933
934 }
935 else
936 {
937 Thread *thread = NULL;
938 uint32_t line_number;
939
940 if (command.GetArgumentCount() != 1)
941 {
942 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
943 result.SetStatus (eReturnStatusFailed);
944 return false;
945 }
946
947 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
948 if (line_number == UINT32_MAX)
949 {
Greg Clayton9c236732011-10-26 00:56:27 +0000950 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +0000951 result.SetStatus (eReturnStatusFailed);
952 return false;
953 }
954
955 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
956 {
Jim Inghamc8332952010-08-26 21:32:51 +0000957 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000958 }
959 else
960 {
Greg Claytona2243772012-05-31 00:29:20 +0000961 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000962 }
963
964 if (thread == NULL)
965 {
966 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000967 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
968 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000969 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000970 result.SetStatus (eReturnStatusFailed);
971 return false;
972 }
973
Jim Inghamd82bc6d2012-05-11 23:47:32 +0000974 const bool abort_other_plans = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000975
976 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
977 if (frame == NULL)
978 {
979
Jim Inghamb07c62a2011-05-08 00:56:32 +0000980 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
981 m_options.m_frame_idx,
982 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000983 result.SetStatus (eReturnStatusFailed);
984 return false;
985 }
986
Jim Ingham88e3de22012-05-03 21:19:36 +0000987 ThreadPlan *new_plan = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000988
989 if (frame->HasDebugInformation ())
990 {
991 // Finally we got here... Translate the given line number to a bunch of addresses:
992 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
993 LineTable *line_table = NULL;
994 if (sc.comp_unit)
995 line_table = sc.comp_unit->GetLineTable();
996
997 if (line_table == NULL)
998 {
999 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1000 m_options.m_frame_idx, m_options.m_thread_idx);
1001 result.SetStatus (eReturnStatusFailed);
1002 return false;
1003 }
1004
1005 LineEntry function_start;
1006 uint32_t index_ptr = 0, end_ptr;
1007 std::vector<addr_t> address_list;
1008
1009 // Find the beginning & end index of the
1010 AddressRange fun_addr_range = sc.function->GetAddressRange();
1011 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1012 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1013
Jim Inghamb07c62a2011-05-08 00:56:32 +00001014 Address fun_end_addr(fun_start_addr.GetSection(),
1015 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00001016 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1017
Jim Inghamb07c62a2011-05-08 00:56:32 +00001018 bool all_in_function = true;
1019
Chris Lattner24943d22010-06-08 16:52:24 +00001020 while (index_ptr <= end_ptr)
1021 {
1022 LineEntry line_entry;
Jim Inghamd6d47972011-09-23 00:54:11 +00001023 const bool exact = false;
1024 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +00001025 if (index_ptr == UINT32_MAX)
1026 break;
1027
Greg Claytoneea26402010-09-14 23:36:40 +00001028 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001029 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001030 {
1031 if (fun_addr_range.ContainsLoadAddress (address, target))
1032 address_list.push_back (address);
1033 else
1034 all_in_function = false;
1035 }
Chris Lattner24943d22010-06-08 16:52:24 +00001036 index_ptr++;
1037 }
1038
Jim Inghamb07c62a2011-05-08 00:56:32 +00001039 if (address_list.size() == 0)
1040 {
1041 if (all_in_function)
1042 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1043 else
1044 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1045
1046 result.SetStatus (eReturnStatusFailed);
1047 return false;
1048 }
1049
1050 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1051 &address_list.front(),
1052 address_list.size(),
1053 m_options.m_stop_others,
1054 thread->GetSelectedFrameIndex ());
Jim Ingham88e3de22012-05-03 21:19:36 +00001055 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1056 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1057 // will resume the original plan.
1058 new_plan->SetIsMasterPlan (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001059 new_plan->SetOkayToDiscard(false);
1060 }
1061 else
1062 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001063 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1064 m_options.m_frame_idx,
1065 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001066 result.SetStatus (eReturnStatusFailed);
1067 return false;
1068
1069 }
1070
Jim Inghamc8332952010-08-26 21:32:51 +00001071 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001072 Error error (process->Resume ());
1073 if (error.Success())
1074 {
Greg Clayton444e35b2011-10-19 18:09:39 +00001075 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001076 if (synchronous_execution)
1077 {
1078 StateType state = process->WaitForProcessToStop (NULL);
1079
1080 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +00001081 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +00001082 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1083 }
1084 else
1085 {
1086 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1087 }
1088 }
1089 else
1090 {
1091 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1092 result.SetStatus (eReturnStatusFailed);
1093 }
1094
1095 }
1096 return result.Succeeded();
1097 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001098
Chris Lattner24943d22010-06-08 16:52:24 +00001099 CommandOptions m_options;
1100
1101};
1102
Greg Claytonb3448432011-03-24 21:19:54 +00001103OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001104CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1105{
Caroline Tice43b014a2010-10-04 22:28:36 +00001106{ 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 +00001107{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1108{ 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"},
1109{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001110};
1111
1112
1113//-------------------------------------------------------------------------
1114// CommandObjectThreadSelect
1115//-------------------------------------------------------------------------
1116
Jim Inghamda26bd22012-06-08 21:56:10 +00001117class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001118{
1119public:
1120
Greg Clayton238c0a12010-09-18 01:14:36 +00001121 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001122 CommandObjectParsed (interpreter,
1123 "thread select",
1124 "Select a thread as the currently active thread.",
1125 NULL,
1126 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001127 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001128 CommandArgumentEntry arg;
1129 CommandArgumentData thread_idx_arg;
1130
1131 // Define the first (and only) variant of this arg.
1132 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1133 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1134
1135 // There is only one variant this argument could be; put it into the argument entry.
1136 arg.push_back (thread_idx_arg);
1137
1138 // Push the data for the first argument into the m_arguments vector.
1139 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001140 }
1141
1142
1143 virtual
1144 ~CommandObjectThreadSelect ()
1145 {
1146 }
1147
Jim Inghamda26bd22012-06-08 21:56:10 +00001148protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001149 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001150 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001151 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001152 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001153 if (process == NULL)
1154 {
1155 result.AppendError ("no process");
1156 result.SetStatus (eReturnStatusFailed);
1157 return false;
1158 }
1159 else if (command.GetArgumentCount() != 1)
1160 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001161 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 +00001162 result.SetStatus (eReturnStatusFailed);
1163 return false;
1164 }
1165
1166 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1167
1168 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1169 if (new_thread == NULL)
1170 {
Greg Clayton9c236732011-10-26 00:56:27 +00001171 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +00001172 result.SetStatus (eReturnStatusFailed);
1173 return false;
1174 }
1175
Jim Inghamc8332952010-08-26 21:32:51 +00001176 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001177 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001178
Greg Claytonabe0fed2011-04-18 08:33:37 +00001179 const uint32_t start_frame = 0;
1180 const uint32_t num_frames = 1;
1181 const uint32_t num_frames_with_source = 1;
1182 new_thread->GetStatus (result.GetOutputStream(),
1183 start_frame,
1184 num_frames,
1185 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001186
1187 return result.Succeeded();
1188 }
1189
1190};
1191
1192
1193//-------------------------------------------------------------------------
1194// CommandObjectThreadList
1195//-------------------------------------------------------------------------
1196
Jim Inghamda26bd22012-06-08 21:56:10 +00001197class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001198{
Greg Clayton63094e02010-06-23 01:19:29 +00001199public:
Chris Lattner24943d22010-06-08 16:52:24 +00001200
Chris Lattner24943d22010-06-08 16:52:24 +00001201
Greg Clayton238c0a12010-09-18 01:14:36 +00001202 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Inghamda26bd22012-06-08 21:56:10 +00001203 CommandObjectParsed (interpreter,
1204 "thread list",
1205 "Show a summary of all current threads in a process.",
1206 "thread list",
1207 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001208 {
Greg Clayton63094e02010-06-23 01:19:29 +00001209 }
Chris Lattner24943d22010-06-08 16:52:24 +00001210
Greg Clayton63094e02010-06-23 01:19:29 +00001211 ~CommandObjectThreadList()
1212 {
1213 }
1214
Jim Inghamda26bd22012-06-08 21:56:10 +00001215protected:
Greg Clayton63094e02010-06-23 01:19:29 +00001216 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001217 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton63094e02010-06-23 01:19:29 +00001218 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001219 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001220 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001221 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001222 Process *process = exe_ctx.GetProcessPtr();
1223 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00001224 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001225 const bool only_threads_with_stop_reason = false;
1226 const uint32_t start_frame = 0;
1227 const uint32_t num_frames = 0;
1228 const uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +00001229 process->GetStatus(strm);
1230 process->GetThreadStatus (strm,
1231 only_threads_with_stop_reason,
1232 start_frame,
1233 num_frames,
1234 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001235 }
1236 else
1237 {
Greg Clayton63094e02010-06-23 01:19:29 +00001238 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001239 result.SetStatus (eReturnStatusFailed);
1240 }
Greg Clayton63094e02010-06-23 01:19:29 +00001241 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001242 }
Greg Clayton63094e02010-06-23 01:19:29 +00001243};
Chris Lattner24943d22010-06-08 16:52:24 +00001244
1245//-------------------------------------------------------------------------
1246// CommandObjectMultiwordThread
1247//-------------------------------------------------------------------------
1248
Greg Clayton63094e02010-06-23 01:19:29 +00001249CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001250 CommandObjectMultiword (interpreter,
1251 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001252 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001253 "thread <subcommand> [<subcommand-options>]")
1254{
Greg Clayton238c0a12010-09-18 01:14:36 +00001255 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1256 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1257 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1258 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1259 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1260 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1261 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001262 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001263 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001264 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001265 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1266 eStepTypeInto,
1267 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001268
Greg Clayton238c0a12010-09-18 01:14:36 +00001269 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1270 interpreter,
1271 "thread step-out",
Jim Ingham1586d972011-12-17 01:35:57 +00001272 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001273 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001274 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1275 eStepTypeOut,
1276 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001277
Greg Clayton238c0a12010-09-18 01:14:36 +00001278 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1279 interpreter,
1280 "thread step-over",
1281 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001282 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001283 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1284 eStepTypeOver,
1285 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001286
Greg Clayton238c0a12010-09-18 01:14:36 +00001287 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1288 interpreter,
1289 "thread step-inst",
1290 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001291 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001292 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1293 eStepTypeTrace,
1294 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001295
Greg Clayton238c0a12010-09-18 01:14:36 +00001296 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1297 interpreter,
1298 "thread step-inst-over",
1299 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001300 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001301 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1302 eStepTypeTraceOver,
1303 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001304}
1305
1306CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1307{
1308}
1309
1310