blob: bace4e58b4ad63a8edd1b06ae8e60477ed728f40 [file] [log] [blame]
Chris Lattner30fdc8d2010-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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectThread.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Inghamcb640dd2012-09-14 02:14:15 +000018#include "lldb/lldb-private.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/State.h"
20#include "lldb/Core/SourceManager.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000021#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#include "lldb/Interpreter/Options.h"
25#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/LineTable.h"
28#include "lldb/Symbol/LineEntry.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Process.h"
30#include "lldb/Target/RegisterContext.h"
Jason Molenda750ea692013-11-12 07:02:07 +000031#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
34#include "lldb/Target/ThreadPlan.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Target/ThreadPlanStepInstruction.h"
36#include "lldb/Target/ThreadPlanStepOut.h"
37#include "lldb/Target/ThreadPlanStepRange.h"
38#include "lldb/Target/ThreadPlanStepInRange.h"
Greg Clayton1f746072012-08-29 21:13:06 +000039
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040
41using namespace lldb;
42using namespace lldb_private;
43
44
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045//-------------------------------------------------------------------------
46// CommandObjectThreadBacktrace
47//-------------------------------------------------------------------------
48
Jim Ingham2bdbfd52014-09-29 23:17:18 +000049class CommandObjectIterateOverThreads : public CommandObjectParsed
50{
51public:
52 CommandObjectIterateOverThreads (CommandInterpreter &interpreter,
53 const char *name,
54 const char *help,
55 const char *syntax,
56 uint32_t flags) :
57 CommandObjectParsed (interpreter, name, help, syntax, flags)
58 {
59 }
60
61 virtual ~CommandObjectIterateOverThreads() {}
62 virtual bool
63 DoExecute (Args& command, CommandReturnObject &result)
64 {
65 result.SetStatus (m_success_return);
66
67 if (command.GetArgumentCount() == 0)
68 {
69 Thread *thread = m_exe_ctx.GetThreadPtr();
70 if (!HandleOneThread (*thread, result))
71 return false;
72 }
73 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
74 {
75 Process *process = m_exe_ctx.GetProcessPtr();
76 uint32_t idx = 0;
77 for (ThreadSP thread_sp : process->Threads())
78 {
79 if (idx != 0 && m_add_return)
80 result.AppendMessage("");
81
82 if (!HandleOneThread(*(thread_sp.get()), result))
83 return false;
84 ++idx;
85 }
86 }
87 else
88 {
89 const size_t num_args = command.GetArgumentCount();
90 Process *process = m_exe_ctx.GetProcessPtr();
91 Mutex::Locker locker (process->GetThreadList().GetMutex());
92 std::vector<ThreadSP> thread_sps;
93
94 for (size_t i = 0; i < num_args; i++)
95 {
96 bool success;
97
98 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
99 if (!success)
100 {
101 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
102 result.SetStatus (eReturnStatusFailed);
103 return false;
104 }
105
106 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
107
108 if (!thread_sps[i])
109 {
110 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
111 result.SetStatus (eReturnStatusFailed);
112 return false;
113 }
114
115 }
116
117 for (uint32_t i = 0; i < num_args; i++)
118 {
119 if (!HandleOneThread (*(thread_sps[i].get()), result))
120 return false;
121
122 if (i < num_args - 1 && m_add_return)
123 result.AppendMessage("");
124 }
125 }
126 return result.Succeeded();
127 }
128
129protected:
130
131 // Override this to do whatever you need to do for one thread.
132 //
133 // If you return false, the iteration will stop, otherwise it will proceed.
134 // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
135 // so you only need to set the return status in HandleOneThread if you want to indicate an error.
136 // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
137
138 virtual bool
139 HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
140
141 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
142 bool m_add_return = true;
143
144};
145
146//-------------------------------------------------------------------------
147// CommandObjectThreadBacktrace
148//-------------------------------------------------------------------------
149
150class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151{
152public:
153
Jim Inghame2e0b452010-08-26 23:36:03 +0000154 class CommandOptions : public Options
155 {
156 public:
157
Greg Claytoneb0103f2011-04-07 22:46:35 +0000158 CommandOptions (CommandInterpreter &interpreter) :
159 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +0000160 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000161 // Keep default values of all options in one place: OptionParsingStarting ()
162 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +0000163 }
164
165 virtual
166 ~CommandOptions ()
167 {
168 }
169
170 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000171 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame2e0b452010-08-26 23:36:03 +0000172 {
173 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000174 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame2e0b452010-08-26 23:36:03 +0000175
176 switch (short_option)
177 {
178 case 'c':
179 {
180 bool success;
181 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
182 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000183 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000184 if (input_count < -1)
185 m_count = UINT32_MAX;
186 else
187 m_count = input_count;
188 }
189 break;
190 case 's':
191 {
192 bool success;
193 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
194 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000195 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000196 }
Jason Molenda750ea692013-11-12 07:02:07 +0000197 case 'e':
198 {
199 bool success;
200 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
201 if (!success)
202 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
203 }
Jim Inghame2e0b452010-08-26 23:36:03 +0000204 break;
205 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000206 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000207 break;
208
209 }
210 return error;
211 }
212
213 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000214 OptionParsingStarting ()
Jim Inghame2e0b452010-08-26 23:36:03 +0000215 {
Greg Clayton7260f622011-04-18 08:33:37 +0000216 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000217 m_start = 0;
Jason Molenda750ea692013-11-12 07:02:07 +0000218 m_extended_backtrace = false;
Jim Inghame2e0b452010-08-26 23:36:03 +0000219 }
220
Greg Claytone0d378b2011-03-24 21:19:54 +0000221 const OptionDefinition*
Jim Inghame2e0b452010-08-26 23:36:03 +0000222 GetDefinitions ()
223 {
224 return g_option_table;
225 }
226
227 // Options table: Required for subclasses of Options.
228
Greg Claytone0d378b2011-03-24 21:19:54 +0000229 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000230
231 // Instance variables to hold the values for command options.
232 uint32_t m_count;
233 uint32_t m_start;
Jason Molenda750ea692013-11-12 07:02:07 +0000234 bool m_extended_backtrace;
Jim Inghame2e0b452010-08-26 23:36:03 +0000235 };
236
Greg Claytona7015092010-09-18 01:14:36 +0000237 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000238 CommandObjectIterateOverThreads (interpreter,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000239 "thread backtrace",
240 "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.",
241 NULL,
242 eFlagRequiresProcess |
243 eFlagRequiresThread |
244 eFlagTryTargetAPILock |
245 eFlagProcessMustBeLaunched |
246 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000247 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248 {
249 }
250
251 ~CommandObjectThreadBacktrace()
252 {
253 }
254
Jim Inghame2e0b452010-08-26 23:36:03 +0000255 virtual Options *
256 GetOptions ()
257 {
258 return &m_options;
259 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260
Jim Ingham5a988412012-06-08 21:56:10 +0000261protected:
Jason Molenda750ea692013-11-12 07:02:07 +0000262 void
263 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
264 {
265 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
266 if (runtime)
267 {
268 Stream &strm = result.GetOutputStream();
269 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
270 for (auto type : types)
271 {
Jason Molenda008c45f2013-11-12 23:33:32 +0000272 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
Jason Molenda750ea692013-11-12 07:02:07 +0000273 if (ext_thread_sp && ext_thread_sp->IsValid ())
274 {
275 const uint32_t num_frames_with_source = 0;
276 if (ext_thread_sp->GetStatus (strm,
277 m_options.m_start,
278 m_options.m_count,
279 num_frames_with_source))
280 {
281 DoExtendedBacktrace (ext_thread_sp.get(), result);
282 }
283 }
284 }
285 }
286 }
287
Greg Clayton66111032010-06-23 01:19:29 +0000288 virtual bool
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000289 HandleOneThread (Thread &thread, CommandReturnObject &result)
290 {
Greg Clayton7260f622011-04-18 08:33:37 +0000291 Stream &strm = result.GetOutputStream();
292
293 // Don't show source context when doing backtraces.
294 const uint32_t num_frames_with_source = 0;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000295
296 if (!thread.GetStatus (strm,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000297 m_options.m_start,
298 m_options.m_count,
299 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000300 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000301 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID());
302 result.SetStatus (eReturnStatusFailed);
303 return false;
Jim Ingham09b263e2010-08-27 00:58:05 +0000304 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000305 if (m_options.m_extended_backtrace)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000307 DoExtendedBacktrace (&thread, result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000309
310 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311 }
Jim Ingham5a988412012-06-08 21:56:10 +0000312
Jim Inghame2e0b452010-08-26 23:36:03 +0000313 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314};
315
Greg Claytone0d378b2011-03-24 21:19:54 +0000316OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000317CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
318{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000319{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
320{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
321{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
322{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghame2e0b452010-08-26 23:36:03 +0000323};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000324
Greg Clayton69b518f2010-07-07 17:07:17 +0000325enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326{
327 eStepScopeSource,
328 eStepScopeInstruction
329};
330
Jim Ingham5a988412012-06-08 21:56:10 +0000331class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332{
333public:
334
335 class CommandOptions : public Options
336 {
337 public:
338
Greg Claytoneb0103f2011-04-07 22:46:35 +0000339 CommandOptions (CommandInterpreter &interpreter) :
340 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000342 // Keep default values of all options in one place: OptionParsingStarting ()
343 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 }
345
346 virtual
347 ~CommandOptions ()
348 {
349 }
350
351 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000352 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 {
354 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000355 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356
357 switch (short_option)
358 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000359 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360 {
361 bool success;
Jim Ingham4b4b2472014-03-13 02:47:14 +0000362 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000364 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000365 else
366 {
367 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
368 }
369 }
370 break;
371
372 case 'A':
373 {
374 bool success;
375 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
376 if (!success)
377 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
378 else
379 {
380 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
381 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 }
383 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000384
Jim Ingham7a88ec92014-07-08 19:28:57 +0000385 case 'c':
386 {
387 m_step_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
388 if (m_step_count == UINT32_MAX)
389 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
390 break;
391 }
392 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000393 case 'C':
394 {
395 m_class_name.clear();
396 m_class_name.assign(option_arg);
397 }
398 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000399 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000402 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 }
404 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000405
406 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000407 {
408 m_avoid_regexp.clear();
409 m_avoid_regexp.assign(option_arg);
410 }
411 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000412
Jim Inghamc6276822012-12-12 19:58:40 +0000413 case 't':
414 {
415 m_step_in_target.clear();
416 m_step_in_target.assign(option_arg);
417
418 }
419 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000420 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000421 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000422 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423
424 }
425 return error;
426 }
427
428 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000429 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000431 m_step_in_avoid_no_debug = eLazyBoolCalculate;
432 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433 m_run_mode = eOnlyDuringStepping;
Jim Inghama56c8002010-07-10 02:27:39 +0000434 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000435 m_step_in_target.clear();
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000436 m_class_name.clear();
Jim Ingham7a88ec92014-07-08 19:28:57 +0000437 m_step_count = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 }
439
Greg Claytone0d378b2011-03-24 21:19:54 +0000440 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441 GetDefinitions ()
442 {
443 return g_option_table;
444 }
445
446 // Options table: Required for subclasses of Options.
447
Greg Claytone0d378b2011-03-24 21:19:54 +0000448 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449
450 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000451 LazyBool m_step_in_avoid_no_debug;
452 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000454 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000455 std::string m_step_in_target;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000456 std::string m_class_name;
Zachary Turner898e10e2015-01-09 20:15:21 +0000457 uint32_t m_step_count;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458 };
459
Greg Claytona7015092010-09-18 01:14:36 +0000460 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
461 const char *name,
462 const char *help,
463 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000464 StepType step_type,
465 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000466 CommandObjectParsed (interpreter, name, help, syntax,
467 eFlagRequiresProcess |
468 eFlagRequiresThread |
469 eFlagTryTargetAPILock |
470 eFlagProcessMustBeLaunched |
471 eFlagProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 m_step_type (step_type),
473 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000474 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 {
Caroline Tice405fe672010-10-04 22:28:36 +0000476 CommandArgumentEntry arg;
477 CommandArgumentData thread_id_arg;
478
479 // Define the first (and only) variant of this arg.
480 thread_id_arg.arg_type = eArgTypeThreadID;
481 thread_id_arg.arg_repetition = eArgRepeatOptional;
482
483 // There is only one variant this argument could be; put it into the argument entry.
484 arg.push_back (thread_id_arg);
485
486 // Push the data for the first argument into the m_arguments vector.
487 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488 }
489
490 virtual
491 ~CommandObjectThreadStepWithTypeAndScope ()
492 {
493 }
494
495 virtual
496 Options *
497 GetOptions ()
498 {
499 return &m_options;
500 }
501
Jim Ingham5a988412012-06-08 21:56:10 +0000502protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000503 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000504 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000506 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000507 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508
Greg Claytonf9fc6092013-01-09 19:44:40 +0000509 const uint32_t num_threads = process->GetThreadList().GetSize();
510 Thread *thread = NULL;
511
512 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000514 thread = process->GetThreadList().GetSelectedThread().get();
515 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000517 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000519 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000521 }
522 else
523 {
524 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
525 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
526 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000527 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000528 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
529 result.SetStatus (eReturnStatusFailed);
530 return false;
531 }
532 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
533 if (thread == NULL)
534 {
535 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
536 step_thread_idx, num_threads);
537 result.SetStatus (eReturnStatusFailed);
538 return false;
539 }
540 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000541
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000542 if (m_step_type == eStepTypeScripted)
543 {
544 if (m_options.m_class_name.empty())
545 {
546 result.AppendErrorWithFormat ("empty class name for scripted step.");
547 result.SetStatus(eReturnStatusFailed);
548 return false;
549 }
550 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
551 {
552 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
553 result.SetStatus(eReturnStatusFailed);
554 return false;
555 }
556 }
557
Greg Claytonf9fc6092013-01-09 19:44:40 +0000558 const bool abort_other_plans = false;
559 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
560
561 // This is a bit unfortunate, but not all the commands in this command object support
562 // only while stepping, so I use the bool for them.
563 bool bool_stop_other_threads;
564 if (m_options.m_run_mode == eAllThreads)
565 bool_stop_other_threads = false;
566 else if (m_options.m_run_mode == eOnlyDuringStepping)
567 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000568 if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000569 bool_stop_other_threads = false;
570 else
571 bool_stop_other_threads = true;
572 }
573 else
574 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000575
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000576 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000577
578 if (m_step_type == eStepTypeInto)
579 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000580 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000581
582 if (frame->HasDebugInformation ())
583 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000584 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000585 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
586 frame->GetSymbolContext(eSymbolContextEverything),
587 m_options.m_step_in_target.c_str(),
588 stop_other_threads,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000589 m_options.m_step_in_avoid_no_debug,
590 m_options.m_step_out_avoid_no_debug);
591
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000592 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000593 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000594 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000595 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000596 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000597 }
598 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000599 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000600
601 }
602 else if (m_step_type == eStepTypeOver)
603 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000604 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000605
606 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000607 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000608 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
609 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000610 stop_other_threads,
611 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000612 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000613 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000614 abort_other_plans,
615 bool_stop_other_threads);
616
617 }
618 else if (m_step_type == eStepTypeTrace)
619 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000620 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000621 }
622 else if (m_step_type == eStepTypeTraceOver)
623 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000624 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000625 }
626 else if (m_step_type == eStepTypeOut)
627 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000628 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000629 NULL,
630 false,
631 bool_stop_other_threads,
632 eVoteYes,
633 eVoteNoOpinion,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000634 thread->GetSelectedFrameIndex(),
635 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000636 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000637 else if (m_step_type == eStepTypeScripted)
638 {
639 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
640 m_options.m_class_name.c_str(),
641 bool_stop_other_threads);
642 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000643 else
644 {
645 result.AppendError ("step type is not supported");
646 result.SetStatus (eReturnStatusFailed);
647 return false;
648 }
649
650 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
651 // so that they can be interruptible). Then resume the process.
652
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000653 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000654 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000655 new_plan_sp->SetIsMasterPlan (true);
656 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000657
658 if (m_options.m_step_count > 1)
659 {
Zachary Turner40411162014-07-16 20:28:24 +0000660 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
Jim Ingham7a88ec92014-07-08 19:28:57 +0000661 {
662 result.AppendWarning ("step operation does not support iteration count.");
663 }
664 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000665
Greg Claytondc6224e2014-10-21 01:00:42 +0000666
Greg Claytonf9fc6092013-01-09 19:44:40 +0000667 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000668
669 StreamString stream;
670 Error error;
671 if (synchronous_execution)
672 error = process->ResumeSynchronous (&stream);
673 else
674 error = process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000675
676 // There is a race condition where this thread will return up the call stack to the main command handler
677 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
678 // a chance to call PushProcessIOHandler().
679 process->SyncIOHandler(2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000680
681 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000682 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000683 // If any state changed events had anything to say, add that to the result
684 if (stream.GetData())
685 result.AppendMessage(stream.GetData());
686
Greg Claytonf9fc6092013-01-09 19:44:40 +0000687 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
688 result.SetDidChangeProcessState (true);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000689 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000690 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000691 else
692 {
693 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
694 }
695 }
696 else
697 {
698 result.AppendError ("Couldn't find thread plan to implement step type.");
699 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700 }
701 return result.Succeeded();
702 }
703
704protected:
705 StepType m_step_type;
706 StepScope m_step_scope;
707 CommandOptions m_options;
708};
709
Greg Claytone0d378b2011-03-24 21:19:54 +0000710static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711g_tri_running_mode[] =
712{
Greg Claytoned8a7052010-09-18 03:37:20 +0000713{ eOnlyThisThread, "this-thread", "Run only this thread"},
714{ eAllThreads, "all-threads", "Run all threads"},
715{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716{ 0, NULL, NULL }
717};
718
Greg Claytone0d378b2011-03-24 21:19:54 +0000719static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720g_duo_running_mode[] =
721{
Greg Claytoned8a7052010-09-18 03:37:20 +0000722{ eOnlyThisThread, "this-thread", "Run only this thread"},
723{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724{ 0, NULL, NULL }
725};
726
Greg Claytone0d378b2011-03-24 21:19:54 +0000727OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000728CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
729{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000730{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
731{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000732{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
733{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
734{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
735{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
736{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
Zachary Turnerd37221d2014-07-09 16:31:49 +0000737{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000738};
739
740
741//-------------------------------------------------------------------------
742// CommandObjectThreadContinue
743//-------------------------------------------------------------------------
744
Jim Ingham5a988412012-06-08 21:56:10 +0000745class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000746{
747public:
748
Greg Claytona7015092010-09-18 01:14:36 +0000749 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000750 CommandObjectParsed (interpreter,
751 "thread continue",
752 "Continue execution of one or more threads in an active process.",
753 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000754 eFlagRequiresThread |
755 eFlagTryTargetAPILock |
756 eFlagProcessMustBeLaunched |
757 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758 {
Caroline Tice405fe672010-10-04 22:28:36 +0000759 CommandArgumentEntry arg;
760 CommandArgumentData thread_idx_arg;
761
762 // Define the first (and only) variant of this arg.
763 thread_idx_arg.arg_type = eArgTypeThreadIndex;
764 thread_idx_arg.arg_repetition = eArgRepeatPlus;
765
766 // There is only one variant this argument could be; put it into the argument entry.
767 arg.push_back (thread_idx_arg);
768
769 // Push the data for the first argument into the m_arguments vector.
770 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771 }
772
773
774 virtual
775 ~CommandObjectThreadContinue ()
776 {
777 }
778
779 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000780 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000781 {
Greg Claytona7015092010-09-18 01:14:36 +0000782 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783
Greg Claytona7015092010-09-18 01:14:36 +0000784 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000786 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787 result.SetStatus (eReturnStatusFailed);
788 return false;
789 }
790
Greg Claytonf9fc6092013-01-09 19:44:40 +0000791 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000792 if (process == NULL)
793 {
794 result.AppendError ("no process exists. Cannot continue");
795 result.SetStatus (eReturnStatusFailed);
796 return false;
797 }
798
799 StateType state = process->GetState();
800 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
801 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000802 const size_t argc = command.GetArgumentCount();
803 if (argc > 0)
804 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000805 // These two lines appear at the beginning of both blocks in
806 // this if..else, but that is because we need to release the
807 // lock before calling process->Resume below.
808 Mutex::Locker locker (process->GetThreadList().GetMutex());
809 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000810 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000811 for (uint32_t i=0; i<argc; ++i)
812 {
Jim Inghamce76c622012-05-31 20:48:41 +0000813 bool success;
814 const int base = 0;
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000815 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
816 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000817 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000818 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000819
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000820 if (thread)
821 {
822 resume_threads.push_back(thread);
823 }
824 else
825 {
826 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
827 result.SetStatus (eReturnStatusFailed);
828 return false;
829 }
Jim Inghamce76c622012-05-31 20:48:41 +0000830 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000831 else
Jim Inghamce76c622012-05-31 20:48:41 +0000832 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000833 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000834 result.SetStatus (eReturnStatusFailed);
835 return false;
836 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000838
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000839 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840 {
841 result.AppendError ("no valid thread indexes were specified");
842 result.SetStatus (eReturnStatusFailed);
843 return false;
844 }
845 else
846 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000847 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000848 result.AppendMessageWithFormat ("Resuming thread: ");
849 else
850 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000851
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000852 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000854 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
855 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000856
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000857 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000858 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000859 resume_threads.erase(this_thread_pos);
860 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000861 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
862 else
863 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000864
865 const bool override_suspend = true;
866 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867 }
868 else
869 {
870 thread->SetResumeState (eStateSuspended);
871 }
872 }
Daniel Malead01b2952012-11-29 21:49:15 +0000873 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 }
875 }
876 else
877 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000878 // These two lines appear at the beginning of both blocks in
879 // this if..else, but that is because we need to release the
880 // lock before calling process->Resume below.
881 Mutex::Locker locker (process->GetThreadList().GetMutex());
882 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000883 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000884 if (current_thread == NULL)
885 {
886 result.AppendError ("the process doesn't have a current thread");
887 result.SetStatus (eReturnStatusFailed);
888 return false;
889 }
890 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000891 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000893 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000894 if (thread == current_thread)
895 {
Daniel Malead01b2952012-11-29 21:49:15 +0000896 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000897 const bool override_suspend = true;
898 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000899 }
900 else
901 {
902 thread->SetResumeState (eStateSuspended);
903 }
904 }
905 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000906
Greg Claytondc6224e2014-10-21 01:00:42 +0000907
908 StreamString stream;
909 Error error;
910 if (synchronous_execution)
911 error = process->ResumeSynchronous (&stream);
912 else
913 error = process->Resume ();
914
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000915 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916 if (error.Success())
917 {
Daniel Malead01b2952012-11-29 21:49:15 +0000918 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000919 if (synchronous_execution)
920 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000921 // If any state changed events had anything to say, add that to the result
922 if (stream.GetData())
923 result.AppendMessage(stream.GetData());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000924
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000926 result.SetStatus (eReturnStatusSuccessFinishNoResult);
927 }
928 else
929 {
930 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
931 }
932 }
933 else
934 {
935 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
936 result.SetStatus (eReturnStatusFailed);
937 }
938 }
939 else
940 {
941 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
942 StateAsCString(state));
943 result.SetStatus (eReturnStatusFailed);
944 }
945
946 return result.Succeeded();
947 }
948
949};
950
951//-------------------------------------------------------------------------
952// CommandObjectThreadUntil
953//-------------------------------------------------------------------------
954
Jim Ingham5a988412012-06-08 21:56:10 +0000955class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956{
957public:
958
959 class CommandOptions : public Options
960 {
961 public:
962 uint32_t m_thread_idx;
963 uint32_t m_frame_idx;
964
Greg Claytoneb0103f2011-04-07 22:46:35 +0000965 CommandOptions (CommandInterpreter &interpreter) :
966 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000967 m_thread_idx(LLDB_INVALID_THREAD_ID),
968 m_frame_idx(LLDB_INVALID_FRAME_ID)
969 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000970 // Keep default values of all options in one place: OptionParsingStarting ()
971 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972 }
973
974 virtual
975 ~CommandOptions ()
976 {
977 }
978
979 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000980 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981 {
982 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000983 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984
985 switch (short_option)
986 {
987 case 't':
988 {
Greg Claytonb1320972010-07-14 00:18:15 +0000989 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990 if (m_thread_idx == LLDB_INVALID_INDEX32)
991 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000992 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993 }
994 }
995 break;
996 case 'f':
997 {
998 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
999 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1000 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001001 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002 }
1003 }
1004 break;
1005 case 'm':
1006 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001008 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001010 if (error.Success())
1011 {
1012 if (run_mode == eAllThreads)
1013 m_stop_others = false;
1014 else
1015 m_stop_others = true;
1016 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 }
1018 break;
1019 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001020 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001021 break;
1022
1023 }
1024 return error;
1025 }
1026
1027 void
Greg Claytonf6b8b582011-04-13 00:18:08 +00001028 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030 m_thread_idx = LLDB_INVALID_THREAD_ID;
1031 m_frame_idx = 0;
1032 m_stop_others = false;
1033 }
1034
Greg Claytone0d378b2011-03-24 21:19:54 +00001035 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036 GetDefinitions ()
1037 {
1038 return g_option_table;
1039 }
1040
1041 uint32_t m_step_thread_idx;
1042 bool m_stop_others;
1043
1044 // Options table: Required for subclasses of Options.
1045
Greg Claytone0d378b2011-03-24 21:19:54 +00001046 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047
1048 // Instance variables to hold the values for command options.
1049 };
1050
Greg Claytona7015092010-09-18 01:14:36 +00001051 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001052 CommandObjectParsed (interpreter,
1053 "thread until",
1054 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
1055 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001056 eFlagRequiresThread |
1057 eFlagTryTargetAPILock |
1058 eFlagProcessMustBeLaunched |
1059 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001060 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061 {
Caroline Tice405fe672010-10-04 22:28:36 +00001062 CommandArgumentEntry arg;
1063 CommandArgumentData line_num_arg;
1064
1065 // Define the first (and only) variant of this arg.
1066 line_num_arg.arg_type = eArgTypeLineNum;
1067 line_num_arg.arg_repetition = eArgRepeatPlain;
1068
1069 // There is only one variant this argument could be; put it into the argument entry.
1070 arg.push_back (line_num_arg);
1071
1072 // Push the data for the first argument into the m_arguments vector.
1073 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 }
1075
1076
1077 virtual
1078 ~CommandObjectThreadUntil ()
1079 {
1080 }
1081
1082 virtual
1083 Options *
1084 GetOptions ()
1085 {
1086 return &m_options;
1087 }
1088
Jim Ingham5a988412012-06-08 21:56:10 +00001089protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001091 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001092 {
Greg Claytona7015092010-09-18 01:14:36 +00001093 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094
Greg Claytona7015092010-09-18 01:14:36 +00001095 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +00001096 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001098 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 result.SetStatus (eReturnStatusFailed);
1100 return false;
1101 }
1102
Greg Claytonf9fc6092013-01-09 19:44:40 +00001103 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 if (process == NULL)
1105 {
1106 result.AppendError ("need a valid process to step");
1107 result.SetStatus (eReturnStatusFailed);
1108
1109 }
1110 else
1111 {
1112 Thread *thread = NULL;
1113 uint32_t line_number;
1114
1115 if (command.GetArgumentCount() != 1)
1116 {
1117 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1118 result.SetStatus (eReturnStatusFailed);
1119 return false;
1120 }
1121
1122 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1123 if (line_number == UINT32_MAX)
1124 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001125 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126 result.SetStatus (eReturnStatusFailed);
1127 return false;
1128 }
1129
1130 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1131 {
Jim Ingham2976d002010-08-26 21:32:51 +00001132 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 }
1134 else
1135 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001136 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001137 }
1138
1139 if (thread == NULL)
1140 {
1141 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001142 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1143 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001144 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145 result.SetStatus (eReturnStatusFailed);
1146 return false;
1147 }
1148
Jim Ingham7ba6e992012-05-11 23:47:32 +00001149 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150
Jason Molendab57e4a12013-11-04 09:33:30 +00001151 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152 if (frame == NULL)
1153 {
1154
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001155 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1156 m_options.m_frame_idx,
1157 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001158 result.SetStatus (eReturnStatusFailed);
1159 return false;
1160 }
1161
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001162 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163
1164 if (frame->HasDebugInformation ())
1165 {
1166 // Finally we got here... Translate the given line number to a bunch of addresses:
1167 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1168 LineTable *line_table = NULL;
1169 if (sc.comp_unit)
1170 line_table = sc.comp_unit->GetLineTable();
1171
1172 if (line_table == NULL)
1173 {
1174 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1175 m_options.m_frame_idx, m_options.m_thread_idx);
1176 result.SetStatus (eReturnStatusFailed);
1177 return false;
1178 }
1179
1180 LineEntry function_start;
1181 uint32_t index_ptr = 0, end_ptr;
1182 std::vector<addr_t> address_list;
1183
1184 // Find the beginning & end index of the
1185 AddressRange fun_addr_range = sc.function->GetAddressRange();
1186 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1187 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1188
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001189 Address fun_end_addr(fun_start_addr.GetSection(),
1190 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1192
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001193 bool all_in_function = true;
1194
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001195 while (index_ptr <= end_ptr)
1196 {
1197 LineEntry line_entry;
Jim Ingham87df91b2011-09-23 00:54:11 +00001198 const bool exact = false;
1199 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200 if (index_ptr == UINT32_MAX)
1201 break;
1202
Greg Claytonf5e56de2010-09-14 23:36:40 +00001203 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001204 if (address != LLDB_INVALID_ADDRESS)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001205 {
1206 if (fun_addr_range.ContainsLoadAddress (address, target))
1207 address_list.push_back (address);
1208 else
1209 all_in_function = false;
1210 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001211 index_ptr++;
1212 }
1213
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001214 if (address_list.size() == 0)
1215 {
1216 if (all_in_function)
1217 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1218 else
1219 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1220
1221 result.SetStatus (eReturnStatusFailed);
1222 return false;
1223 }
1224
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001225 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001226 &address_list.front(),
1227 address_list.size(),
1228 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001229 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001230 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1231 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1232 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001233 new_plan_sp->SetIsMasterPlan (true);
1234 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001235 }
1236 else
1237 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001238 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1239 m_options.m_frame_idx,
1240 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241 result.SetStatus (eReturnStatusFailed);
1242 return false;
1243
1244 }
1245
Greg Claytondc6224e2014-10-21 01:00:42 +00001246
1247
Jim Ingham2976d002010-08-26 21:32:51 +00001248 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Greg Claytondc6224e2014-10-21 01:00:42 +00001249
1250 StreamString stream;
1251 Error error;
1252 if (synchronous_execution)
1253 error = process->ResumeSynchronous (&stream);
1254 else
1255 error = process->Resume ();
1256
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257 if (error.Success())
1258 {
Daniel Malead01b2952012-11-29 21:49:15 +00001259 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001260 if (synchronous_execution)
1261 {
Greg Claytondc6224e2014-10-21 01:00:42 +00001262 // If any state changed events had anything to say, add that to the result
1263 if (stream.GetData())
1264 result.AppendMessage(stream.GetData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265
1266 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1268 }
1269 else
1270 {
1271 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1272 }
1273 }
1274 else
1275 {
1276 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1277 result.SetStatus (eReturnStatusFailed);
1278 }
1279
1280 }
1281 return result.Succeeded();
1282 }
Jim Ingham5a988412012-06-08 21:56:10 +00001283
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001284 CommandOptions m_options;
1285
1286};
1287
Greg Claytone0d378b2011-03-24 21:19:54 +00001288OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001289CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1290{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001291{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1292{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1293{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
1294{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295};
1296
1297
1298//-------------------------------------------------------------------------
1299// CommandObjectThreadSelect
1300//-------------------------------------------------------------------------
1301
Jim Ingham5a988412012-06-08 21:56:10 +00001302class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001303{
1304public:
1305
Greg Claytona7015092010-09-18 01:14:36 +00001306 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001307 CommandObjectParsed (interpreter,
1308 "thread select",
1309 "Select a thread as the currently active thread.",
1310 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001311 eFlagRequiresProcess |
1312 eFlagTryTargetAPILock |
1313 eFlagProcessMustBeLaunched |
1314 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001315 {
Caroline Tice405fe672010-10-04 22:28:36 +00001316 CommandArgumentEntry arg;
1317 CommandArgumentData thread_idx_arg;
1318
1319 // Define the first (and only) variant of this arg.
1320 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1321 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1322
1323 // There is only one variant this argument could be; put it into the argument entry.
1324 arg.push_back (thread_idx_arg);
1325
1326 // Push the data for the first argument into the m_arguments vector.
1327 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001328 }
1329
1330
1331 virtual
1332 ~CommandObjectThreadSelect ()
1333 {
1334 }
1335
Jim Ingham5a988412012-06-08 21:56:10 +00001336protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001337 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001338 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001340 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001341 if (process == NULL)
1342 {
1343 result.AppendError ("no process");
1344 result.SetStatus (eReturnStatusFailed);
1345 return false;
1346 }
1347 else if (command.GetArgumentCount() != 1)
1348 {
Jason Molendafd54b362011-09-20 21:44:10 +00001349 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350 result.SetStatus (eReturnStatusFailed);
1351 return false;
1352 }
1353
1354 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1355
1356 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1357 if (new_thread == NULL)
1358 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001359 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001360 result.SetStatus (eReturnStatusFailed);
1361 return false;
1362 }
1363
Jim Inghamc3faa192012-12-11 02:31:48 +00001364 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001365 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001366
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001367 return result.Succeeded();
1368 }
1369
1370};
1371
1372
1373//-------------------------------------------------------------------------
1374// CommandObjectThreadList
1375//-------------------------------------------------------------------------
1376
Jim Ingham5a988412012-06-08 21:56:10 +00001377class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001378{
Greg Clayton66111032010-06-23 01:19:29 +00001379public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001381
Greg Claytona7015092010-09-18 01:14:36 +00001382 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001383 CommandObjectParsed (interpreter,
1384 "thread list",
1385 "Show a summary of all current threads in a process.",
1386 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001387 eFlagRequiresProcess |
1388 eFlagTryTargetAPILock |
1389 eFlagProcessMustBeLaunched |
1390 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001391 {
Greg Clayton66111032010-06-23 01:19:29 +00001392 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001393
Greg Clayton66111032010-06-23 01:19:29 +00001394 ~CommandObjectThreadList()
1395 {
1396 }
1397
Jim Ingham5a988412012-06-08 21:56:10 +00001398protected:
Greg Clayton66111032010-06-23 01:19:29 +00001399 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001400 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001401 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001402 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001403 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001404 Process *process = m_exe_ctx.GetProcessPtr();
1405 const bool only_threads_with_stop_reason = false;
1406 const uint32_t start_frame = 0;
1407 const uint32_t num_frames = 0;
1408 const uint32_t num_frames_with_source = 0;
1409 process->GetStatus(strm);
1410 process->GetThreadStatus (strm,
1411 only_threads_with_stop_reason,
1412 start_frame,
1413 num_frames,
1414 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001415 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001416 }
Greg Clayton66111032010-06-23 01:19:29 +00001417};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001418
Jim Ingham93208b82013-01-31 21:46:01 +00001419//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001420// CommandObjectThreadInfo
1421//-------------------------------------------------------------------------
1422
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001423class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001424{
1425public:
1426
1427 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001428 CommandObjectIterateOverThreads (interpreter,
1429 "thread info",
1430 "Show an extended summary of information about thread(s) in a process.",
1431 "thread info",
1432 eFlagRequiresProcess |
1433 eFlagTryTargetAPILock |
1434 eFlagProcessMustBeLaunched |
1435 eFlagProcessMustBePaused),
Jason Molenda705b1802014-06-13 02:37:02 +00001436 m_options (interpreter)
1437 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001438 m_add_return = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001439 }
1440
1441 class CommandOptions : public Options
1442 {
1443 public:
1444
1445 CommandOptions (CommandInterpreter &interpreter) :
1446 Options (interpreter)
1447 {
1448 OptionParsingStarting ();
1449 }
1450
1451 void
1452 OptionParsingStarting ()
1453 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001454 m_json_thread = false;
1455 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001456 }
1457
1458 virtual
1459 ~CommandOptions ()
1460 {
1461 }
1462
1463 virtual Error
1464 SetOptionValue (uint32_t option_idx, const char *option_arg)
1465 {
1466 const int short_option = m_getopt_table[option_idx].val;
1467 Error error;
1468
1469 switch (short_option)
1470 {
1471 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001472 m_json_thread = true;
1473 break;
1474
1475 case 's':
1476 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001477 break;
1478
Kuba Breckaafdf8422014-10-10 23:43:03 +00001479 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001480 return Error("invalid short option character '%c'", short_option);
1481
1482 }
1483 return error;
1484 }
1485
1486 const OptionDefinition*
1487 GetDefinitions ()
1488 {
1489 return g_option_table;
1490 }
1491
Kuba Breckaafdf8422014-10-10 23:43:03 +00001492 bool m_json_thread;
1493 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001494
1495 static OptionDefinition g_option_table[];
1496 };
1497
1498 virtual
1499 Options *
1500 GetOptions ()
1501 {
1502 return &m_options;
1503 }
1504
1505
1506 virtual
1507 ~CommandObjectThreadInfo ()
1508 {
1509 }
1510
1511 virtual bool
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001512 HandleOneThread (Thread &thread, CommandReturnObject &result)
Jason Molenda705b1802014-06-13 02:37:02 +00001513 {
Jason Molenda705b1802014-06-13 02:37:02 +00001514 Stream &strm = result.GetOutputStream();
Kuba Breckaafdf8422014-10-10 23:43:03 +00001515 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
Jason Molenda705b1802014-06-13 02:37:02 +00001516 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001517 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1518 result.SetStatus (eReturnStatusFailed);
1519 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001520 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001521 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001522 }
1523
1524 CommandOptions m_options;
1525
1526};
1527
1528OptionDefinition
1529CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1530{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001531 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."},
Kuba Breckaafdf8422014-10-10 23:43:03 +00001532 { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
Jason Molenda705b1802014-06-13 02:37:02 +00001533
Zachary Turnerd37221d2014-07-09 16:31:49 +00001534 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jason Molenda705b1802014-06-13 02:37:02 +00001535};
1536
1537
1538//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001539// CommandObjectThreadReturn
1540//-------------------------------------------------------------------------
1541
Jim Inghamcb640dd2012-09-14 02:14:15 +00001542class CommandObjectThreadReturn : public CommandObjectRaw
1543{
1544public:
Jim Ingham93208b82013-01-31 21:46:01 +00001545 class CommandOptions : public Options
1546 {
1547 public:
1548
1549 CommandOptions (CommandInterpreter &interpreter) :
1550 Options (interpreter),
1551 m_from_expression (false)
1552 {
1553 // Keep default values of all options in one place: OptionParsingStarting ()
1554 OptionParsingStarting ();
1555 }
1556
1557 virtual
1558 ~CommandOptions ()
1559 {
1560 }
1561
1562 virtual Error
1563 SetOptionValue (uint32_t option_idx, const char *option_arg)
1564 {
1565 Error error;
1566 const int short_option = m_getopt_table[option_idx].val;
1567
1568 switch (short_option)
1569 {
1570 case 'x':
1571 {
1572 bool success;
1573 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1574 if (success)
1575 m_from_expression = tmp_value;
1576 else
1577 {
1578 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1579 }
1580 }
1581 break;
1582 default:
1583 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1584 break;
1585
1586 }
1587 return error;
1588 }
1589
1590 void
1591 OptionParsingStarting ()
1592 {
1593 m_from_expression = false;
1594 }
1595
1596 const OptionDefinition*
1597 GetDefinitions ()
1598 {
1599 return g_option_table;
1600 }
1601
1602 bool m_from_expression;
1603
1604 // Options table: Required for subclasses of Options.
1605
1606 static OptionDefinition g_option_table[];
1607
1608 // Instance variables to hold the values for command options.
1609 };
1610
1611 virtual
1612 Options *
1613 GetOptions ()
1614 {
1615 return &m_options;
1616 }
1617
Jim Inghamcb640dd2012-09-14 02:14:15 +00001618 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1619 CommandObjectRaw (interpreter,
1620 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001621 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1622 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001623 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001624 eFlagRequiresFrame |
1625 eFlagTryTargetAPILock |
1626 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001627 eFlagProcessMustBePaused ),
1628 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001629 {
1630 CommandArgumentEntry arg;
1631 CommandArgumentData expression_arg;
1632
1633 // Define the first (and only) variant of this arg.
1634 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001635 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001636
1637 // There is only one variant this argument could be; put it into the argument entry.
1638 arg.push_back (expression_arg);
1639
1640 // Push the data for the first argument into the m_arguments vector.
1641 m_arguments.push_back (arg);
1642
1643
1644 }
1645
1646 ~CommandObjectThreadReturn()
1647 {
1648 }
1649
1650protected:
1651
1652 bool DoExecute
1653 (
1654 const char *command,
1655 CommandReturnObject &result
1656 )
1657 {
Jim Ingham93208b82013-01-31 21:46:01 +00001658 // I am going to handle this by hand, because I don't want you to have to say:
1659 // "thread return -- -5".
1660 if (command[0] == '-' && command[1] == 'x')
1661 {
1662 if (command && command[2] != '\0')
1663 result.AppendWarning("Return values ignored when returning from user called expressions");
1664
1665 Thread *thread = m_exe_ctx.GetThreadPtr();
1666 Error error;
1667 error = thread->UnwindInnermostExpression();
1668 if (!error.Success())
1669 {
1670 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1671 result.SetStatus (eReturnStatusFailed);
1672 }
1673 else
1674 {
1675 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1676 if (success)
1677 {
1678 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1679 result.SetStatus (eReturnStatusSuccessFinishResult);
1680 }
1681 else
1682 {
1683 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1684 result.SetStatus (eReturnStatusFailed);
1685 }
1686 }
1687 return result.Succeeded();
1688 }
1689
Jim Inghamcb640dd2012-09-14 02:14:15 +00001690 ValueObjectSP return_valobj_sp;
1691
Jason Molendab57e4a12013-11-04 09:33:30 +00001692 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001693 uint32_t frame_idx = frame_sp->GetFrameIndex();
1694
1695 if (frame_sp->IsInlined())
1696 {
1697 result.AppendError("Don't know how to return from inlined frames.");
1698 result.SetStatus (eReturnStatusFailed);
1699 return false;
1700 }
1701
1702 if (command && command[0] != '\0')
1703 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001704 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001705 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001706
1707 options.SetUnwindOnError(true);
1708 options.SetUseDynamic(eNoDynamicValues);
1709
Jim Ingham8646d3c2014-05-05 02:47:44 +00001710 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001711 exe_results = target->EvaluateExpression (command,
1712 frame_sp.get(),
1713 return_valobj_sp,
1714 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001715 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001716 {
1717 if (return_valobj_sp)
1718 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1719 else
1720 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1721 result.SetStatus (eReturnStatusFailed);
1722 return false;
1723
1724 }
1725 }
1726
1727 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001728 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001729 const bool broadcast = true;
1730 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001731 if (!error.Success())
1732 {
1733 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1734 result.SetStatus (eReturnStatusFailed);
1735 return false;
1736 }
1737
Jim Inghamcb640dd2012-09-14 02:14:15 +00001738 result.SetStatus (eReturnStatusSuccessFinishResult);
1739 return true;
1740 }
Jim Ingham93208b82013-01-31 21:46:01 +00001741
1742 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001743
1744};
Jim Ingham93208b82013-01-31 21:46:01 +00001745OptionDefinition
1746CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1747{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001748{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1749{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham93208b82013-01-31 21:46:01 +00001750};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001751
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001752//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001753// CommandObjectThreadJump
1754//-------------------------------------------------------------------------
1755
1756class CommandObjectThreadJump : public CommandObjectParsed
1757{
1758public:
1759 class CommandOptions : public Options
1760 {
1761 public:
1762
1763 CommandOptions (CommandInterpreter &interpreter) :
1764 Options (interpreter)
1765 {
1766 OptionParsingStarting ();
1767 }
1768
1769 void
1770 OptionParsingStarting ()
1771 {
1772 m_filenames.Clear();
1773 m_line_num = 0;
1774 m_line_offset = 0;
1775 m_load_addr = LLDB_INVALID_ADDRESS;
1776 m_force = false;
1777 }
1778
1779 virtual
1780 ~CommandOptions ()
1781 {
1782 }
1783
1784 virtual Error
1785 SetOptionValue (uint32_t option_idx, const char *option_arg)
1786 {
1787 bool success;
1788 const int short_option = m_getopt_table[option_idx].val;
1789 Error error;
1790
1791 switch (short_option)
1792 {
1793 case 'f':
1794 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1795 if (m_filenames.GetSize() > 1)
1796 return Error("only one source file expected.");
1797 break;
1798 case 'l':
1799 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1800 if (!success || m_line_num == 0)
1801 return Error("invalid line number: '%s'.", option_arg);
1802 break;
1803 case 'b':
1804 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1805 if (!success)
1806 return Error("invalid line offset: '%s'.", option_arg);
1807 break;
1808 case 'a':
1809 {
1810 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1811 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1812 }
1813 break;
1814 case 'r':
1815 m_force = true;
1816 break;
1817
1818 default:
1819 return Error("invalid short option character '%c'", short_option);
1820
1821 }
1822 return error;
1823 }
1824
1825 const OptionDefinition*
1826 GetDefinitions ()
1827 {
1828 return g_option_table;
1829 }
1830
1831 FileSpecList m_filenames;
1832 uint32_t m_line_num;
1833 int32_t m_line_offset;
1834 lldb::addr_t m_load_addr;
1835 bool m_force;
1836
1837 static OptionDefinition g_option_table[];
1838 };
1839
1840 virtual
1841 Options *
1842 GetOptions ()
1843 {
1844 return &m_options;
1845 }
1846
1847 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1848 CommandObjectParsed (interpreter,
1849 "thread jump",
1850 "Sets the program counter to a new address.",
1851 "thread jump",
1852 eFlagRequiresFrame |
1853 eFlagTryTargetAPILock |
1854 eFlagProcessMustBeLaunched |
1855 eFlagProcessMustBePaused ),
1856 m_options (interpreter)
1857 {
1858 }
1859
1860 ~CommandObjectThreadJump()
1861 {
1862 }
1863
1864protected:
1865
1866 bool DoExecute (Args& args, CommandReturnObject &result)
1867 {
1868 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001869 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001870 Thread *thread = m_exe_ctx.GetThreadPtr();
1871 Target *target = m_exe_ctx.GetTargetPtr();
1872 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1873
1874 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1875 {
1876 // Use this address directly.
1877 Address dest = Address(m_options.m_load_addr);
1878
1879 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1880 if (callAddr == LLDB_INVALID_ADDRESS)
1881 {
1882 result.AppendErrorWithFormat ("Invalid destination address.");
1883 result.SetStatus (eReturnStatusFailed);
1884 return false;
1885 }
1886
1887 if (!reg_ctx->SetPC (callAddr))
1888 {
1889 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1890 result.SetStatus (eReturnStatusFailed);
1891 return false;
1892 }
1893 }
1894 else
1895 {
1896 // Pick either the absolute line, or work out a relative one.
1897 int32_t line = (int32_t)m_options.m_line_num;
1898 if (line == 0)
1899 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1900
1901 // Try the current file, but override if asked.
1902 FileSpec file = sym_ctx.line_entry.file;
1903 if (m_options.m_filenames.GetSize() == 1)
1904 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1905
1906 if (!file)
1907 {
1908 result.AppendErrorWithFormat ("No source file available for the current location.");
1909 result.SetStatus (eReturnStatusFailed);
1910 return false;
1911 }
1912
1913 std::string warnings;
1914 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1915
1916 if (err.Fail())
1917 {
1918 result.SetError (err);
1919 return false;
1920 }
1921
1922 if (!warnings.empty())
1923 result.AppendWarning (warnings.c_str());
1924 }
1925
1926 result.SetStatus (eReturnStatusSuccessFinishResult);
1927 return true;
1928 }
1929
1930 CommandOptions m_options;
1931};
1932OptionDefinition
1933CommandObjectThreadJump::CommandOptions::g_option_table[] =
1934{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001935 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001936 "Specifies the source file to jump to."},
1937
Zachary Turnerd37221d2014-07-09 16:31:49 +00001938 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001939 "Specifies the line number to jump to."},
1940
Zachary Turnerd37221d2014-07-09 16:31:49 +00001941 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001942 "Jumps by a relative line offset from the current line."},
1943
Zachary Turnerd37221d2014-07-09 16:31:49 +00001944 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001945 "Jumps to a specific address."},
1946
1947 { LLDB_OPT_SET_1|
1948 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +00001949 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
Richard Mittonf86248d2013-09-12 02:20:34 +00001950
Zachary Turnerd37221d2014-07-09 16:31:49 +00001951 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Richard Mittonf86248d2013-09-12 02:20:34 +00001952};
1953
1954//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001955// Next are the subcommands of CommandObjectMultiwordThreadPlan
1956//-------------------------------------------------------------------------
1957
1958
1959//-------------------------------------------------------------------------
1960// CommandObjectThreadPlanList
1961//-------------------------------------------------------------------------
1962class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1963{
1964public:
1965
1966 class CommandOptions : public Options
1967 {
1968 public:
1969
1970 CommandOptions (CommandInterpreter &interpreter) :
1971 Options(interpreter)
1972 {
1973 // Keep default values of all options in one place: OptionParsingStarting ()
1974 OptionParsingStarting ();
1975 }
1976
1977 virtual
1978 ~CommandOptions ()
1979 {
1980 }
1981
1982 virtual Error
1983 SetOptionValue (uint32_t option_idx, const char *option_arg)
1984 {
1985 Error error;
1986 const int short_option = m_getopt_table[option_idx].val;
1987
1988 switch (short_option)
1989 {
1990 case 'i':
1991 {
1992 m_internal = true;
1993 }
1994 break;
1995 case 'v':
1996 {
1997 m_verbose = true;
1998 }
1999 break;
2000 default:
2001 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2002 break;
2003
2004 }
2005 return error;
2006 }
2007
2008 void
2009 OptionParsingStarting ()
2010 {
2011 m_verbose = false;
2012 m_internal = false;
2013 }
2014
2015 const OptionDefinition*
2016 GetDefinitions ()
2017 {
2018 return g_option_table;
2019 }
2020
2021 // Options table: Required for subclasses of Options.
2022
2023 static OptionDefinition g_option_table[];
2024
2025 // Instance variables to hold the values for command options.
2026 bool m_verbose;
2027 bool m_internal;
2028 };
2029
2030 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
2031 CommandObjectIterateOverThreads (interpreter,
2032 "thread plan list",
2033 "Show thread plans for one or more threads. If no threads are specified, show the "
2034 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2035 NULL,
2036 eFlagRequiresProcess |
2037 eFlagRequiresThread |
2038 eFlagTryTargetAPILock |
2039 eFlagProcessMustBeLaunched |
2040 eFlagProcessMustBePaused ),
2041 m_options(interpreter)
2042 {
2043 }
2044
2045 ~CommandObjectThreadPlanList ()
2046 {
2047 }
2048
2049 virtual Options *
2050 GetOptions ()
2051 {
2052 return &m_options;
2053 }
2054
2055protected:
2056 virtual bool
2057 HandleOneThread (Thread &thread, CommandReturnObject &result)
2058 {
2059 Stream &strm = result.GetOutputStream();
2060 DescriptionLevel desc_level = eDescriptionLevelFull;
2061 if (m_options.m_verbose)
2062 desc_level = eDescriptionLevelVerbose;
2063
2064 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2065 return true;
2066 }
2067 CommandOptions m_options;
2068};
2069
2070OptionDefinition
2071CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2072{
2073{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
2074{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2075{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2076};
2077
2078class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2079{
2080public:
2081 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
2082 CommandObjectParsed (interpreter,
2083 "thread plan discard",
2084 "Discards thread plans up to and including the plan passed as the command argument."
2085 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2086 " without the \"-i\" argument.",
2087 NULL,
2088 eFlagRequiresProcess |
2089 eFlagRequiresThread |
2090 eFlagTryTargetAPILock |
2091 eFlagProcessMustBeLaunched |
2092 eFlagProcessMustBePaused )
2093 {
2094 CommandArgumentEntry arg;
2095 CommandArgumentData plan_index_arg;
2096
2097 // Define the first (and only) variant of this arg.
2098 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2099 plan_index_arg.arg_repetition = eArgRepeatPlain;
2100
2101 // There is only one variant this argument could be; put it into the argument entry.
2102 arg.push_back (plan_index_arg);
2103
2104 // Push the data for the first argument into the m_arguments vector.
2105 m_arguments.push_back (arg);
2106 }
2107
2108 virtual ~CommandObjectThreadPlanDiscard () {}
2109
2110 bool
2111 DoExecute (Args& args, CommandReturnObject &result)
2112 {
2113 Thread *thread = m_exe_ctx.GetThreadPtr();
2114 if (args.GetArgumentCount() != 1)
2115 {
2116 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2117 args.GetArgumentCount());
2118 result.SetStatus (eReturnStatusFailed);
2119 return false;
2120 }
2121
2122 bool success;
2123 uint32_t thread_plan_idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
2124 if (!success)
2125 {
2126 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2127 args.GetArgumentAtIndex(0));
2128 result.SetStatus (eReturnStatusFailed);
2129 return false;
2130 }
2131
2132 if (thread_plan_idx == 0)
2133 {
2134 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2135 result.SetStatus (eReturnStatusFailed);
2136 return false;
2137 }
2138
2139 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2140 {
2141 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2142 return true;
2143 }
2144 else
2145 {
2146 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2147 args.GetArgumentAtIndex(0));
2148 result.SetStatus (eReturnStatusFailed);
2149 return false;
2150 }
2151 }
2152};
2153
2154//-------------------------------------------------------------------------
2155// CommandObjectMultiwordThreadPlan
2156//-------------------------------------------------------------------------
2157
2158class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2159{
2160public:
2161 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2162 CommandObjectMultiword (interpreter,
2163 "plan",
2164 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2165 "thread plan <subcommand> [<subcommand objects]")
2166 {
2167 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2168 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2169 }
2170
2171 virtual ~CommandObjectMultiwordThreadPlan () {}
2172
2173
2174};
2175
2176//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002177// CommandObjectMultiwordThread
2178//-------------------------------------------------------------------------
2179
Greg Clayton66111032010-06-23 01:19:29 +00002180CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002181 CommandObjectMultiword (interpreter,
2182 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002183 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002184 "thread <subcommand> [<subcommand-options>]")
2185{
Greg Claytona7015092010-09-18 01:14:36 +00002186 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2187 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2188 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002189 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002190 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002191 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2192 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002193 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002194 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2195 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002196 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002197 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002198 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002199 eStepTypeInto,
2200 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00002201
Greg Claytona7015092010-09-18 01:14:36 +00002202 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2203 interpreter,
2204 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002205 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002206 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002207 eStepTypeOut,
2208 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002209
Greg Claytona7015092010-09-18 01:14:36 +00002210 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2211 interpreter,
2212 "thread step-over",
2213 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002214 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002215 eStepTypeOver,
2216 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002217
Greg Claytona7015092010-09-18 01:14:36 +00002218 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2219 interpreter,
2220 "thread step-inst",
2221 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002222 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002223 eStepTypeTrace,
2224 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002225
Greg Claytona7015092010-09-18 01:14:36 +00002226 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2227 interpreter,
2228 "thread step-inst-over",
2229 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002230 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002231 eStepTypeTraceOver,
2232 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002233
2234 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2235 interpreter,
2236 "thread step-scripted",
2237 "Step as instructed by the script class passed in the -C option.",
2238 NULL,
2239 eStepTypeScripted,
2240 eStepScopeSource)));
2241
2242 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002243}
2244
2245CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
2246{
2247}
2248
2249