blob: 865dfc96281b5af1ca9ccdbfc545829c66916a21 [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 {
649 const uint32_t num_threads = process->GetThreadList().GetSize();
650 uint32_t idx;
651 const size_t argc = command.GetArgumentCount();
652 if (argc > 0)
653 {
654 std::vector<uint32_t> resume_thread_indexes;
655 for (uint32_t i=0; i<argc; ++i)
656 {
Jim Inghamd07b4f52012-05-31 20:48:41 +0000657 bool success;
658 const int base = 0;
659 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
660 if (!success)
661 {
662 result.AppendErrorWithFormat ("invalid value for thread index: %s.", command.GetArgumentAtIndex(i));
663 result.SetStatus (eReturnStatusFailed);
664 return false;
665 }
666 else if (process->GetThreadList().FindThreadByIndexID(idx))
667 {
668 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) == resume_thread_indexes.end())
669 resume_thread_indexes.push_back(idx);
670 }
Chris Lattner24943d22010-06-08 16:52:24 +0000671 else
Jim Inghamd07b4f52012-05-31 20:48:41 +0000672 {
673 result.AppendErrorWithFormat("thread index %u out of range.\n", idx);
674 result.SetStatus (eReturnStatusFailed);
675 return false;
676 }
Chris Lattner24943d22010-06-08 16:52:24 +0000677 }
678
679 if (resume_thread_indexes.empty())
680 {
681 result.AppendError ("no valid thread indexes were specified");
682 result.SetStatus (eReturnStatusFailed);
683 return false;
684 }
685 else
686 {
Jim Inghamd07b4f52012-05-31 20:48:41 +0000687 if (resume_thread_indexes.size() == 1)
688 result.AppendMessageWithFormat ("Resuming thread: ");
689 else
690 result.AppendMessageWithFormat ("Resuming threads: ");
691
Chris Lattner24943d22010-06-08 16:52:24 +0000692 for (idx=0; idx<num_threads; ++idx)
693 {
Greg Claytona2243772012-05-31 00:29:20 +0000694 Thread *thread = process->GetThreadList().FindThreadByIndexID(idx).get();
Jim Inghamd07b4f52012-05-31 20:48:41 +0000695 std::vector<uint32_t>::iterator this_thread_pos = find(resume_thread_indexes.begin(), resume_thread_indexes.end(), thread->GetIndexID());
696
697 if (this_thread_pos != resume_thread_indexes.end())
Chris Lattner24943d22010-06-08 16:52:24 +0000698 {
Jim Inghamd07b4f52012-05-31 20:48:41 +0000699 resume_thread_indexes.erase(this_thread_pos);
700 if (resume_thread_indexes.size() > 0)
701 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
702 else
703 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
704
Chris Lattner24943d22010-06-08 16:52:24 +0000705 thread->SetResumeState (eStateRunning);
706 }
707 else
708 {
709 thread->SetResumeState (eStateSuspended);
710 }
711 }
Greg Clayton444e35b2011-10-19 18:09:39 +0000712 result.AppendMessageWithFormat ("in process %llu\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000713 }
714 }
715 else
716 {
Jim Inghamc8332952010-08-26 21:32:51 +0000717 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000718 if (current_thread == NULL)
719 {
720 result.AppendError ("the process doesn't have a current thread");
721 result.SetStatus (eReturnStatusFailed);
722 return false;
723 }
724 // Set the actions that the threads should each take when resuming
725 for (idx=0; idx<num_threads; ++idx)
726 {
Greg Claytona2243772012-05-31 00:29:20 +0000727 Thread *thread = process->GetThreadList().FindThreadByIndexID(idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000728 if (thread == current_thread)
729 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000730 result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000731 thread->SetResumeState (eStateRunning);
732 }
733 else
734 {
735 thread->SetResumeState (eStateSuspended);
736 }
737 }
738 }
739
740 Error error (process->Resume());
741 if (error.Success())
742 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000743 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000744 if (synchronous_execution)
745 {
Greg Claytonbef15832010-07-14 00:18:15 +0000746 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000747
748 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +0000749 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +0000750 result.SetStatus (eReturnStatusSuccessFinishNoResult);
751 }
752 else
753 {
754 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
755 }
756 }
757 else
758 {
759 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
760 result.SetStatus (eReturnStatusFailed);
761 }
762 }
763 else
764 {
765 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
766 StateAsCString(state));
767 result.SetStatus (eReturnStatusFailed);
768 }
769
770 return result.Succeeded();
771 }
772
773};
774
775//-------------------------------------------------------------------------
776// CommandObjectThreadUntil
777//-------------------------------------------------------------------------
778
Jim Inghamda26bd22012-06-08 21:56:10 +0000779class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000780{
781public:
782
783 class CommandOptions : public Options
784 {
785 public:
786 uint32_t m_thread_idx;
787 uint32_t m_frame_idx;
788
Greg Claytonf15996e2011-04-07 22:46:35 +0000789 CommandOptions (CommandInterpreter &interpreter) :
790 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000791 m_thread_idx(LLDB_INVALID_THREAD_ID),
792 m_frame_idx(LLDB_INVALID_FRAME_ID)
793 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000794 // Keep default values of all options in one place: OptionParsingStarting ()
795 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000796 }
797
798 virtual
799 ~CommandOptions ()
800 {
801 }
802
803 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000804 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000805 {
806 Error error;
807 char short_option = (char) m_getopt_table[option_idx].val;
808
809 switch (short_option)
810 {
811 case 't':
812 {
Greg Claytonbef15832010-07-14 00:18:15 +0000813 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner24943d22010-06-08 16:52:24 +0000814 if (m_thread_idx == LLDB_INVALID_INDEX32)
815 {
Greg Clayton9c236732011-10-26 00:56:27 +0000816 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000817 }
818 }
819 break;
820 case 'f':
821 {
822 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
823 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
824 {
Greg Clayton9c236732011-10-26 00:56:27 +0000825 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000826 }
827 }
828 break;
829 case 'm':
830 {
Chris Lattner24943d22010-06-08 16:52:24 +0000831 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Clayton61aca5d2011-10-07 18:58:12 +0000832 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000833
Greg Clayton61aca5d2011-10-07 18:58:12 +0000834 if (error.Success())
835 {
836 if (run_mode == eAllThreads)
837 m_stop_others = false;
838 else
839 m_stop_others = true;
840 }
Chris Lattner24943d22010-06-08 16:52:24 +0000841 }
842 break;
843 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000844 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000845 break;
846
847 }
848 return error;
849 }
850
851 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000852 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000853 {
Chris Lattner24943d22010-06-08 16:52:24 +0000854 m_thread_idx = LLDB_INVALID_THREAD_ID;
855 m_frame_idx = 0;
856 m_stop_others = false;
857 }
858
Greg Claytonb3448432011-03-24 21:19:54 +0000859 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000860 GetDefinitions ()
861 {
862 return g_option_table;
863 }
864
865 uint32_t m_step_thread_idx;
866 bool m_stop_others;
867
868 // Options table: Required for subclasses of Options.
869
Greg Claytonb3448432011-03-24 21:19:54 +0000870 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000871
872 // Instance variables to hold the values for command options.
873 };
874
Greg Clayton238c0a12010-09-18 01:14:36 +0000875 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000876 CommandObjectParsed (interpreter,
877 "thread until",
878 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
879 NULL,
880 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
Greg Claytonf15996e2011-04-07 22:46:35 +0000881 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000882 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000883 CommandArgumentEntry arg;
884 CommandArgumentData line_num_arg;
885
886 // Define the first (and only) variant of this arg.
887 line_num_arg.arg_type = eArgTypeLineNum;
888 line_num_arg.arg_repetition = eArgRepeatPlain;
889
890 // There is only one variant this argument could be; put it into the argument entry.
891 arg.push_back (line_num_arg);
892
893 // Push the data for the first argument into the m_arguments vector.
894 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000895 }
896
897
898 virtual
899 ~CommandObjectThreadUntil ()
900 {
901 }
902
903 virtual
904 Options *
905 GetOptions ()
906 {
907 return &m_options;
908 }
909
Jim Inghamda26bd22012-06-08 21:56:10 +0000910protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000911 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000912 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000913 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000914 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000915
Greg Clayton238c0a12010-09-18 01:14:36 +0000916 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytoneea26402010-09-14 23:36:40 +0000917 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000918 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000919 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000920 result.SetStatus (eReturnStatusFailed);
921 return false;
922 }
923
Greg Clayton567e7f32011-09-22 04:58:26 +0000924 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000925 if (process == NULL)
926 {
927 result.AppendError ("need a valid process to step");
928 result.SetStatus (eReturnStatusFailed);
929
930 }
931 else
932 {
933 Thread *thread = NULL;
934 uint32_t line_number;
935
936 if (command.GetArgumentCount() != 1)
937 {
938 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
939 result.SetStatus (eReturnStatusFailed);
940 return false;
941 }
942
943 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
944 if (line_number == UINT32_MAX)
945 {
Greg Clayton9c236732011-10-26 00:56:27 +0000946 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +0000947 result.SetStatus (eReturnStatusFailed);
948 return false;
949 }
950
951 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
952 {
Jim Inghamc8332952010-08-26 21:32:51 +0000953 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000954 }
955 else
956 {
Greg Claytona2243772012-05-31 00:29:20 +0000957 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000958 }
959
960 if (thread == NULL)
961 {
962 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Inghamb07c62a2011-05-08 00:56:32 +0000963 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
964 m_options.m_thread_idx,
Jim Inghamb07c62a2011-05-08 00:56:32 +0000965 num_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000966 result.SetStatus (eReturnStatusFailed);
967 return false;
968 }
969
Jim Inghamd82bc6d2012-05-11 23:47:32 +0000970 const bool abort_other_plans = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000971
972 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
973 if (frame == NULL)
974 {
975
Jim Inghamb07c62a2011-05-08 00:56:32 +0000976 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
977 m_options.m_frame_idx,
978 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000979 result.SetStatus (eReturnStatusFailed);
980 return false;
981 }
982
Jim Ingham88e3de22012-05-03 21:19:36 +0000983 ThreadPlan *new_plan = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000984
985 if (frame->HasDebugInformation ())
986 {
987 // Finally we got here... Translate the given line number to a bunch of addresses:
988 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
989 LineTable *line_table = NULL;
990 if (sc.comp_unit)
991 line_table = sc.comp_unit->GetLineTable();
992
993 if (line_table == NULL)
994 {
995 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
996 m_options.m_frame_idx, m_options.m_thread_idx);
997 result.SetStatus (eReturnStatusFailed);
998 return false;
999 }
1000
1001 LineEntry function_start;
1002 uint32_t index_ptr = 0, end_ptr;
1003 std::vector<addr_t> address_list;
1004
1005 // Find the beginning & end index of the
1006 AddressRange fun_addr_range = sc.function->GetAddressRange();
1007 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1008 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1009
Jim Inghamb07c62a2011-05-08 00:56:32 +00001010 Address fun_end_addr(fun_start_addr.GetSection(),
1011 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00001012 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1013
Jim Inghamb07c62a2011-05-08 00:56:32 +00001014 bool all_in_function = true;
1015
Chris Lattner24943d22010-06-08 16:52:24 +00001016 while (index_ptr <= end_ptr)
1017 {
1018 LineEntry line_entry;
Jim Inghamd6d47972011-09-23 00:54:11 +00001019 const bool exact = false;
1020 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +00001021 if (index_ptr == UINT32_MAX)
1022 break;
1023
Greg Claytoneea26402010-09-14 23:36:40 +00001024 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner24943d22010-06-08 16:52:24 +00001025 if (address != LLDB_INVALID_ADDRESS)
Jim Inghamb07c62a2011-05-08 00:56:32 +00001026 {
1027 if (fun_addr_range.ContainsLoadAddress (address, target))
1028 address_list.push_back (address);
1029 else
1030 all_in_function = false;
1031 }
Chris Lattner24943d22010-06-08 16:52:24 +00001032 index_ptr++;
1033 }
1034
Jim Inghamb07c62a2011-05-08 00:56:32 +00001035 if (address_list.size() == 0)
1036 {
1037 if (all_in_function)
1038 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1039 else
1040 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1041
1042 result.SetStatus (eReturnStatusFailed);
1043 return false;
1044 }
1045
1046 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1047 &address_list.front(),
1048 address_list.size(),
1049 m_options.m_stop_others,
1050 thread->GetSelectedFrameIndex ());
Jim Ingham88e3de22012-05-03 21:19:36 +00001051 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1052 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1053 // will resume the original plan.
1054 new_plan->SetIsMasterPlan (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001055 new_plan->SetOkayToDiscard(false);
1056 }
1057 else
1058 {
Jim Inghamb07c62a2011-05-08 00:56:32 +00001059 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1060 m_options.m_frame_idx,
1061 m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001062 result.SetStatus (eReturnStatusFailed);
1063 return false;
1064
1065 }
1066
Jim Inghamc8332952010-08-26 21:32:51 +00001067 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001068 Error error (process->Resume ());
1069 if (error.Success())
1070 {
Greg Clayton444e35b2011-10-19 18:09:39 +00001071 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00001072 if (synchronous_execution)
1073 {
1074 StateType state = process->WaitForProcessToStop (NULL);
1075
1076 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +00001077 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +00001078 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1079 }
1080 else
1081 {
1082 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1083 }
1084 }
1085 else
1086 {
1087 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1088 result.SetStatus (eReturnStatusFailed);
1089 }
1090
1091 }
1092 return result.Succeeded();
1093 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001094
Chris Lattner24943d22010-06-08 16:52:24 +00001095 CommandOptions m_options;
1096
1097};
1098
Greg Claytonb3448432011-03-24 21:19:54 +00001099OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001100CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1101{
Caroline Tice43b014a2010-10-04 22:28:36 +00001102{ 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 +00001103{ LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1104{ 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"},
1105{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001106};
1107
1108
1109//-------------------------------------------------------------------------
1110// CommandObjectThreadSelect
1111//-------------------------------------------------------------------------
1112
Jim Inghamda26bd22012-06-08 21:56:10 +00001113class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001114{
1115public:
1116
Greg Clayton238c0a12010-09-18 01:14:36 +00001117 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001118 CommandObjectParsed (interpreter,
1119 "thread select",
1120 "Select a thread as the currently active thread.",
1121 NULL,
1122 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001123 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001124 CommandArgumentEntry arg;
1125 CommandArgumentData thread_idx_arg;
1126
1127 // Define the first (and only) variant of this arg.
1128 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1129 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1130
1131 // There is only one variant this argument could be; put it into the argument entry.
1132 arg.push_back (thread_idx_arg);
1133
1134 // Push the data for the first argument into the m_arguments vector.
1135 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001136 }
1137
1138
1139 virtual
1140 ~CommandObjectThreadSelect ()
1141 {
1142 }
1143
Jim Inghamda26bd22012-06-08 21:56:10 +00001144protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001145 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001146 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001147 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001148 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001149 if (process == NULL)
1150 {
1151 result.AppendError ("no process");
1152 result.SetStatus (eReturnStatusFailed);
1153 return false;
1154 }
1155 else if (command.GetArgumentCount() != 1)
1156 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001157 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 +00001158 result.SetStatus (eReturnStatusFailed);
1159 return false;
1160 }
1161
1162 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1163
1164 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1165 if (new_thread == NULL)
1166 {
Greg Clayton9c236732011-10-26 00:56:27 +00001167 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +00001168 result.SetStatus (eReturnStatusFailed);
1169 return false;
1170 }
1171
Jim Inghamc8332952010-08-26 21:32:51 +00001172 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
Johnny Chen8dbb6e82010-09-14 00:53:53 +00001173 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001174
Greg Claytonabe0fed2011-04-18 08:33:37 +00001175 const uint32_t start_frame = 0;
1176 const uint32_t num_frames = 1;
1177 const uint32_t num_frames_with_source = 1;
1178 new_thread->GetStatus (result.GetOutputStream(),
1179 start_frame,
1180 num_frames,
1181 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001182
1183 return result.Succeeded();
1184 }
1185
1186};
1187
1188
1189//-------------------------------------------------------------------------
1190// CommandObjectThreadList
1191//-------------------------------------------------------------------------
1192
Jim Inghamda26bd22012-06-08 21:56:10 +00001193class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001194{
Greg Clayton63094e02010-06-23 01:19:29 +00001195public:
Chris Lattner24943d22010-06-08 16:52:24 +00001196
Chris Lattner24943d22010-06-08 16:52:24 +00001197
Greg Clayton238c0a12010-09-18 01:14:36 +00001198 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Inghamda26bd22012-06-08 21:56:10 +00001199 CommandObjectParsed (interpreter,
1200 "thread list",
1201 "Show a summary of all current threads in a process.",
1202 "thread list",
1203 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Chris Lattner24943d22010-06-08 16:52:24 +00001204 {
Greg Clayton63094e02010-06-23 01:19:29 +00001205 }
Chris Lattner24943d22010-06-08 16:52:24 +00001206
Greg Clayton63094e02010-06-23 01:19:29 +00001207 ~CommandObjectThreadList()
1208 {
1209 }
1210
Jim Inghamda26bd22012-06-08 21:56:10 +00001211protected:
Greg Clayton63094e02010-06-23 01:19:29 +00001212 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001213 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton63094e02010-06-23 01:19:29 +00001214 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001215 Stream &strm = result.GetOutputStream();
Greg Clayton63094e02010-06-23 01:19:29 +00001216 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001217 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001218 Process *process = exe_ctx.GetProcessPtr();
1219 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00001220 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001221 const bool only_threads_with_stop_reason = false;
1222 const uint32_t start_frame = 0;
1223 const uint32_t num_frames = 0;
1224 const uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +00001225 process->GetStatus(strm);
1226 process->GetThreadStatus (strm,
1227 only_threads_with_stop_reason,
1228 start_frame,
1229 num_frames,
1230 num_frames_with_source);
Chris Lattner24943d22010-06-08 16:52:24 +00001231 }
1232 else
1233 {
Greg Clayton63094e02010-06-23 01:19:29 +00001234 result.AppendError ("no current location or status available");
Chris Lattner24943d22010-06-08 16:52:24 +00001235 result.SetStatus (eReturnStatusFailed);
1236 }
Greg Clayton63094e02010-06-23 01:19:29 +00001237 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +00001238 }
Greg Clayton63094e02010-06-23 01:19:29 +00001239};
Chris Lattner24943d22010-06-08 16:52:24 +00001240
1241//-------------------------------------------------------------------------
1242// CommandObjectMultiwordThread
1243//-------------------------------------------------------------------------
1244
Greg Clayton63094e02010-06-23 01:19:29 +00001245CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001246 CommandObjectMultiword (interpreter,
1247 "thread",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001248 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner24943d22010-06-08 16:52:24 +00001249 "thread <subcommand> [<subcommand-options>]")
1250{
Greg Clayton238c0a12010-09-18 01:14:36 +00001251 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1252 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1253 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1254 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1255 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1256 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1257 interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +00001258 "thread step-in",
Greg Clayton238c0a12010-09-18 01:14:36 +00001259 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001260 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001261 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1262 eStepTypeInto,
1263 eStepScopeSource)));
Greg Clayton63094e02010-06-23 01:19:29 +00001264
Greg Clayton238c0a12010-09-18 01:14:36 +00001265 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1266 interpreter,
1267 "thread step-out",
Jim Ingham1586d972011-12-17 01:35:57 +00001268 "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 +00001269 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001270 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1271 eStepTypeOut,
1272 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001273
Greg Clayton238c0a12010-09-18 01:14:36 +00001274 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1275 interpreter,
1276 "thread step-over",
1277 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001278 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001279 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1280 eStepTypeOver,
1281 eStepScopeSource)));
Chris Lattner24943d22010-06-08 16:52:24 +00001282
Greg Clayton238c0a12010-09-18 01:14:36 +00001283 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1284 interpreter,
1285 "thread step-inst",
1286 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice43b014a2010-10-04 22:28:36 +00001287 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001288 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1289 eStepTypeTrace,
1290 eStepScopeInstruction)));
Greg Clayton63094e02010-06-23 01:19:29 +00001291
Greg Clayton238c0a12010-09-18 01:14:36 +00001292 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1293 interpreter,
1294 "thread step-inst-over",
1295 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001296 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +00001297 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1298 eStepTypeTraceOver,
1299 eStepScopeInstruction)));
Chris Lattner24943d22010-06-08 16:52:24 +00001300}
1301
1302CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1303{
1304}
1305
1306