blob: fbb233ab1dbf4d554b2c1e615f25c11339119476 [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;
Jim Ingham7a88ec92014-07-08 19:28:57 +0000457 int32_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
666 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
667 process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000668
669 // There is a race condition where this thread will return up the call stack to the main command handler
670 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
671 // a chance to call PushProcessIOHandler().
672 process->SyncIOHandler(2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000673
674 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000675 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000676 StateType state = process->WaitForProcessToStop (NULL);
677
678 //EventSP event_sp;
679 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
680 //while (! StateIsStoppedState (state))
681 // {
682 // state = process->WaitForStateChangedEvents (NULL, event_sp);
683 // }
684 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
685 result.SetDidChangeProcessState (true);
686 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
687 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000689 else
690 {
691 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
692 }
693 }
694 else
695 {
696 result.AppendError ("Couldn't find thread plan to implement step type.");
697 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698 }
699 return result.Succeeded();
700 }
701
702protected:
703 StepType m_step_type;
704 StepScope m_step_scope;
705 CommandOptions m_options;
706};
707
Greg Claytone0d378b2011-03-24 21:19:54 +0000708static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709g_tri_running_mode[] =
710{
Greg Claytoned8a7052010-09-18 03:37:20 +0000711{ eOnlyThisThread, "this-thread", "Run only this thread"},
712{ eAllThreads, "all-threads", "Run all threads"},
713{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714{ 0, NULL, NULL }
715};
716
Greg Claytone0d378b2011-03-24 21:19:54 +0000717static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718g_duo_running_mode[] =
719{
Greg Claytoned8a7052010-09-18 03:37:20 +0000720{ eOnlyThisThread, "this-thread", "Run only this thread"},
721{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722{ 0, NULL, NULL }
723};
724
Greg Claytone0d378b2011-03-24 21:19:54 +0000725OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000726CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
727{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000728{ 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."},
729{ 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 +0000730{ 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."},
731{ 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."},
732{ 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."},
733{ 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."},
734{ 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 +0000735{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000736};
737
738
739//-------------------------------------------------------------------------
740// CommandObjectThreadContinue
741//-------------------------------------------------------------------------
742
Jim Ingham5a988412012-06-08 21:56:10 +0000743class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744{
745public:
746
Greg Claytona7015092010-09-18 01:14:36 +0000747 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000748 CommandObjectParsed (interpreter,
749 "thread continue",
750 "Continue execution of one or more threads in an active process.",
751 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000752 eFlagRequiresThread |
753 eFlagTryTargetAPILock |
754 eFlagProcessMustBeLaunched |
755 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 {
Caroline Tice405fe672010-10-04 22:28:36 +0000757 CommandArgumentEntry arg;
758 CommandArgumentData thread_idx_arg;
759
760 // Define the first (and only) variant of this arg.
761 thread_idx_arg.arg_type = eArgTypeThreadIndex;
762 thread_idx_arg.arg_repetition = eArgRepeatPlus;
763
764 // There is only one variant this argument could be; put it into the argument entry.
765 arg.push_back (thread_idx_arg);
766
767 // Push the data for the first argument into the m_arguments vector.
768 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769 }
770
771
772 virtual
773 ~CommandObjectThreadContinue ()
774 {
775 }
776
777 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000778 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779 {
Greg Claytona7015092010-09-18 01:14:36 +0000780 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000781
Greg Claytona7015092010-09-18 01:14:36 +0000782 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000784 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785 result.SetStatus (eReturnStatusFailed);
786 return false;
787 }
788
Greg Claytonf9fc6092013-01-09 19:44:40 +0000789 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000790 if (process == NULL)
791 {
792 result.AppendError ("no process exists. Cannot continue");
793 result.SetStatus (eReturnStatusFailed);
794 return false;
795 }
796
797 StateType state = process->GetState();
798 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
799 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 const size_t argc = command.GetArgumentCount();
801 if (argc > 0)
802 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000803 // These two lines appear at the beginning of both blocks in
804 // this if..else, but that is because we need to release the
805 // lock before calling process->Resume below.
806 Mutex::Locker locker (process->GetThreadList().GetMutex());
807 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000808 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000809 for (uint32_t i=0; i<argc; ++i)
810 {
Jim Inghamce76c622012-05-31 20:48:41 +0000811 bool success;
812 const int base = 0;
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000813 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
814 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000815 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000816 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000817
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000818 if (thread)
819 {
820 resume_threads.push_back(thread);
821 }
822 else
823 {
824 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
825 result.SetStatus (eReturnStatusFailed);
826 return false;
827 }
Jim Inghamce76c622012-05-31 20:48:41 +0000828 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 else
Jim Inghamce76c622012-05-31 20:48:41 +0000830 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000831 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000832 result.SetStatus (eReturnStatusFailed);
833 return false;
834 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000836
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000837 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838 {
839 result.AppendError ("no valid thread indexes were specified");
840 result.SetStatus (eReturnStatusFailed);
841 return false;
842 }
843 else
844 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000845 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000846 result.AppendMessageWithFormat ("Resuming thread: ");
847 else
848 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000849
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000850 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000852 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
853 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000854
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000855 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000857 resume_threads.erase(this_thread_pos);
858 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000859 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
860 else
861 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000862
863 const bool override_suspend = true;
864 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865 }
866 else
867 {
868 thread->SetResumeState (eStateSuspended);
869 }
870 }
Daniel Malead01b2952012-11-29 21:49:15 +0000871 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000872 }
873 }
874 else
875 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000876 // These two lines appear at the beginning of both blocks in
877 // this if..else, but that is because we need to release the
878 // lock before calling process->Resume below.
879 Mutex::Locker locker (process->GetThreadList().GetMutex());
880 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000881 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000882 if (current_thread == NULL)
883 {
884 result.AppendError ("the process doesn't have a current thread");
885 result.SetStatus (eReturnStatusFailed);
886 return false;
887 }
888 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000889 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000890 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000891 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 if (thread == current_thread)
893 {
Daniel Malead01b2952012-11-29 21:49:15 +0000894 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000895 const bool override_suspend = true;
896 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000897 }
898 else
899 {
900 thread->SetResumeState (eStateSuspended);
901 }
902 }
903 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000904
905 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906 Error error (process->Resume());
907 if (error.Success())
908 {
Daniel Malead01b2952012-11-29 21:49:15 +0000909 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000910 if (synchronous_execution)
911 {
Greg Claytonb1320972010-07-14 00:18:15 +0000912 state = process->WaitForProcessToStop (NULL);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000913
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000914 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +0000915 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916 result.SetStatus (eReturnStatusSuccessFinishNoResult);
917 }
918 else
919 {
920 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
921 }
922 }
923 else
924 {
925 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
926 result.SetStatus (eReturnStatusFailed);
927 }
928 }
929 else
930 {
931 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
932 StateAsCString(state));
933 result.SetStatus (eReturnStatusFailed);
934 }
935
936 return result.Succeeded();
937 }
938
939};
940
941//-------------------------------------------------------------------------
942// CommandObjectThreadUntil
943//-------------------------------------------------------------------------
944
Jim Ingham5a988412012-06-08 21:56:10 +0000945class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946{
947public:
948
949 class CommandOptions : public Options
950 {
951 public:
952 uint32_t m_thread_idx;
953 uint32_t m_frame_idx;
954
Greg Claytoneb0103f2011-04-07 22:46:35 +0000955 CommandOptions (CommandInterpreter &interpreter) :
956 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000957 m_thread_idx(LLDB_INVALID_THREAD_ID),
958 m_frame_idx(LLDB_INVALID_FRAME_ID)
959 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000960 // Keep default values of all options in one place: OptionParsingStarting ()
961 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962 }
963
964 virtual
965 ~CommandOptions ()
966 {
967 }
968
969 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000970 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000971 {
972 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000973 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000974
975 switch (short_option)
976 {
977 case 't':
978 {
Greg Claytonb1320972010-07-14 00:18:15 +0000979 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000980 if (m_thread_idx == LLDB_INVALID_INDEX32)
981 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000982 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000983 }
984 }
985 break;
986 case 'f':
987 {
988 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
989 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
990 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000991 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000992 }
993 }
994 break;
995 case 'm':
996 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000997 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000998 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000999
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001000 if (error.Success())
1001 {
1002 if (run_mode == eAllThreads)
1003 m_stop_others = false;
1004 else
1005 m_stop_others = true;
1006 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007 }
1008 break;
1009 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001010 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 break;
1012
1013 }
1014 return error;
1015 }
1016
1017 void
Greg Claytonf6b8b582011-04-13 00:18:08 +00001018 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001020 m_thread_idx = LLDB_INVALID_THREAD_ID;
1021 m_frame_idx = 0;
1022 m_stop_others = false;
1023 }
1024
Greg Claytone0d378b2011-03-24 21:19:54 +00001025 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026 GetDefinitions ()
1027 {
1028 return g_option_table;
1029 }
1030
1031 uint32_t m_step_thread_idx;
1032 bool m_stop_others;
1033
1034 // Options table: Required for subclasses of Options.
1035
Greg Claytone0d378b2011-03-24 21:19:54 +00001036 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037
1038 // Instance variables to hold the values for command options.
1039 };
1040
Greg Claytona7015092010-09-18 01:14:36 +00001041 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001042 CommandObjectParsed (interpreter,
1043 "thread until",
1044 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
1045 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001046 eFlagRequiresThread |
1047 eFlagTryTargetAPILock |
1048 eFlagProcessMustBeLaunched |
1049 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001050 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051 {
Caroline Tice405fe672010-10-04 22:28:36 +00001052 CommandArgumentEntry arg;
1053 CommandArgumentData line_num_arg;
1054
1055 // Define the first (and only) variant of this arg.
1056 line_num_arg.arg_type = eArgTypeLineNum;
1057 line_num_arg.arg_repetition = eArgRepeatPlain;
1058
1059 // There is only one variant this argument could be; put it into the argument entry.
1060 arg.push_back (line_num_arg);
1061
1062 // Push the data for the first argument into the m_arguments vector.
1063 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001064 }
1065
1066
1067 virtual
1068 ~CommandObjectThreadUntil ()
1069 {
1070 }
1071
1072 virtual
1073 Options *
1074 GetOptions ()
1075 {
1076 return &m_options;
1077 }
1078
Jim Ingham5a988412012-06-08 21:56:10 +00001079protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001080 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001081 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082 {
Greg Claytona7015092010-09-18 01:14:36 +00001083 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001084
Greg Claytona7015092010-09-18 01:14:36 +00001085 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +00001086 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001088 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089 result.SetStatus (eReturnStatusFailed);
1090 return false;
1091 }
1092
Greg Claytonf9fc6092013-01-09 19:44:40 +00001093 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094 if (process == NULL)
1095 {
1096 result.AppendError ("need a valid process to step");
1097 result.SetStatus (eReturnStatusFailed);
1098
1099 }
1100 else
1101 {
1102 Thread *thread = NULL;
1103 uint32_t line_number;
1104
1105 if (command.GetArgumentCount() != 1)
1106 {
1107 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1108 result.SetStatus (eReturnStatusFailed);
1109 return false;
1110 }
1111
1112 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1113 if (line_number == UINT32_MAX)
1114 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001115 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116 result.SetStatus (eReturnStatusFailed);
1117 return false;
1118 }
1119
1120 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1121 {
Jim Ingham2976d002010-08-26 21:32:51 +00001122 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001123 }
1124 else
1125 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001126 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127 }
1128
1129 if (thread == NULL)
1130 {
1131 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001132 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1133 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001134 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135 result.SetStatus (eReturnStatusFailed);
1136 return false;
1137 }
1138
Jim Ingham7ba6e992012-05-11 23:47:32 +00001139 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140
Jason Molendab57e4a12013-11-04 09:33:30 +00001141 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001142 if (frame == NULL)
1143 {
1144
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001145 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1146 m_options.m_frame_idx,
1147 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148 result.SetStatus (eReturnStatusFailed);
1149 return false;
1150 }
1151
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001152 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153
1154 if (frame->HasDebugInformation ())
1155 {
1156 // Finally we got here... Translate the given line number to a bunch of addresses:
1157 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1158 LineTable *line_table = NULL;
1159 if (sc.comp_unit)
1160 line_table = sc.comp_unit->GetLineTable();
1161
1162 if (line_table == NULL)
1163 {
1164 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1165 m_options.m_frame_idx, m_options.m_thread_idx);
1166 result.SetStatus (eReturnStatusFailed);
1167 return false;
1168 }
1169
1170 LineEntry function_start;
1171 uint32_t index_ptr = 0, end_ptr;
1172 std::vector<addr_t> address_list;
1173
1174 // Find the beginning & end index of the
1175 AddressRange fun_addr_range = sc.function->GetAddressRange();
1176 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1177 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1178
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001179 Address fun_end_addr(fun_start_addr.GetSection(),
1180 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1182
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001183 bool all_in_function = true;
1184
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185 while (index_ptr <= end_ptr)
1186 {
1187 LineEntry line_entry;
Jim Ingham87df91b2011-09-23 00:54:11 +00001188 const bool exact = false;
1189 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001190 if (index_ptr == UINT32_MAX)
1191 break;
1192
Greg Claytonf5e56de2010-09-14 23:36:40 +00001193 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001194 if (address != LLDB_INVALID_ADDRESS)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001195 {
1196 if (fun_addr_range.ContainsLoadAddress (address, target))
1197 address_list.push_back (address);
1198 else
1199 all_in_function = false;
1200 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201 index_ptr++;
1202 }
1203
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001204 if (address_list.size() == 0)
1205 {
1206 if (all_in_function)
1207 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1208 else
1209 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1210
1211 result.SetStatus (eReturnStatusFailed);
1212 return false;
1213 }
1214
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001215 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001216 &address_list.front(),
1217 address_list.size(),
1218 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001219 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001220 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1221 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1222 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001223 new_plan_sp->SetIsMasterPlan (true);
1224 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001225 }
1226 else
1227 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001228 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1229 m_options.m_frame_idx,
1230 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231 result.SetStatus (eReturnStatusFailed);
1232 return false;
1233
1234 }
1235
Jim Ingham2976d002010-08-26 21:32:51 +00001236 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237 Error error (process->Resume ());
1238 if (error.Success())
1239 {
Daniel Malead01b2952012-11-29 21:49:15 +00001240 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241 if (synchronous_execution)
1242 {
1243 StateType state = process->WaitForProcessToStop (NULL);
1244
1245 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +00001246 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1248 }
1249 else
1250 {
1251 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1252 }
1253 }
1254 else
1255 {
1256 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1257 result.SetStatus (eReturnStatusFailed);
1258 }
1259
1260 }
1261 return result.Succeeded();
1262 }
Jim Ingham5a988412012-06-08 21:56:10 +00001263
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264 CommandOptions m_options;
1265
1266};
1267
Greg Claytone0d378b2011-03-24 21:19:54 +00001268OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1270{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001271{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1272{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1273{ 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"},
1274{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275};
1276
1277
1278//-------------------------------------------------------------------------
1279// CommandObjectThreadSelect
1280//-------------------------------------------------------------------------
1281
Jim Ingham5a988412012-06-08 21:56:10 +00001282class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001283{
1284public:
1285
Greg Claytona7015092010-09-18 01:14:36 +00001286 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001287 CommandObjectParsed (interpreter,
1288 "thread select",
1289 "Select a thread as the currently active thread.",
1290 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001291 eFlagRequiresProcess |
1292 eFlagTryTargetAPILock |
1293 eFlagProcessMustBeLaunched |
1294 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295 {
Caroline Tice405fe672010-10-04 22:28:36 +00001296 CommandArgumentEntry arg;
1297 CommandArgumentData thread_idx_arg;
1298
1299 // Define the first (and only) variant of this arg.
1300 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1301 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1302
1303 // There is only one variant this argument could be; put it into the argument entry.
1304 arg.push_back (thread_idx_arg);
1305
1306 // Push the data for the first argument into the m_arguments vector.
1307 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001308 }
1309
1310
1311 virtual
1312 ~CommandObjectThreadSelect ()
1313 {
1314 }
1315
Jim Ingham5a988412012-06-08 21:56:10 +00001316protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001318 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001320 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001321 if (process == NULL)
1322 {
1323 result.AppendError ("no process");
1324 result.SetStatus (eReturnStatusFailed);
1325 return false;
1326 }
1327 else if (command.GetArgumentCount() != 1)
1328 {
Jason Molendafd54b362011-09-20 21:44:10 +00001329 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 +00001330 result.SetStatus (eReturnStatusFailed);
1331 return false;
1332 }
1333
1334 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1335
1336 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1337 if (new_thread == NULL)
1338 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001339 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001340 result.SetStatus (eReturnStatusFailed);
1341 return false;
1342 }
1343
Jim Inghamc3faa192012-12-11 02:31:48 +00001344 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001345 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001346
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001347 return result.Succeeded();
1348 }
1349
1350};
1351
1352
1353//-------------------------------------------------------------------------
1354// CommandObjectThreadList
1355//-------------------------------------------------------------------------
1356
Jim Ingham5a988412012-06-08 21:56:10 +00001357class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001358{
Greg Clayton66111032010-06-23 01:19:29 +00001359public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001360
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001361
Greg Claytona7015092010-09-18 01:14:36 +00001362 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001363 CommandObjectParsed (interpreter,
1364 "thread list",
1365 "Show a summary of all current threads in a process.",
1366 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001367 eFlagRequiresProcess |
1368 eFlagTryTargetAPILock |
1369 eFlagProcessMustBeLaunched |
1370 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001371 {
Greg Clayton66111032010-06-23 01:19:29 +00001372 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001373
Greg Clayton66111032010-06-23 01:19:29 +00001374 ~CommandObjectThreadList()
1375 {
1376 }
1377
Jim Ingham5a988412012-06-08 21:56:10 +00001378protected:
Greg Clayton66111032010-06-23 01:19:29 +00001379 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001380 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001381 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001382 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001383 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001384 Process *process = m_exe_ctx.GetProcessPtr();
1385 const bool only_threads_with_stop_reason = false;
1386 const uint32_t start_frame = 0;
1387 const uint32_t num_frames = 0;
1388 const uint32_t num_frames_with_source = 0;
1389 process->GetStatus(strm);
1390 process->GetThreadStatus (strm,
1391 only_threads_with_stop_reason,
1392 start_frame,
1393 num_frames,
1394 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001395 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001396 }
Greg Clayton66111032010-06-23 01:19:29 +00001397};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001398
Jim Ingham93208b82013-01-31 21:46:01 +00001399//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001400// CommandObjectThreadInfo
1401//-------------------------------------------------------------------------
1402
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001403class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001404{
1405public:
1406
1407 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001408 CommandObjectIterateOverThreads (interpreter,
1409 "thread info",
1410 "Show an extended summary of information about thread(s) in a process.",
1411 "thread info",
1412 eFlagRequiresProcess |
1413 eFlagTryTargetAPILock |
1414 eFlagProcessMustBeLaunched |
1415 eFlagProcessMustBePaused),
Jason Molenda705b1802014-06-13 02:37:02 +00001416 m_options (interpreter)
1417 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001418 m_add_return = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001419 }
1420
1421 class CommandOptions : public Options
1422 {
1423 public:
1424
1425 CommandOptions (CommandInterpreter &interpreter) :
1426 Options (interpreter)
1427 {
1428 OptionParsingStarting ();
1429 }
1430
1431 void
1432 OptionParsingStarting ()
1433 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001434 m_json_thread = false;
1435 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001436 }
1437
1438 virtual
1439 ~CommandOptions ()
1440 {
1441 }
1442
1443 virtual Error
1444 SetOptionValue (uint32_t option_idx, const char *option_arg)
1445 {
1446 const int short_option = m_getopt_table[option_idx].val;
1447 Error error;
1448
1449 switch (short_option)
1450 {
1451 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001452 m_json_thread = true;
1453 break;
1454
1455 case 's':
1456 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001457 break;
1458
Kuba Breckaafdf8422014-10-10 23:43:03 +00001459 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001460 return Error("invalid short option character '%c'", short_option);
1461
1462 }
1463 return error;
1464 }
1465
1466 const OptionDefinition*
1467 GetDefinitions ()
1468 {
1469 return g_option_table;
1470 }
1471
Kuba Breckaafdf8422014-10-10 23:43:03 +00001472 bool m_json_thread;
1473 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001474
1475 static OptionDefinition g_option_table[];
1476 };
1477
1478 virtual
1479 Options *
1480 GetOptions ()
1481 {
1482 return &m_options;
1483 }
1484
1485
1486 virtual
1487 ~CommandObjectThreadInfo ()
1488 {
1489 }
1490
1491 virtual bool
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001492 HandleOneThread (Thread &thread, CommandReturnObject &result)
Jason Molenda705b1802014-06-13 02:37:02 +00001493 {
Jason Molenda705b1802014-06-13 02:37:02 +00001494 Stream &strm = result.GetOutputStream();
Kuba Breckaafdf8422014-10-10 23:43:03 +00001495 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
Jason Molenda705b1802014-06-13 02:37:02 +00001496 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001497 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1498 result.SetStatus (eReturnStatusFailed);
1499 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001500 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001501 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001502 }
1503
1504 CommandOptions m_options;
1505
1506};
1507
1508OptionDefinition
1509CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1510{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001511 { 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 +00001512 { 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 +00001513
Zachary Turnerd37221d2014-07-09 16:31:49 +00001514 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jason Molenda705b1802014-06-13 02:37:02 +00001515};
1516
1517
1518//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001519// CommandObjectThreadReturn
1520//-------------------------------------------------------------------------
1521
Jim Inghamcb640dd2012-09-14 02:14:15 +00001522class CommandObjectThreadReturn : public CommandObjectRaw
1523{
1524public:
Jim Ingham93208b82013-01-31 21:46:01 +00001525 class CommandOptions : public Options
1526 {
1527 public:
1528
1529 CommandOptions (CommandInterpreter &interpreter) :
1530 Options (interpreter),
1531 m_from_expression (false)
1532 {
1533 // Keep default values of all options in one place: OptionParsingStarting ()
1534 OptionParsingStarting ();
1535 }
1536
1537 virtual
1538 ~CommandOptions ()
1539 {
1540 }
1541
1542 virtual Error
1543 SetOptionValue (uint32_t option_idx, const char *option_arg)
1544 {
1545 Error error;
1546 const int short_option = m_getopt_table[option_idx].val;
1547
1548 switch (short_option)
1549 {
1550 case 'x':
1551 {
1552 bool success;
1553 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1554 if (success)
1555 m_from_expression = tmp_value;
1556 else
1557 {
1558 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1559 }
1560 }
1561 break;
1562 default:
1563 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1564 break;
1565
1566 }
1567 return error;
1568 }
1569
1570 void
1571 OptionParsingStarting ()
1572 {
1573 m_from_expression = false;
1574 }
1575
1576 const OptionDefinition*
1577 GetDefinitions ()
1578 {
1579 return g_option_table;
1580 }
1581
1582 bool m_from_expression;
1583
1584 // Options table: Required for subclasses of Options.
1585
1586 static OptionDefinition g_option_table[];
1587
1588 // Instance variables to hold the values for command options.
1589 };
1590
1591 virtual
1592 Options *
1593 GetOptions ()
1594 {
1595 return &m_options;
1596 }
1597
Jim Inghamcb640dd2012-09-14 02:14:15 +00001598 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1599 CommandObjectRaw (interpreter,
1600 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001601 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1602 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001603 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001604 eFlagRequiresFrame |
1605 eFlagTryTargetAPILock |
1606 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001607 eFlagProcessMustBePaused ),
1608 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001609 {
1610 CommandArgumentEntry arg;
1611 CommandArgumentData expression_arg;
1612
1613 // Define the first (and only) variant of this arg.
1614 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001615 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001616
1617 // There is only one variant this argument could be; put it into the argument entry.
1618 arg.push_back (expression_arg);
1619
1620 // Push the data for the first argument into the m_arguments vector.
1621 m_arguments.push_back (arg);
1622
1623
1624 }
1625
1626 ~CommandObjectThreadReturn()
1627 {
1628 }
1629
1630protected:
1631
1632 bool DoExecute
1633 (
1634 const char *command,
1635 CommandReturnObject &result
1636 )
1637 {
Jim Ingham93208b82013-01-31 21:46:01 +00001638 // I am going to handle this by hand, because I don't want you to have to say:
1639 // "thread return -- -5".
1640 if (command[0] == '-' && command[1] == 'x')
1641 {
1642 if (command && command[2] != '\0')
1643 result.AppendWarning("Return values ignored when returning from user called expressions");
1644
1645 Thread *thread = m_exe_ctx.GetThreadPtr();
1646 Error error;
1647 error = thread->UnwindInnermostExpression();
1648 if (!error.Success())
1649 {
1650 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1651 result.SetStatus (eReturnStatusFailed);
1652 }
1653 else
1654 {
1655 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1656 if (success)
1657 {
1658 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1659 result.SetStatus (eReturnStatusSuccessFinishResult);
1660 }
1661 else
1662 {
1663 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1664 result.SetStatus (eReturnStatusFailed);
1665 }
1666 }
1667 return result.Succeeded();
1668 }
1669
Jim Inghamcb640dd2012-09-14 02:14:15 +00001670 ValueObjectSP return_valobj_sp;
1671
Jason Molendab57e4a12013-11-04 09:33:30 +00001672 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001673 uint32_t frame_idx = frame_sp->GetFrameIndex();
1674
1675 if (frame_sp->IsInlined())
1676 {
1677 result.AppendError("Don't know how to return from inlined frames.");
1678 result.SetStatus (eReturnStatusFailed);
1679 return false;
1680 }
1681
1682 if (command && command[0] != '\0')
1683 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001684 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001685 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001686
1687 options.SetUnwindOnError(true);
1688 options.SetUseDynamic(eNoDynamicValues);
1689
Jim Ingham8646d3c2014-05-05 02:47:44 +00001690 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001691 exe_results = target->EvaluateExpression (command,
1692 frame_sp.get(),
1693 return_valobj_sp,
1694 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001695 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001696 {
1697 if (return_valobj_sp)
1698 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1699 else
1700 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1701 result.SetStatus (eReturnStatusFailed);
1702 return false;
1703
1704 }
1705 }
1706
1707 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001708 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001709 const bool broadcast = true;
1710 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001711 if (!error.Success())
1712 {
1713 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1714 result.SetStatus (eReturnStatusFailed);
1715 return false;
1716 }
1717
Jim Inghamcb640dd2012-09-14 02:14:15 +00001718 result.SetStatus (eReturnStatusSuccessFinishResult);
1719 return true;
1720 }
Jim Ingham93208b82013-01-31 21:46:01 +00001721
1722 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001723
1724};
Jim Ingham93208b82013-01-31 21:46:01 +00001725OptionDefinition
1726CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1727{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001728{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1729{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham93208b82013-01-31 21:46:01 +00001730};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001731
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001732//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001733// CommandObjectThreadJump
1734//-------------------------------------------------------------------------
1735
1736class CommandObjectThreadJump : public CommandObjectParsed
1737{
1738public:
1739 class CommandOptions : public Options
1740 {
1741 public:
1742
1743 CommandOptions (CommandInterpreter &interpreter) :
1744 Options (interpreter)
1745 {
1746 OptionParsingStarting ();
1747 }
1748
1749 void
1750 OptionParsingStarting ()
1751 {
1752 m_filenames.Clear();
1753 m_line_num = 0;
1754 m_line_offset = 0;
1755 m_load_addr = LLDB_INVALID_ADDRESS;
1756 m_force = false;
1757 }
1758
1759 virtual
1760 ~CommandOptions ()
1761 {
1762 }
1763
1764 virtual Error
1765 SetOptionValue (uint32_t option_idx, const char *option_arg)
1766 {
1767 bool success;
1768 const int short_option = m_getopt_table[option_idx].val;
1769 Error error;
1770
1771 switch (short_option)
1772 {
1773 case 'f':
1774 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1775 if (m_filenames.GetSize() > 1)
1776 return Error("only one source file expected.");
1777 break;
1778 case 'l':
1779 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1780 if (!success || m_line_num == 0)
1781 return Error("invalid line number: '%s'.", option_arg);
1782 break;
1783 case 'b':
1784 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1785 if (!success)
1786 return Error("invalid line offset: '%s'.", option_arg);
1787 break;
1788 case 'a':
1789 {
1790 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1791 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1792 }
1793 break;
1794 case 'r':
1795 m_force = true;
1796 break;
1797
1798 default:
1799 return Error("invalid short option character '%c'", short_option);
1800
1801 }
1802 return error;
1803 }
1804
1805 const OptionDefinition*
1806 GetDefinitions ()
1807 {
1808 return g_option_table;
1809 }
1810
1811 FileSpecList m_filenames;
1812 uint32_t m_line_num;
1813 int32_t m_line_offset;
1814 lldb::addr_t m_load_addr;
1815 bool m_force;
1816
1817 static OptionDefinition g_option_table[];
1818 };
1819
1820 virtual
1821 Options *
1822 GetOptions ()
1823 {
1824 return &m_options;
1825 }
1826
1827 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1828 CommandObjectParsed (interpreter,
1829 "thread jump",
1830 "Sets the program counter to a new address.",
1831 "thread jump",
1832 eFlagRequiresFrame |
1833 eFlagTryTargetAPILock |
1834 eFlagProcessMustBeLaunched |
1835 eFlagProcessMustBePaused ),
1836 m_options (interpreter)
1837 {
1838 }
1839
1840 ~CommandObjectThreadJump()
1841 {
1842 }
1843
1844protected:
1845
1846 bool DoExecute (Args& args, CommandReturnObject &result)
1847 {
1848 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001849 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001850 Thread *thread = m_exe_ctx.GetThreadPtr();
1851 Target *target = m_exe_ctx.GetTargetPtr();
1852 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1853
1854 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1855 {
1856 // Use this address directly.
1857 Address dest = Address(m_options.m_load_addr);
1858
1859 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1860 if (callAddr == LLDB_INVALID_ADDRESS)
1861 {
1862 result.AppendErrorWithFormat ("Invalid destination address.");
1863 result.SetStatus (eReturnStatusFailed);
1864 return false;
1865 }
1866
1867 if (!reg_ctx->SetPC (callAddr))
1868 {
1869 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1870 result.SetStatus (eReturnStatusFailed);
1871 return false;
1872 }
1873 }
1874 else
1875 {
1876 // Pick either the absolute line, or work out a relative one.
1877 int32_t line = (int32_t)m_options.m_line_num;
1878 if (line == 0)
1879 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1880
1881 // Try the current file, but override if asked.
1882 FileSpec file = sym_ctx.line_entry.file;
1883 if (m_options.m_filenames.GetSize() == 1)
1884 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1885
1886 if (!file)
1887 {
1888 result.AppendErrorWithFormat ("No source file available for the current location.");
1889 result.SetStatus (eReturnStatusFailed);
1890 return false;
1891 }
1892
1893 std::string warnings;
1894 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1895
1896 if (err.Fail())
1897 {
1898 result.SetError (err);
1899 return false;
1900 }
1901
1902 if (!warnings.empty())
1903 result.AppendWarning (warnings.c_str());
1904 }
1905
1906 result.SetStatus (eReturnStatusSuccessFinishResult);
1907 return true;
1908 }
1909
1910 CommandOptions m_options;
1911};
1912OptionDefinition
1913CommandObjectThreadJump::CommandOptions::g_option_table[] =
1914{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001915 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001916 "Specifies the source file to jump to."},
1917
Zachary Turnerd37221d2014-07-09 16:31:49 +00001918 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001919 "Specifies the line number to jump to."},
1920
Zachary Turnerd37221d2014-07-09 16:31:49 +00001921 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001922 "Jumps by a relative line offset from the current line."},
1923
Zachary Turnerd37221d2014-07-09 16:31:49 +00001924 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001925 "Jumps to a specific address."},
1926
1927 { LLDB_OPT_SET_1|
1928 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +00001929 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 +00001930
Zachary Turnerd37221d2014-07-09 16:31:49 +00001931 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Richard Mittonf86248d2013-09-12 02:20:34 +00001932};
1933
1934//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001935// Next are the subcommands of CommandObjectMultiwordThreadPlan
1936//-------------------------------------------------------------------------
1937
1938
1939//-------------------------------------------------------------------------
1940// CommandObjectThreadPlanList
1941//-------------------------------------------------------------------------
1942class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1943{
1944public:
1945
1946 class CommandOptions : public Options
1947 {
1948 public:
1949
1950 CommandOptions (CommandInterpreter &interpreter) :
1951 Options(interpreter)
1952 {
1953 // Keep default values of all options in one place: OptionParsingStarting ()
1954 OptionParsingStarting ();
1955 }
1956
1957 virtual
1958 ~CommandOptions ()
1959 {
1960 }
1961
1962 virtual Error
1963 SetOptionValue (uint32_t option_idx, const char *option_arg)
1964 {
1965 Error error;
1966 const int short_option = m_getopt_table[option_idx].val;
1967
1968 switch (short_option)
1969 {
1970 case 'i':
1971 {
1972 m_internal = true;
1973 }
1974 break;
1975 case 'v':
1976 {
1977 m_verbose = true;
1978 }
1979 break;
1980 default:
1981 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1982 break;
1983
1984 }
1985 return error;
1986 }
1987
1988 void
1989 OptionParsingStarting ()
1990 {
1991 m_verbose = false;
1992 m_internal = false;
1993 }
1994
1995 const OptionDefinition*
1996 GetDefinitions ()
1997 {
1998 return g_option_table;
1999 }
2000
2001 // Options table: Required for subclasses of Options.
2002
2003 static OptionDefinition g_option_table[];
2004
2005 // Instance variables to hold the values for command options.
2006 bool m_verbose;
2007 bool m_internal;
2008 };
2009
2010 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
2011 CommandObjectIterateOverThreads (interpreter,
2012 "thread plan list",
2013 "Show thread plans for one or more threads. If no threads are specified, show the "
2014 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2015 NULL,
2016 eFlagRequiresProcess |
2017 eFlagRequiresThread |
2018 eFlagTryTargetAPILock |
2019 eFlagProcessMustBeLaunched |
2020 eFlagProcessMustBePaused ),
2021 m_options(interpreter)
2022 {
2023 }
2024
2025 ~CommandObjectThreadPlanList ()
2026 {
2027 }
2028
2029 virtual Options *
2030 GetOptions ()
2031 {
2032 return &m_options;
2033 }
2034
2035protected:
2036 virtual bool
2037 HandleOneThread (Thread &thread, CommandReturnObject &result)
2038 {
2039 Stream &strm = result.GetOutputStream();
2040 DescriptionLevel desc_level = eDescriptionLevelFull;
2041 if (m_options.m_verbose)
2042 desc_level = eDescriptionLevelVerbose;
2043
2044 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2045 return true;
2046 }
2047 CommandOptions m_options;
2048};
2049
2050OptionDefinition
2051CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2052{
2053{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
2054{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2055{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2056};
2057
2058class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2059{
2060public:
2061 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
2062 CommandObjectParsed (interpreter,
2063 "thread plan discard",
2064 "Discards thread plans up to and including the plan passed as the command argument."
2065 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2066 " without the \"-i\" argument.",
2067 NULL,
2068 eFlagRequiresProcess |
2069 eFlagRequiresThread |
2070 eFlagTryTargetAPILock |
2071 eFlagProcessMustBeLaunched |
2072 eFlagProcessMustBePaused )
2073 {
2074 CommandArgumentEntry arg;
2075 CommandArgumentData plan_index_arg;
2076
2077 // Define the first (and only) variant of this arg.
2078 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2079 plan_index_arg.arg_repetition = eArgRepeatPlain;
2080
2081 // There is only one variant this argument could be; put it into the argument entry.
2082 arg.push_back (plan_index_arg);
2083
2084 // Push the data for the first argument into the m_arguments vector.
2085 m_arguments.push_back (arg);
2086 }
2087
2088 virtual ~CommandObjectThreadPlanDiscard () {}
2089
2090 bool
2091 DoExecute (Args& args, CommandReturnObject &result)
2092 {
2093 Thread *thread = m_exe_ctx.GetThreadPtr();
2094 if (args.GetArgumentCount() != 1)
2095 {
2096 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2097 args.GetArgumentCount());
2098 result.SetStatus (eReturnStatusFailed);
2099 return false;
2100 }
2101
2102 bool success;
2103 uint32_t thread_plan_idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
2104 if (!success)
2105 {
2106 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2107 args.GetArgumentAtIndex(0));
2108 result.SetStatus (eReturnStatusFailed);
2109 return false;
2110 }
2111
2112 if (thread_plan_idx == 0)
2113 {
2114 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2115 result.SetStatus (eReturnStatusFailed);
2116 return false;
2117 }
2118
2119 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2120 {
2121 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2122 return true;
2123 }
2124 else
2125 {
2126 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2127 args.GetArgumentAtIndex(0));
2128 result.SetStatus (eReturnStatusFailed);
2129 return false;
2130 }
2131 }
2132};
2133
2134//-------------------------------------------------------------------------
2135// CommandObjectMultiwordThreadPlan
2136//-------------------------------------------------------------------------
2137
2138class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2139{
2140public:
2141 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2142 CommandObjectMultiword (interpreter,
2143 "plan",
2144 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2145 "thread plan <subcommand> [<subcommand objects]")
2146 {
2147 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2148 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2149 }
2150
2151 virtual ~CommandObjectMultiwordThreadPlan () {}
2152
2153
2154};
2155
2156//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002157// CommandObjectMultiwordThread
2158//-------------------------------------------------------------------------
2159
Greg Clayton66111032010-06-23 01:19:29 +00002160CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002161 CommandObjectMultiword (interpreter,
2162 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002163 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002164 "thread <subcommand> [<subcommand-options>]")
2165{
Greg Claytona7015092010-09-18 01:14:36 +00002166 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2167 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2168 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002169 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002170 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002171 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2172 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002173 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002174 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2175 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002176 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002177 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002178 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002179 eStepTypeInto,
2180 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00002181
Greg Claytona7015092010-09-18 01:14:36 +00002182 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2183 interpreter,
2184 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002185 "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 +00002186 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002187 eStepTypeOut,
2188 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002189
Greg Claytona7015092010-09-18 01:14:36 +00002190 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2191 interpreter,
2192 "thread step-over",
2193 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002194 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002195 eStepTypeOver,
2196 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002197
Greg Claytona7015092010-09-18 01:14:36 +00002198 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2199 interpreter,
2200 "thread step-inst",
2201 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002202 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002203 eStepTypeTrace,
2204 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002205
Greg Claytona7015092010-09-18 01:14:36 +00002206 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2207 interpreter,
2208 "thread step-inst-over",
2209 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002210 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002211 eStepTypeTraceOver,
2212 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002213
2214 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2215 interpreter,
2216 "thread step-scripted",
2217 "Step as instructed by the script class passed in the -C option.",
2218 NULL,
2219 eStepTypeScripted,
2220 eStepScopeSource)));
2221
2222 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002223}
2224
2225CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
2226{
2227}
2228
2229