blob: e932c9d96c35c5c6a13ad498b592e03a86827c61 [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
10#include "CommandObjectThread.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Jim Inghamcb640dd2012-09-14 02:14:15 +000016#include "lldb/lldb-private.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Core/State.h"
18#include "lldb/Core/SourceManager.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000019#include "lldb/Core/ValueObject.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000020#include "lldb/Host/Host.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000021#include "lldb/Host/StringConvert.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
Bruce Mitchener13d21e92015-10-07 16:56:17 +000061 ~CommandObjectIterateOverThreads() override {}
62
63 bool
64 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +000065 {
66 result.SetStatus (m_success_return);
67
68 if (command.GetArgumentCount() == 0)
69 {
70 Thread *thread = m_exe_ctx.GetThreadPtr();
71 if (!HandleOneThread (*thread, result))
72 return false;
73 }
74 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
75 {
76 Process *process = m_exe_ctx.GetProcessPtr();
77 uint32_t idx = 0;
78 for (ThreadSP thread_sp : process->Threads())
79 {
80 if (idx != 0 && m_add_return)
81 result.AppendMessage("");
82
83 if (!HandleOneThread(*(thread_sp.get()), result))
84 return false;
85 ++idx;
86 }
87 }
88 else
89 {
90 const size_t num_args = command.GetArgumentCount();
91 Process *process = m_exe_ctx.GetProcessPtr();
92 Mutex::Locker locker (process->GetThreadList().GetMutex());
93 std::vector<ThreadSP> thread_sps;
94
95 for (size_t i = 0; i < num_args; i++)
96 {
97 bool success;
98
Vince Harron5275aaa2015-01-15 20:08:35 +000099 uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000100 if (!success)
101 {
102 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
103 result.SetStatus (eReturnStatusFailed);
104 return false;
105 }
106
107 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
108
109 if (!thread_sps[i])
110 {
111 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
112 result.SetStatus (eReturnStatusFailed);
113 return false;
114 }
115
116 }
117
118 for (uint32_t i = 0; i < num_args; i++)
119 {
120 if (!HandleOneThread (*(thread_sps[i].get()), result))
121 return false;
122
123 if (i < num_args - 1 && m_add_return)
124 result.AppendMessage("");
125 }
126 }
127 return result.Succeeded();
128 }
129
130protected:
131
132 // Override this to do whatever you need to do for one thread.
133 //
134 // If you return false, the iteration will stop, otherwise it will proceed.
135 // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
136 // so you only need to set the return status in HandleOneThread if you want to indicate an error.
137 // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
138
139 virtual bool
140 HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
141
142 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
143 bool m_add_return = true;
144
145};
146
147//-------------------------------------------------------------------------
148// CommandObjectThreadBacktrace
149//-------------------------------------------------------------------------
150
151class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152{
153public:
154
Jim Inghame2e0b452010-08-26 23:36:03 +0000155 class CommandOptions : public Options
156 {
157 public:
158
Greg Claytoneb0103f2011-04-07 22:46:35 +0000159 CommandOptions (CommandInterpreter &interpreter) :
160 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +0000161 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000162 // Keep default values of all options in one place: OptionParsingStarting ()
163 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +0000164 }
165
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000166 ~CommandOptions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000167 {
168 }
169
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000170 Error
171 SetOptionValue (uint32_t option_idx, const char *option_arg) override
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;
Vince Harron5275aaa2015-01-15 20:08:35 +0000181 int32_t input_count = StringConvert::ToSInt32 (option_arg, -1, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000182 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;
Vince Harron5275aaa2015-01-15 20:08:35 +0000193 m_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000194 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
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000214 OptionParsingStarting () override
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*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000222 GetDefinitions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000223 {
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,
Enrico Granatae87764f2015-05-27 05:04:35 +0000242 eCommandRequiresProcess |
243 eCommandRequiresThread |
244 eCommandTryTargetAPILock |
245 eCommandProcessMustBeLaunched |
246 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000247 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248 {
249 }
250
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000251 ~CommandObjectThreadBacktrace() override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 {
253 }
254
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000255 Options *
256 GetOptions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000257 {
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
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000288 bool
289 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000290 {
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
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000346 ~CommandOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347 {
348 }
349
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000350 Error
351 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352 {
353 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000354 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355
356 switch (short_option)
357 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000358 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 {
360 bool success;
Jim Ingham4b4b2472014-03-13 02:47:14 +0000361 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000363 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000364 else
365 {
366 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
367 }
368 }
369 break;
370
371 case 'A':
372 {
373 bool success;
374 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
375 if (!success)
376 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
377 else
378 {
379 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
380 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381 }
382 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000383
Jim Ingham7a88ec92014-07-08 19:28:57 +0000384 case 'c':
385 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000386 m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000387 if (m_step_count == UINT32_MAX)
388 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
389 break;
390 }
391 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000392 case 'C':
393 {
394 m_class_name.clear();
395 m_class_name.assign(option_arg);
396 }
397 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000398 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000401 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402 }
403 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000404
405 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000406 {
407 m_avoid_regexp.clear();
408 m_avoid_regexp.assign(option_arg);
409 }
410 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000411
Jim Inghamc6276822012-12-12 19:58:40 +0000412 case 't':
413 {
414 m_step_in_target.clear();
415 m_step_in_target.assign(option_arg);
416
417 }
418 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000419 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000420 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000421 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422
423 }
424 return error;
425 }
426
427 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000428 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000430 m_step_in_avoid_no_debug = eLazyBoolCalculate;
431 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432 m_run_mode = eOnlyDuringStepping;
Ewan Crawford78baa192015-05-13 09:18:18 +0000433
434 // Check if we are in Non-Stop mode
435 lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
436 if (target_sp.get() != nullptr && target_sp->GetNonStopModeEnabled())
437 m_run_mode = eOnlyThisThread;
438
Jim Inghama56c8002010-07-10 02:27:39 +0000439 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000440 m_step_in_target.clear();
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000441 m_class_name.clear();
Jim Ingham7a88ec92014-07-08 19:28:57 +0000442 m_step_count = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443 }
444
Greg Claytone0d378b2011-03-24 21:19:54 +0000445 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000446 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447 {
448 return g_option_table;
449 }
450
451 // Options table: Required for subclasses of Options.
452
Greg Claytone0d378b2011-03-24 21:19:54 +0000453 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454
455 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000456 LazyBool m_step_in_avoid_no_debug;
457 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000459 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000460 std::string m_step_in_target;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000461 std::string m_class_name;
Zachary Turner898e10e2015-01-09 20:15:21 +0000462 uint32_t m_step_count;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463 };
464
Greg Claytona7015092010-09-18 01:14:36 +0000465 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
466 const char *name,
467 const char *help,
468 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000469 StepType step_type,
470 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000471 CommandObjectParsed (interpreter, name, help, syntax,
Enrico Granatae87764f2015-05-27 05:04:35 +0000472 eCommandRequiresProcess |
473 eCommandRequiresThread |
474 eCommandTryTargetAPILock |
475 eCommandProcessMustBeLaunched |
476 eCommandProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477 m_step_type (step_type),
478 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000479 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480 {
Caroline Tice405fe672010-10-04 22:28:36 +0000481 CommandArgumentEntry arg;
482 CommandArgumentData thread_id_arg;
483
484 // Define the first (and only) variant of this arg.
485 thread_id_arg.arg_type = eArgTypeThreadID;
486 thread_id_arg.arg_repetition = eArgRepeatOptional;
487
488 // There is only one variant this argument could be; put it into the argument entry.
489 arg.push_back (thread_id_arg);
490
491 // Push the data for the first argument into the m_arguments vector.
492 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493 }
494
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000495 ~CommandObjectThreadStepWithTypeAndScope () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 {
497 }
498
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000500 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501 {
502 return &m_options;
503 }
504
Jim Ingham5a988412012-06-08 21:56:10 +0000505protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000506 bool
507 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000509 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000510 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511
Greg Claytonf9fc6092013-01-09 19:44:40 +0000512 const uint32_t num_threads = process->GetThreadList().GetSize();
513 Thread *thread = NULL;
514
515 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000517 thread = process->GetThreadList().GetSelectedThread().get();
518 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000520 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000522 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000524 }
525 else
526 {
527 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
Vince Harron5275aaa2015-01-15 20:08:35 +0000528 uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000529 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000531 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
532 result.SetStatus (eReturnStatusFailed);
533 return false;
534 }
535 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
536 if (thread == NULL)
537 {
538 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
539 step_thread_idx, num_threads);
540 result.SetStatus (eReturnStatusFailed);
541 return false;
542 }
543 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000544
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000545 if (m_step_type == eStepTypeScripted)
546 {
547 if (m_options.m_class_name.empty())
548 {
549 result.AppendErrorWithFormat ("empty class name for scripted step.");
550 result.SetStatus(eReturnStatusFailed);
551 return false;
552 }
553 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
554 {
555 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
556 result.SetStatus(eReturnStatusFailed);
557 return false;
558 }
559 }
560
Greg Claytonf9fc6092013-01-09 19:44:40 +0000561 const bool abort_other_plans = false;
562 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
563
564 // This is a bit unfortunate, but not all the commands in this command object support
565 // only while stepping, so I use the bool for them.
566 bool bool_stop_other_threads;
567 if (m_options.m_run_mode == eAllThreads)
568 bool_stop_other_threads = false;
569 else if (m_options.m_run_mode == eOnlyDuringStepping)
570 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000571 if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000572 bool_stop_other_threads = false;
573 else
574 bool_stop_other_threads = true;
575 }
576 else
577 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000578
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000579 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000580
581 if (m_step_type == eStepTypeInto)
582 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000583 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Stephane Sezerca05ae22015-03-26 17:47:34 +0000584 assert(frame != nullptr);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000585
Stephane Sezerca05ae22015-03-26 17:47:34 +0000586 if (frame->HasDebugInformation ())
Greg Claytonf9fc6092013-01-09 19:44:40 +0000587 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000588 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Jason Molenda25d5b102015-12-15 00:40:30 +0000589 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000590 frame->GetSymbolContext(eSymbolContextEverything),
591 m_options.m_step_in_target.c_str(),
592 stop_other_threads,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000593 m_options.m_step_in_avoid_no_debug,
594 m_options.m_step_out_avoid_no_debug);
595
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000596 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000597 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000598 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000599 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000600 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000601 }
602 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000603 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000604
605 }
606 else if (m_step_type == eStepTypeOver)
607 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000608 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000609
610 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000611 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Jason Molenda25d5b102015-12-15 00:40:30 +0000612 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000613 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000614 stop_other_threads,
615 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000616 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000617 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000618 abort_other_plans,
619 bool_stop_other_threads);
620
621 }
622 else if (m_step_type == eStepTypeTrace)
623 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000624 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000625 }
626 else if (m_step_type == eStepTypeTraceOver)
627 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000628 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000629 }
630 else if (m_step_type == eStepTypeOut)
631 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000632 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000633 NULL,
634 false,
635 bool_stop_other_threads,
636 eVoteYes,
637 eVoteNoOpinion,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000638 thread->GetSelectedFrameIndex(),
639 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000640 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000641 else if (m_step_type == eStepTypeScripted)
642 {
643 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
644 m_options.m_class_name.c_str(),
645 bool_stop_other_threads);
646 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000647 else
648 {
649 result.AppendError ("step type is not supported");
650 result.SetStatus (eReturnStatusFailed);
651 return false;
652 }
653
654 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
655 // so that they can be interruptible). Then resume the process.
656
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000657 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000658 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000659 new_plan_sp->SetIsMasterPlan (true);
660 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000661
662 if (m_options.m_step_count > 1)
663 {
Zachary Turner40411162014-07-16 20:28:24 +0000664 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
Jim Ingham7a88ec92014-07-08 19:28:57 +0000665 {
666 result.AppendWarning ("step operation does not support iteration count.");
667 }
668 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000669
Greg Claytondc6224e2014-10-21 01:00:42 +0000670
Greg Claytonf9fc6092013-01-09 19:44:40 +0000671 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000672
Pavel Labath44464872015-05-27 12:40:32 +0000673 const uint32_t iohandler_id = process->GetIOHandlerID();
674
Greg Claytondc6224e2014-10-21 01:00:42 +0000675 StreamString stream;
676 Error error;
677 if (synchronous_execution)
678 error = process->ResumeSynchronous (&stream);
679 else
680 error = process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000681
682 // There is a race condition where this thread will return up the call stack to the main command handler
683 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
684 // a chance to call PushProcessIOHandler().
Pavel Labath44464872015-05-27 12:40:32 +0000685 process->SyncIOHandler(iohandler_id, 2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000686
687 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000688 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000689 // If any state changed events had anything to say, add that to the result
690 if (stream.GetData())
691 result.AppendMessage(stream.GetData());
692
Greg Claytonf9fc6092013-01-09 19:44:40 +0000693 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
694 result.SetDidChangeProcessState (true);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000695 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000697 else
698 {
699 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
700 }
701 }
702 else
703 {
704 result.AppendError ("Couldn't find thread plan to implement step type.");
705 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000706 }
707 return result.Succeeded();
708 }
709
710protected:
711 StepType m_step_type;
712 StepScope m_step_scope;
713 CommandOptions m_options;
714};
715
Greg Claytone0d378b2011-03-24 21:19:54 +0000716static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000717g_tri_running_mode[] =
718{
Greg Claytoned8a7052010-09-18 03:37:20 +0000719{ eOnlyThisThread, "this-thread", "Run only this thread"},
720{ eAllThreads, "all-threads", "Run all threads"},
721{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722{ 0, NULL, NULL }
723};
724
Greg Claytone0d378b2011-03-24 21:19:54 +0000725static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000726g_duo_running_mode[] =
727{
Greg Claytoned8a7052010-09-18 03:37:20 +0000728{ eOnlyThisThread, "this-thread", "Run only this thread"},
729{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000730{ 0, NULL, NULL }
731};
732
Greg Claytone0d378b2011-03-24 21:19:54 +0000733OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
735{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000736{ 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."},
737{ 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 +0000738{ 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."},
739{ 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."},
740{ 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."},
741{ 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."},
742{ 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 +0000743{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744};
745
746
747//-------------------------------------------------------------------------
748// CommandObjectThreadContinue
749//-------------------------------------------------------------------------
750
Jim Ingham5a988412012-06-08 21:56:10 +0000751class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752{
753public:
754
Greg Claytona7015092010-09-18 01:14:36 +0000755 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000756 CommandObjectParsed (interpreter,
757 "thread continue",
758 "Continue execution of one or more threads in an active process.",
759 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +0000760 eCommandRequiresThread |
761 eCommandTryTargetAPILock |
762 eCommandProcessMustBeLaunched |
763 eCommandProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 {
Caroline Tice405fe672010-10-04 22:28:36 +0000765 CommandArgumentEntry arg;
766 CommandArgumentData thread_idx_arg;
767
768 // Define the first (and only) variant of this arg.
769 thread_idx_arg.arg_type = eArgTypeThreadIndex;
770 thread_idx_arg.arg_repetition = eArgRepeatPlus;
771
772 // There is only one variant this argument could be; put it into the argument entry.
773 arg.push_back (thread_idx_arg);
774
775 // Push the data for the first argument into the m_arguments vector.
776 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000777 }
778
779
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000780 ~CommandObjectThreadContinue () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000781 {
782 }
783
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000784 bool
785 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786 {
Greg Claytona7015092010-09-18 01:14:36 +0000787 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000788
Greg Claytona7015092010-09-18 01:14:36 +0000789 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000790 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000791 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000792 result.SetStatus (eReturnStatusFailed);
793 return false;
794 }
795
Greg Claytonf9fc6092013-01-09 19:44:40 +0000796 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000797 if (process == NULL)
798 {
799 result.AppendError ("no process exists. Cannot continue");
800 result.SetStatus (eReturnStatusFailed);
801 return false;
802 }
803
804 StateType state = process->GetState();
805 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
806 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000807 const size_t argc = command.GetArgumentCount();
808 if (argc > 0)
809 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000810 // These two lines appear at the beginning of both blocks in
811 // this if..else, but that is because we need to release the
812 // lock before calling process->Resume below.
813 Mutex::Locker locker (process->GetThreadList().GetMutex());
814 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000815 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816 for (uint32_t i=0; i<argc; ++i)
817 {
Jim Inghamce76c622012-05-31 20:48:41 +0000818 bool success;
819 const int base = 0;
Vince Harron5275aaa2015-01-15 20:08:35 +0000820 uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000821 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000822 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000823 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000824
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000825 if (thread)
826 {
827 resume_threads.push_back(thread);
828 }
829 else
830 {
831 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
832 result.SetStatus (eReturnStatusFailed);
833 return false;
834 }
Jim Inghamce76c622012-05-31 20:48:41 +0000835 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000836 else
Jim Inghamce76c622012-05-31 20:48:41 +0000837 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000838 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000839 result.SetStatus (eReturnStatusFailed);
840 return false;
841 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000843
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000844 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845 {
846 result.AppendError ("no valid thread indexes were specified");
847 result.SetStatus (eReturnStatusFailed);
848 return false;
849 }
850 else
851 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000852 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000853 result.AppendMessageWithFormat ("Resuming thread: ");
854 else
855 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000856
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000857 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000858 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000859 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
860 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000861
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000862 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000864 resume_threads.erase(this_thread_pos);
865 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000866 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
867 else
868 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000869
870 const bool override_suspend = true;
871 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000872 }
873 else
874 {
875 thread->SetResumeState (eStateSuspended);
876 }
877 }
Daniel Malead01b2952012-11-29 21:49:15 +0000878 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000879 }
880 }
881 else
882 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000883 // These two lines appear at the beginning of both blocks in
884 // this if..else, but that is because we need to release the
885 // lock before calling process->Resume below.
886 Mutex::Locker locker (process->GetThreadList().GetMutex());
887 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000888 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000889 if (current_thread == NULL)
890 {
891 result.AppendError ("the process doesn't have a current thread");
892 result.SetStatus (eReturnStatusFailed);
893 return false;
894 }
895 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000896 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000897 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000898 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000899 if (thread == current_thread)
900 {
Daniel Malead01b2952012-11-29 21:49:15 +0000901 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000902 const bool override_suspend = true;
903 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000904 }
905 else
906 {
907 thread->SetResumeState (eStateSuspended);
908 }
909 }
910 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000911
Greg Claytondc6224e2014-10-21 01:00:42 +0000912
913 StreamString stream;
914 Error error;
915 if (synchronous_execution)
916 error = process->ResumeSynchronous (&stream);
917 else
918 error = process->Resume ();
919
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000920 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921 if (error.Success())
922 {
Daniel Malead01b2952012-11-29 21:49:15 +0000923 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924 if (synchronous_execution)
925 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000926 // If any state changed events had anything to say, add that to the result
927 if (stream.GetData())
928 result.AppendMessage(stream.GetData());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000929
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000930 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931 result.SetStatus (eReturnStatusSuccessFinishNoResult);
932 }
933 else
934 {
935 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
936 }
937 }
938 else
939 {
940 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
941 result.SetStatus (eReturnStatusFailed);
942 }
943 }
944 else
945 {
946 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
947 StateAsCString(state));
948 result.SetStatus (eReturnStatusFailed);
949 }
950
951 return result.Succeeded();
952 }
953
954};
955
956//-------------------------------------------------------------------------
957// CommandObjectThreadUntil
958//-------------------------------------------------------------------------
959
Jim Ingham5a988412012-06-08 21:56:10 +0000960class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961{
962public:
963
964 class CommandOptions : public Options
965 {
966 public:
967 uint32_t m_thread_idx;
968 uint32_t m_frame_idx;
969
Greg Claytoneb0103f2011-04-07 22:46:35 +0000970 CommandOptions (CommandInterpreter &interpreter) :
971 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972 m_thread_idx(LLDB_INVALID_THREAD_ID),
973 m_frame_idx(LLDB_INVALID_FRAME_ID)
974 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000975 // Keep default values of all options in one place: OptionParsingStarting ()
976 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977 }
978
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000979 ~CommandOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000980 {
981 }
982
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000983 Error
984 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985 {
986 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000987 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988
989 switch (short_option)
990 {
Jim Ingham9bdea542015-02-06 02:10:56 +0000991 case 'a':
992 {
993 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
994 lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
995 if (error.Success())
996 m_until_addrs.push_back(tmp_addr);
997 }
998 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000999 case 't':
1000 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001001 m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002 if (m_thread_idx == LLDB_INVALID_INDEX32)
1003 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001004 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001005 }
1006 }
1007 break;
1008 case 'f':
1009 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001010 m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1012 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001013 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014 }
1015 }
1016 break;
1017 case 'm':
1018 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001020 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001021
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001022 if (error.Success())
1023 {
1024 if (run_mode == eAllThreads)
1025 m_stop_others = false;
1026 else
1027 m_stop_others = true;
1028 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 }
1030 break;
1031 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001032 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 break;
1034
1035 }
1036 return error;
1037 }
1038
1039 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001040 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001041 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 m_thread_idx = LLDB_INVALID_THREAD_ID;
1043 m_frame_idx = 0;
1044 m_stop_others = false;
Jim Ingham9bdea542015-02-06 02:10:56 +00001045 m_until_addrs.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046 }
1047
Greg Claytone0d378b2011-03-24 21:19:54 +00001048 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001049 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050 {
1051 return g_option_table;
1052 }
1053
1054 uint32_t m_step_thread_idx;
1055 bool m_stop_others;
Jim Ingham9bdea542015-02-06 02:10:56 +00001056 std::vector<lldb::addr_t> m_until_addrs;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057
1058 // Options table: Required for subclasses of Options.
1059
Greg Claytone0d378b2011-03-24 21:19:54 +00001060 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061
1062 // Instance variables to hold the values for command options.
1063 };
1064
Greg Claytona7015092010-09-18 01:14:36 +00001065 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001066 CommandObjectParsed (interpreter,
1067 "thread until",
Jim Ingham9bdea542015-02-06 02:10:56 +00001068 "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
Jim Ingham5a988412012-06-08 21:56:10 +00001069 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00001070 eCommandRequiresThread |
1071 eCommandTryTargetAPILock |
1072 eCommandProcessMustBeLaunched |
1073 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001074 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001075 {
Caroline Tice405fe672010-10-04 22:28:36 +00001076 CommandArgumentEntry arg;
1077 CommandArgumentData line_num_arg;
1078
1079 // Define the first (and only) variant of this arg.
1080 line_num_arg.arg_type = eArgTypeLineNum;
1081 line_num_arg.arg_repetition = eArgRepeatPlain;
1082
1083 // There is only one variant this argument could be; put it into the argument entry.
1084 arg.push_back (line_num_arg);
1085
1086 // Push the data for the first argument into the m_arguments vector.
1087 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001088 }
1089
1090
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001091 ~CommandObjectThreadUntil () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001092 {
1093 }
1094
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001096 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097 {
1098 return &m_options;
1099 }
1100
Jim Ingham5a988412012-06-08 21:56:10 +00001101protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001102 bool
1103 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 {
Greg Claytona7015092010-09-18 01:14:36 +00001105 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106
Greg Claytona7015092010-09-18 01:14:36 +00001107 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +00001108 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001109 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001110 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111 result.SetStatus (eReturnStatusFailed);
1112 return false;
1113 }
1114
Greg Claytonf9fc6092013-01-09 19:44:40 +00001115 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116 if (process == NULL)
1117 {
1118 result.AppendError ("need a valid process to step");
1119 result.SetStatus (eReturnStatusFailed);
1120
1121 }
1122 else
1123 {
1124 Thread *thread = NULL;
Jim Ingham9bdea542015-02-06 02:10:56 +00001125 std::vector<uint32_t> line_numbers;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126
Jim Ingham9bdea542015-02-06 02:10:56 +00001127 if (command.GetArgumentCount() >= 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001128 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001129 size_t num_args = command.GetArgumentCount();
1130 for (size_t i = 0; i < num_args; i++)
1131 {
1132 uint32_t line_number;
1133 line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1134 if (line_number == UINT32_MAX)
1135 {
1136 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1137 result.SetStatus (eReturnStatusFailed);
1138 return false;
1139 }
1140 else
1141 line_numbers.push_back(line_number);
1142 }
1143 }
1144 else if (m_options.m_until_addrs.empty())
1145 {
1146 result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147 result.SetStatus (eReturnStatusFailed);
1148 return false;
1149 }
1150
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001151
1152 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1153 {
Jim Ingham2976d002010-08-26 21:32:51 +00001154 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001155 }
1156 else
1157 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001158 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001159 }
1160
1161 if (thread == NULL)
1162 {
1163 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001164 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1165 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001166 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 result.SetStatus (eReturnStatusFailed);
1168 return false;
1169 }
1170
Jim Ingham7ba6e992012-05-11 23:47:32 +00001171 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172
Jason Molendab57e4a12013-11-04 09:33:30 +00001173 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 if (frame == NULL)
1175 {
1176
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001177 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1178 m_options.m_frame_idx,
1179 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 result.SetStatus (eReturnStatusFailed);
1181 return false;
1182 }
1183
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001184 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185
1186 if (frame->HasDebugInformation ())
1187 {
1188 // Finally we got here... Translate the given line number to a bunch of addresses:
1189 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1190 LineTable *line_table = NULL;
1191 if (sc.comp_unit)
1192 line_table = sc.comp_unit->GetLineTable();
1193
1194 if (line_table == NULL)
1195 {
1196 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1197 m_options.m_frame_idx, m_options.m_thread_idx);
1198 result.SetStatus (eReturnStatusFailed);
1199 return false;
1200 }
1201
1202 LineEntry function_start;
1203 uint32_t index_ptr = 0, end_ptr;
1204 std::vector<addr_t> address_list;
1205
1206 // Find the beginning & end index of the
1207 AddressRange fun_addr_range = sc.function->GetAddressRange();
1208 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1209 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1210
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001211 Address fun_end_addr(fun_start_addr.GetSection(),
1212 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001214 bool all_in_function = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001215
Jim Ingham9bdea542015-02-06 02:10:56 +00001216 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1217
1218 for (uint32_t line_number : line_numbers)
1219 {
1220 uint32_t start_idx_ptr = index_ptr;
1221 while (start_idx_ptr <= end_ptr)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001222 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001223 LineEntry line_entry;
1224 const bool exact = false;
1225 start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
1226 if (start_idx_ptr == UINT32_MAX)
1227 break;
1228
1229 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1230 if (address != LLDB_INVALID_ADDRESS)
1231 {
1232 if (fun_addr_range.ContainsLoadAddress (address, target))
1233 address_list.push_back (address);
1234 else
1235 all_in_function = false;
1236 }
1237 start_idx_ptr++;
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001238 }
Jim Ingham9bdea542015-02-06 02:10:56 +00001239 }
1240
1241 for (lldb::addr_t address : m_options.m_until_addrs)
1242 {
1243 if (fun_addr_range.ContainsLoadAddress (address, target))
1244 address_list.push_back (address);
1245 else
1246 all_in_function = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247 }
1248
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001249 if (address_list.size() == 0)
1250 {
1251 if (all_in_function)
1252 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1253 else
1254 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1255
1256 result.SetStatus (eReturnStatusFailed);
1257 return false;
1258 }
1259
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001260 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001261 &address_list.front(),
1262 address_list.size(),
1263 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001264 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001265 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1266 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1267 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001268 new_plan_sp->SetIsMasterPlan (true);
1269 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001270 }
1271 else
1272 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001273 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1274 m_options.m_frame_idx,
1275 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001276 result.SetStatus (eReturnStatusFailed);
1277 return false;
1278
1279 }
1280
Greg Claytondc6224e2014-10-21 01:00:42 +00001281
1282
Jim Ingham2976d002010-08-26 21:32:51 +00001283 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Greg Claytondc6224e2014-10-21 01:00:42 +00001284
1285 StreamString stream;
1286 Error error;
1287 if (synchronous_execution)
1288 error = process->ResumeSynchronous (&stream);
1289 else
1290 error = process->Resume ();
1291
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001292 if (error.Success())
1293 {
Daniel Malead01b2952012-11-29 21:49:15 +00001294 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295 if (synchronous_execution)
1296 {
Greg Claytondc6224e2014-10-21 01:00:42 +00001297 // If any state changed events had anything to say, add that to the result
1298 if (stream.GetData())
1299 result.AppendMessage(stream.GetData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300
1301 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1303 }
1304 else
1305 {
1306 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1307 }
1308 }
1309 else
1310 {
1311 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1312 result.SetStatus (eReturnStatusFailed);
1313 }
1314
1315 }
1316 return result.Succeeded();
1317 }
Jim Ingham5a988412012-06-08 21:56:10 +00001318
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319 CommandOptions m_options;
1320
1321};
1322
Greg Claytone0d378b2011-03-24 21:19:54 +00001323OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001324CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1325{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001326{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1327{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
Jim Ingham9bdea542015-02-06 02:10:56 +00001328{ 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"},
1329{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."},
Zachary Turnerd37221d2014-07-09 16:31:49 +00001330{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001331};
1332
1333
1334//-------------------------------------------------------------------------
1335// CommandObjectThreadSelect
1336//-------------------------------------------------------------------------
1337
Jim Ingham5a988412012-06-08 21:56:10 +00001338class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339{
1340public:
1341
Greg Claytona7015092010-09-18 01:14:36 +00001342 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001343 CommandObjectParsed (interpreter,
1344 "thread select",
1345 "Select a thread as the currently active thread.",
1346 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00001347 eCommandRequiresProcess |
1348 eCommandTryTargetAPILock |
1349 eCommandProcessMustBeLaunched |
1350 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001351 {
Caroline Tice405fe672010-10-04 22:28:36 +00001352 CommandArgumentEntry arg;
1353 CommandArgumentData thread_idx_arg;
1354
1355 // Define the first (and only) variant of this arg.
1356 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1357 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1358
1359 // There is only one variant this argument could be; put it into the argument entry.
1360 arg.push_back (thread_idx_arg);
1361
1362 // Push the data for the first argument into the m_arguments vector.
1363 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001364 }
1365
1366
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001367 ~CommandObjectThreadSelect () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001368 {
1369 }
1370
Jim Ingham5a988412012-06-08 21:56:10 +00001371protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001372 bool
1373 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001374 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001375 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001376 if (process == NULL)
1377 {
1378 result.AppendError ("no process");
1379 result.SetStatus (eReturnStatusFailed);
1380 return false;
1381 }
1382 else if (command.GetArgumentCount() != 1)
1383 {
Jason Molendafd54b362011-09-20 21:44:10 +00001384 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 +00001385 result.SetStatus (eReturnStatusFailed);
1386 return false;
1387 }
1388
Vince Harron5275aaa2015-01-15 20:08:35 +00001389 uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001390
1391 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1392 if (new_thread == NULL)
1393 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001394 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001395 result.SetStatus (eReturnStatusFailed);
1396 return false;
1397 }
1398
Jim Inghamc3faa192012-12-11 02:31:48 +00001399 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001400 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001401
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001402 return result.Succeeded();
1403 }
1404
1405};
1406
1407
1408//-------------------------------------------------------------------------
1409// CommandObjectThreadList
1410//-------------------------------------------------------------------------
1411
Jim Ingham5a988412012-06-08 21:56:10 +00001412class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001413{
Greg Clayton66111032010-06-23 01:19:29 +00001414public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001415
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001416
Greg Claytona7015092010-09-18 01:14:36 +00001417 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001418 CommandObjectParsed (interpreter,
1419 "thread list",
1420 "Show a summary of all current threads in a process.",
1421 "thread list",
Enrico Granatae87764f2015-05-27 05:04:35 +00001422 eCommandRequiresProcess |
1423 eCommandTryTargetAPILock |
1424 eCommandProcessMustBeLaunched |
1425 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001426 {
Greg Clayton66111032010-06-23 01:19:29 +00001427 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001428
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001429 ~CommandObjectThreadList() override
Greg Clayton66111032010-06-23 01:19:29 +00001430 {
1431 }
1432
Jim Ingham5a988412012-06-08 21:56:10 +00001433protected:
Greg Clayton66111032010-06-23 01:19:29 +00001434 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001435 DoExecute (Args& command, CommandReturnObject &result) override
Greg Clayton66111032010-06-23 01:19:29 +00001436 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001437 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001438 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001439 Process *process = m_exe_ctx.GetProcessPtr();
1440 const bool only_threads_with_stop_reason = false;
1441 const uint32_t start_frame = 0;
1442 const uint32_t num_frames = 0;
1443 const uint32_t num_frames_with_source = 0;
1444 process->GetStatus(strm);
1445 process->GetThreadStatus (strm,
1446 only_threads_with_stop_reason,
1447 start_frame,
1448 num_frames,
1449 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001450 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001451 }
Greg Clayton66111032010-06-23 01:19:29 +00001452};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001453
Jim Ingham93208b82013-01-31 21:46:01 +00001454//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001455// CommandObjectThreadInfo
1456//-------------------------------------------------------------------------
1457
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001458class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001459{
1460public:
1461
1462 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001463 CommandObjectIterateOverThreads (interpreter,
1464 "thread info",
1465 "Show an extended summary of information about thread(s) in a process.",
1466 "thread info",
Enrico Granatae87764f2015-05-27 05:04:35 +00001467 eCommandRequiresProcess |
1468 eCommandTryTargetAPILock |
1469 eCommandProcessMustBeLaunched |
1470 eCommandProcessMustBePaused),
Jason Molenda705b1802014-06-13 02:37:02 +00001471 m_options (interpreter)
1472 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001473 m_add_return = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001474 }
1475
1476 class CommandOptions : public Options
1477 {
1478 public:
1479
1480 CommandOptions (CommandInterpreter &interpreter) :
1481 Options (interpreter)
1482 {
1483 OptionParsingStarting ();
1484 }
1485
1486 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001487 OptionParsingStarting () override
Jason Molenda705b1802014-06-13 02:37:02 +00001488 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001489 m_json_thread = false;
1490 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001491 }
1492
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001493 ~CommandOptions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001494 {
1495 }
1496
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001497 Error
1498 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jason Molenda705b1802014-06-13 02:37:02 +00001499 {
1500 const int short_option = m_getopt_table[option_idx].val;
1501 Error error;
1502
1503 switch (short_option)
1504 {
1505 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001506 m_json_thread = true;
1507 break;
1508
1509 case 's':
1510 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001511 break;
1512
Kuba Breckaafdf8422014-10-10 23:43:03 +00001513 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001514 return Error("invalid short option character '%c'", short_option);
1515
1516 }
1517 return error;
1518 }
1519
1520 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001521 GetDefinitions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001522 {
1523 return g_option_table;
1524 }
1525
Kuba Breckaafdf8422014-10-10 23:43:03 +00001526 bool m_json_thread;
1527 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001528
1529 static OptionDefinition g_option_table[];
1530 };
1531
Jason Molenda705b1802014-06-13 02:37:02 +00001532 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001533 GetOptions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001534 {
1535 return &m_options;
1536 }
1537
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001538 ~CommandObjectThreadInfo () override
Jason Molenda705b1802014-06-13 02:37:02 +00001539 {
1540 }
1541
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001542 bool
1543 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jason Molenda705b1802014-06-13 02:37:02 +00001544 {
Jason Molenda705b1802014-06-13 02:37:02 +00001545 Stream &strm = result.GetOutputStream();
Kuba Breckaafdf8422014-10-10 23:43:03 +00001546 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
Jason Molenda705b1802014-06-13 02:37:02 +00001547 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001548 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1549 result.SetStatus (eReturnStatusFailed);
1550 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001551 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001552 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001553 }
1554
1555 CommandOptions m_options;
1556
1557};
1558
1559OptionDefinition
1560CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1561{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001562 { 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 +00001563 { 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 +00001564
Zachary Turnerd37221d2014-07-09 16:31:49 +00001565 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jason Molenda705b1802014-06-13 02:37:02 +00001566};
1567
1568
1569//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001570// CommandObjectThreadReturn
1571//-------------------------------------------------------------------------
1572
Jim Inghamcb640dd2012-09-14 02:14:15 +00001573class CommandObjectThreadReturn : public CommandObjectRaw
1574{
1575public:
Jim Ingham93208b82013-01-31 21:46:01 +00001576 class CommandOptions : public Options
1577 {
1578 public:
1579
1580 CommandOptions (CommandInterpreter &interpreter) :
1581 Options (interpreter),
1582 m_from_expression (false)
1583 {
1584 // Keep default values of all options in one place: OptionParsingStarting ()
1585 OptionParsingStarting ();
1586 }
1587
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001588 ~CommandOptions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001589 {
1590 }
1591
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001592 Error
1593 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham93208b82013-01-31 21:46:01 +00001594 {
1595 Error error;
1596 const int short_option = m_getopt_table[option_idx].val;
1597
1598 switch (short_option)
1599 {
1600 case 'x':
1601 {
1602 bool success;
1603 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1604 if (success)
1605 m_from_expression = tmp_value;
1606 else
1607 {
1608 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1609 }
1610 }
1611 break;
1612 default:
1613 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1614 break;
1615
1616 }
1617 return error;
1618 }
1619
1620 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001621 OptionParsingStarting () override
Jim Ingham93208b82013-01-31 21:46:01 +00001622 {
1623 m_from_expression = false;
1624 }
1625
1626 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001627 GetDefinitions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001628 {
1629 return g_option_table;
1630 }
1631
1632 bool m_from_expression;
1633
1634 // Options table: Required for subclasses of Options.
1635
1636 static OptionDefinition g_option_table[];
1637
1638 // Instance variables to hold the values for command options.
1639 };
1640
Jim Ingham93208b82013-01-31 21:46:01 +00001641 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001642 GetOptions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001643 {
1644 return &m_options;
1645 }
1646
Jim Inghamcb640dd2012-09-14 02:14:15 +00001647 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1648 CommandObjectRaw (interpreter,
1649 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001650 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1651 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001652 "thread return",
Enrico Granatae87764f2015-05-27 05:04:35 +00001653 eCommandRequiresFrame |
1654 eCommandTryTargetAPILock |
1655 eCommandProcessMustBeLaunched |
1656 eCommandProcessMustBePaused ),
Jim Ingham93208b82013-01-31 21:46:01 +00001657 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001658 {
1659 CommandArgumentEntry arg;
1660 CommandArgumentData expression_arg;
1661
1662 // Define the first (and only) variant of this arg.
1663 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001664 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001665
1666 // There is only one variant this argument could be; put it into the argument entry.
1667 arg.push_back (expression_arg);
1668
1669 // Push the data for the first argument into the m_arguments vector.
1670 m_arguments.push_back (arg);
1671
1672
1673 }
1674
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001675 ~CommandObjectThreadReturn() override
Jim Inghamcb640dd2012-09-14 02:14:15 +00001676 {
1677 }
1678
1679protected:
1680
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001681 bool
1682 DoExecute (const char *command, CommandReturnObject &result) override
Jim Inghamcb640dd2012-09-14 02:14:15 +00001683 {
Jim Ingham93208b82013-01-31 21:46:01 +00001684 // I am going to handle this by hand, because I don't want you to have to say:
1685 // "thread return -- -5".
1686 if (command[0] == '-' && command[1] == 'x')
1687 {
1688 if (command && command[2] != '\0')
1689 result.AppendWarning("Return values ignored when returning from user called expressions");
1690
1691 Thread *thread = m_exe_ctx.GetThreadPtr();
1692 Error error;
1693 error = thread->UnwindInnermostExpression();
1694 if (!error.Success())
1695 {
1696 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1697 result.SetStatus (eReturnStatusFailed);
1698 }
1699 else
1700 {
1701 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1702 if (success)
1703 {
1704 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1705 result.SetStatus (eReturnStatusSuccessFinishResult);
1706 }
1707 else
1708 {
1709 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1710 result.SetStatus (eReturnStatusFailed);
1711 }
1712 }
1713 return result.Succeeded();
1714 }
1715
Jim Inghamcb640dd2012-09-14 02:14:15 +00001716 ValueObjectSP return_valobj_sp;
1717
Jason Molendab57e4a12013-11-04 09:33:30 +00001718 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001719 uint32_t frame_idx = frame_sp->GetFrameIndex();
1720
1721 if (frame_sp->IsInlined())
1722 {
1723 result.AppendError("Don't know how to return from inlined frames.");
1724 result.SetStatus (eReturnStatusFailed);
1725 return false;
1726 }
1727
1728 if (command && command[0] != '\0')
1729 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001730 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001731 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001732
1733 options.SetUnwindOnError(true);
1734 options.SetUseDynamic(eNoDynamicValues);
1735
Jim Ingham8646d3c2014-05-05 02:47:44 +00001736 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001737 exe_results = target->EvaluateExpression (command,
1738 frame_sp.get(),
1739 return_valobj_sp,
1740 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001741 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001742 {
1743 if (return_valobj_sp)
1744 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1745 else
1746 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1747 result.SetStatus (eReturnStatusFailed);
1748 return false;
1749
1750 }
1751 }
1752
1753 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001754 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001755 const bool broadcast = true;
1756 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001757 if (!error.Success())
1758 {
1759 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1760 result.SetStatus (eReturnStatusFailed);
1761 return false;
1762 }
1763
Jim Inghamcb640dd2012-09-14 02:14:15 +00001764 result.SetStatus (eReturnStatusSuccessFinishResult);
1765 return true;
1766 }
Jim Ingham93208b82013-01-31 21:46:01 +00001767
1768 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001769
1770};
Jim Ingham93208b82013-01-31 21:46:01 +00001771OptionDefinition
1772CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1773{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001774{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1775{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham93208b82013-01-31 21:46:01 +00001776};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001777
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001778//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001779// CommandObjectThreadJump
1780//-------------------------------------------------------------------------
1781
1782class CommandObjectThreadJump : public CommandObjectParsed
1783{
1784public:
1785 class CommandOptions : public Options
1786 {
1787 public:
1788
1789 CommandOptions (CommandInterpreter &interpreter) :
1790 Options (interpreter)
1791 {
1792 OptionParsingStarting ();
1793 }
1794
1795 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001796 OptionParsingStarting () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001797 {
1798 m_filenames.Clear();
1799 m_line_num = 0;
1800 m_line_offset = 0;
1801 m_load_addr = LLDB_INVALID_ADDRESS;
1802 m_force = false;
1803 }
1804
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001805 ~CommandOptions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001806 {
1807 }
1808
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001809 Error
1810 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001811 {
1812 bool success;
1813 const int short_option = m_getopt_table[option_idx].val;
1814 Error error;
1815
1816 switch (short_option)
1817 {
1818 case 'f':
1819 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1820 if (m_filenames.GetSize() > 1)
1821 return Error("only one source file expected.");
1822 break;
1823 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001824 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001825 if (!success || m_line_num == 0)
1826 return Error("invalid line number: '%s'.", option_arg);
1827 break;
1828 case 'b':
Vince Harron5275aaa2015-01-15 20:08:35 +00001829 m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001830 if (!success)
1831 return Error("invalid line offset: '%s'.", option_arg);
1832 break;
1833 case 'a':
1834 {
1835 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1836 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1837 }
1838 break;
1839 case 'r':
1840 m_force = true;
1841 break;
1842
1843 default:
1844 return Error("invalid short option character '%c'", short_option);
1845
1846 }
1847 return error;
1848 }
1849
1850 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001851 GetDefinitions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001852 {
1853 return g_option_table;
1854 }
1855
1856 FileSpecList m_filenames;
1857 uint32_t m_line_num;
1858 int32_t m_line_offset;
1859 lldb::addr_t m_load_addr;
1860 bool m_force;
1861
1862 static OptionDefinition g_option_table[];
1863 };
1864
Richard Mittonf86248d2013-09-12 02:20:34 +00001865 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001866 GetOptions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001867 {
1868 return &m_options;
1869 }
1870
1871 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1872 CommandObjectParsed (interpreter,
1873 "thread jump",
1874 "Sets the program counter to a new address.",
1875 "thread jump",
Enrico Granatae87764f2015-05-27 05:04:35 +00001876 eCommandRequiresFrame |
1877 eCommandTryTargetAPILock |
1878 eCommandProcessMustBeLaunched |
1879 eCommandProcessMustBePaused ),
Richard Mittonf86248d2013-09-12 02:20:34 +00001880 m_options (interpreter)
1881 {
1882 }
1883
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001884 ~CommandObjectThreadJump() override
Richard Mittonf86248d2013-09-12 02:20:34 +00001885 {
1886 }
1887
1888protected:
1889
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001890 bool DoExecute (Args& args, CommandReturnObject &result) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001891 {
1892 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001893 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001894 Thread *thread = m_exe_ctx.GetThreadPtr();
1895 Target *target = m_exe_ctx.GetTargetPtr();
1896 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1897
1898 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1899 {
1900 // Use this address directly.
1901 Address dest = Address(m_options.m_load_addr);
1902
1903 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1904 if (callAddr == LLDB_INVALID_ADDRESS)
1905 {
1906 result.AppendErrorWithFormat ("Invalid destination address.");
1907 result.SetStatus (eReturnStatusFailed);
1908 return false;
1909 }
1910
1911 if (!reg_ctx->SetPC (callAddr))
1912 {
1913 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1914 result.SetStatus (eReturnStatusFailed);
1915 return false;
1916 }
1917 }
1918 else
1919 {
1920 // Pick either the absolute line, or work out a relative one.
1921 int32_t line = (int32_t)m_options.m_line_num;
1922 if (line == 0)
1923 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1924
1925 // Try the current file, but override if asked.
1926 FileSpec file = sym_ctx.line_entry.file;
1927 if (m_options.m_filenames.GetSize() == 1)
1928 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1929
1930 if (!file)
1931 {
1932 result.AppendErrorWithFormat ("No source file available for the current location.");
1933 result.SetStatus (eReturnStatusFailed);
1934 return false;
1935 }
1936
1937 std::string warnings;
1938 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1939
1940 if (err.Fail())
1941 {
1942 result.SetError (err);
1943 return false;
1944 }
1945
1946 if (!warnings.empty())
1947 result.AppendWarning (warnings.c_str());
1948 }
1949
1950 result.SetStatus (eReturnStatusSuccessFinishResult);
1951 return true;
1952 }
1953
1954 CommandOptions m_options;
1955};
1956OptionDefinition
1957CommandObjectThreadJump::CommandOptions::g_option_table[] =
1958{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001959 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001960 "Specifies the source file to jump to."},
1961
Zachary Turnerd37221d2014-07-09 16:31:49 +00001962 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001963 "Specifies the line number to jump to."},
1964
Zachary Turnerd37221d2014-07-09 16:31:49 +00001965 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001966 "Jumps by a relative line offset from the current line."},
1967
Zachary Turnerd37221d2014-07-09 16:31:49 +00001968 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001969 "Jumps to a specific address."},
1970
1971 { LLDB_OPT_SET_1|
1972 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +00001973 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 +00001974
Zachary Turnerd37221d2014-07-09 16:31:49 +00001975 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Richard Mittonf86248d2013-09-12 02:20:34 +00001976};
1977
1978//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001979// Next are the subcommands of CommandObjectMultiwordThreadPlan
1980//-------------------------------------------------------------------------
1981
1982
1983//-------------------------------------------------------------------------
1984// CommandObjectThreadPlanList
1985//-------------------------------------------------------------------------
1986class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1987{
1988public:
1989
1990 class CommandOptions : public Options
1991 {
1992 public:
1993
1994 CommandOptions (CommandInterpreter &interpreter) :
1995 Options(interpreter)
1996 {
1997 // Keep default values of all options in one place: OptionParsingStarting ()
1998 OptionParsingStarting ();
1999 }
2000
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002001 ~CommandOptions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002002 {
2003 }
2004
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002005 Error
2006 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002007 {
2008 Error error;
2009 const int short_option = m_getopt_table[option_idx].val;
2010
2011 switch (short_option)
2012 {
2013 case 'i':
2014 {
2015 m_internal = true;
2016 }
2017 break;
2018 case 'v':
2019 {
2020 m_verbose = true;
2021 }
2022 break;
2023 default:
2024 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2025 break;
2026
2027 }
2028 return error;
2029 }
2030
2031 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002032 OptionParsingStarting () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002033 {
2034 m_verbose = false;
2035 m_internal = false;
2036 }
2037
2038 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002039 GetDefinitions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002040 {
2041 return g_option_table;
2042 }
2043
2044 // Options table: Required for subclasses of Options.
2045
2046 static OptionDefinition g_option_table[];
2047
2048 // Instance variables to hold the values for command options.
2049 bool m_verbose;
2050 bool m_internal;
2051 };
2052
2053 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
2054 CommandObjectIterateOverThreads (interpreter,
2055 "thread plan list",
2056 "Show thread plans for one or more threads. If no threads are specified, show the "
2057 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2058 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00002059 eCommandRequiresProcess |
2060 eCommandRequiresThread |
2061 eCommandTryTargetAPILock |
2062 eCommandProcessMustBeLaunched |
2063 eCommandProcessMustBePaused ),
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002064 m_options(interpreter)
2065 {
2066 }
2067
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002068 ~CommandObjectThreadPlanList () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002069 {
2070 }
2071
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002072 Options *
2073 GetOptions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002074 {
2075 return &m_options;
2076 }
2077
2078protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002079 bool
2080 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002081 {
2082 Stream &strm = result.GetOutputStream();
2083 DescriptionLevel desc_level = eDescriptionLevelFull;
2084 if (m_options.m_verbose)
2085 desc_level = eDescriptionLevelVerbose;
2086
2087 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2088 return true;
2089 }
2090 CommandOptions m_options;
2091};
2092
2093OptionDefinition
2094CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2095{
2096{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
2097{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2098{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2099};
2100
2101class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2102{
2103public:
2104 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
2105 CommandObjectParsed (interpreter,
2106 "thread plan discard",
2107 "Discards thread plans up to and including the plan passed as the command argument."
2108 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2109 " without the \"-i\" argument.",
2110 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00002111 eCommandRequiresProcess |
2112 eCommandRequiresThread |
2113 eCommandTryTargetAPILock |
2114 eCommandProcessMustBeLaunched |
2115 eCommandProcessMustBePaused )
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002116 {
2117 CommandArgumentEntry arg;
2118 CommandArgumentData plan_index_arg;
2119
2120 // Define the first (and only) variant of this arg.
2121 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2122 plan_index_arg.arg_repetition = eArgRepeatPlain;
2123
2124 // There is only one variant this argument could be; put it into the argument entry.
2125 arg.push_back (plan_index_arg);
2126
2127 // Push the data for the first argument into the m_arguments vector.
2128 m_arguments.push_back (arg);
2129 }
2130
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002131 ~CommandObjectThreadPlanDiscard () override {}
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002132
2133 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002134 DoExecute (Args& args, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002135 {
2136 Thread *thread = m_exe_ctx.GetThreadPtr();
2137 if (args.GetArgumentCount() != 1)
2138 {
2139 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2140 args.GetArgumentCount());
2141 result.SetStatus (eReturnStatusFailed);
2142 return false;
2143 }
2144
2145 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00002146 uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002147 if (!success)
2148 {
2149 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2150 args.GetArgumentAtIndex(0));
2151 result.SetStatus (eReturnStatusFailed);
2152 return false;
2153 }
2154
2155 if (thread_plan_idx == 0)
2156 {
2157 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2158 result.SetStatus (eReturnStatusFailed);
2159 return false;
2160 }
2161
2162 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2163 {
2164 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2165 return true;
2166 }
2167 else
2168 {
2169 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2170 args.GetArgumentAtIndex(0));
2171 result.SetStatus (eReturnStatusFailed);
2172 return false;
2173 }
2174 }
2175};
2176
2177//-------------------------------------------------------------------------
2178// CommandObjectMultiwordThreadPlan
2179//-------------------------------------------------------------------------
2180
2181class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2182{
2183public:
2184 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2185 CommandObjectMultiword (interpreter,
2186 "plan",
2187 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2188 "thread plan <subcommand> [<subcommand objects]")
2189 {
2190 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2191 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2192 }
2193
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002194 ~CommandObjectMultiwordThreadPlan () override {}
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002195
2196
2197};
2198
2199//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002200// CommandObjectMultiwordThread
2201//-------------------------------------------------------------------------
2202
Greg Clayton66111032010-06-23 01:19:29 +00002203CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002204 CommandObjectMultiword (interpreter,
2205 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002206 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002207 "thread <subcommand> [<subcommand-options>]")
2208{
Greg Claytona7015092010-09-18 01:14:36 +00002209 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2210 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2211 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002212 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002213 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002214 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2215 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002216 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002217 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2218 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002219 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002220 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002221 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002222 eStepTypeInto,
2223 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00002224
Greg Claytona7015092010-09-18 01:14:36 +00002225 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2226 interpreter,
2227 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002228 "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 +00002229 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002230 eStepTypeOut,
2231 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002232
Greg Claytona7015092010-09-18 01:14:36 +00002233 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2234 interpreter,
2235 "thread step-over",
2236 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002237 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002238 eStepTypeOver,
2239 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002240
Greg Claytona7015092010-09-18 01:14:36 +00002241 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2242 interpreter,
2243 "thread step-inst",
2244 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002245 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002246 eStepTypeTrace,
2247 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002248
Greg Claytona7015092010-09-18 01:14:36 +00002249 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2250 interpreter,
2251 "thread step-inst-over",
2252 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002253 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002254 eStepTypeTraceOver,
2255 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002256
2257 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2258 interpreter,
2259 "thread step-scripted",
2260 "Step as instructed by the script class passed in the -C option.",
2261 NULL,
2262 eStepTypeScripted,
2263 eStepScopeSource)));
2264
2265 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002266}
2267
2268CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
2269{
2270}
2271
2272