blob: 27f1ebab801c7b0b7729274eedc51c8d97f3cbf3 [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 }
Jim Ingham1f5fcf82016-02-06 00:31:23 +0000197 break;
Jason Molenda750ea692013-11-12 07:02:07 +0000198 case 'e':
199 {
200 bool success;
201 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
202 if (!success)
203 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
204 }
Jim Inghame2e0b452010-08-26 23:36:03 +0000205 break;
206 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000207 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000208 break;
209
210 }
211 return error;
212 }
213
214 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000215 OptionParsingStarting () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000216 {
Greg Clayton7260f622011-04-18 08:33:37 +0000217 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000218 m_start = 0;
Jason Molenda750ea692013-11-12 07:02:07 +0000219 m_extended_backtrace = false;
Jim Inghame2e0b452010-08-26 23:36:03 +0000220 }
221
Greg Claytone0d378b2011-03-24 21:19:54 +0000222 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000223 GetDefinitions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000224 {
225 return g_option_table;
226 }
227
228 // Options table: Required for subclasses of Options.
229
Greg Claytone0d378b2011-03-24 21:19:54 +0000230 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000231
232 // Instance variables to hold the values for command options.
233 uint32_t m_count;
234 uint32_t m_start;
Jason Molenda750ea692013-11-12 07:02:07 +0000235 bool m_extended_backtrace;
Jim Inghame2e0b452010-08-26 23:36:03 +0000236 };
237
Greg Claytona7015092010-09-18 01:14:36 +0000238 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000239 CommandObjectIterateOverThreads (interpreter,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000240 "thread backtrace",
241 "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.",
242 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +0000243 eCommandRequiresProcess |
244 eCommandRequiresThread |
245 eCommandTryTargetAPILock |
246 eCommandProcessMustBeLaunched |
247 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000248 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 {
250 }
251
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000252 ~CommandObjectThreadBacktrace() override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253 {
254 }
255
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000256 Options *
257 GetOptions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000258 {
259 return &m_options;
260 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261
Jim Ingham5a988412012-06-08 21:56:10 +0000262protected:
Jason Molenda750ea692013-11-12 07:02:07 +0000263 void
264 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
265 {
266 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
267 if (runtime)
268 {
269 Stream &strm = result.GetOutputStream();
270 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
271 for (auto type : types)
272 {
Jason Molenda008c45f2013-11-12 23:33:32 +0000273 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
Jason Molenda750ea692013-11-12 07:02:07 +0000274 if (ext_thread_sp && ext_thread_sp->IsValid ())
275 {
276 const uint32_t num_frames_with_source = 0;
277 if (ext_thread_sp->GetStatus (strm,
278 m_options.m_start,
279 m_options.m_count,
280 num_frames_with_source))
281 {
282 DoExtendedBacktrace (ext_thread_sp.get(), result);
283 }
284 }
285 }
286 }
287 }
288
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000289 bool
290 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000291 {
Greg Clayton7260f622011-04-18 08:33:37 +0000292 Stream &strm = result.GetOutputStream();
293
294 // Don't show source context when doing backtraces.
295 const uint32_t num_frames_with_source = 0;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000296
297 if (!thread.GetStatus (strm,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000298 m_options.m_start,
299 m_options.m_count,
300 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000301 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000302 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID());
303 result.SetStatus (eReturnStatusFailed);
304 return false;
Jim Ingham09b263e2010-08-27 00:58:05 +0000305 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000306 if (m_options.m_extended_backtrace)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000308 DoExtendedBacktrace (&thread, result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000310
311 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312 }
Jim Ingham5a988412012-06-08 21:56:10 +0000313
Jim Inghame2e0b452010-08-26 23:36:03 +0000314 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315};
316
Greg Claytone0d378b2011-03-24 21:19:54 +0000317OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000318CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
319{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000320{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
321{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
322{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
323{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghame2e0b452010-08-26 23:36:03 +0000324};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325
Greg Clayton69b518f2010-07-07 17:07:17 +0000326enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327{
328 eStepScopeSource,
329 eStepScopeInstruction
330};
331
Jim Ingham5a988412012-06-08 21:56:10 +0000332class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333{
334public:
335
336 class CommandOptions : public Options
337 {
338 public:
339
Greg Claytoneb0103f2011-04-07 22:46:35 +0000340 CommandOptions (CommandInterpreter &interpreter) :
341 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000343 // Keep default values of all options in one place: OptionParsingStarting ()
344 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 }
346
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000347 ~CommandOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 {
349 }
350
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000351 Error
352 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 {
354 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000355 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356
357 switch (short_option)
358 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000359 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360 {
361 bool success;
Jim Ingham4b4b2472014-03-13 02:47:14 +0000362 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000364 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000365 else
366 {
367 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
368 }
369 }
370 break;
371
372 case 'A':
373 {
374 bool success;
375 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
376 if (!success)
377 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
378 else
379 {
380 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
381 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 }
383 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000384
Jim Ingham7a88ec92014-07-08 19:28:57 +0000385 case 'c':
386 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000387 m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000388 if (m_step_count == UINT32_MAX)
389 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
390 break;
391 }
392 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000393 case 'C':
394 {
395 m_class_name.clear();
396 m_class_name.assign(option_arg);
397 }
398 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000399 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000402 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 }
404 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000405
406 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000407 {
408 m_avoid_regexp.clear();
409 m_avoid_regexp.assign(option_arg);
410 }
411 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000412
Jim Inghamc6276822012-12-12 19:58:40 +0000413 case 't':
414 {
415 m_step_in_target.clear();
416 m_step_in_target.assign(option_arg);
417
418 }
419 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000420 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000421 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000422 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423
424 }
425 return error;
426 }
427
428 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000429 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000431 m_step_in_avoid_no_debug = eLazyBoolCalculate;
432 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433 m_run_mode = eOnlyDuringStepping;
Ewan Crawford78baa192015-05-13 09:18:18 +0000434
435 // Check if we are in Non-Stop mode
436 lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
437 if (target_sp.get() != nullptr && target_sp->GetNonStopModeEnabled())
438 m_run_mode = eOnlyThisThread;
439
Jim Inghama56c8002010-07-10 02:27:39 +0000440 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000441 m_step_in_target.clear();
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000442 m_class_name.clear();
Jim Ingham7a88ec92014-07-08 19:28:57 +0000443 m_step_count = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000444 }
445
Greg Claytone0d378b2011-03-24 21:19:54 +0000446 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000447 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448 {
449 return g_option_table;
450 }
451
452 // Options table: Required for subclasses of Options.
453
Greg Claytone0d378b2011-03-24 21:19:54 +0000454 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455
456 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000457 LazyBool m_step_in_avoid_no_debug;
458 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000460 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000461 std::string m_step_in_target;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000462 std::string m_class_name;
Zachary Turner898e10e2015-01-09 20:15:21 +0000463 uint32_t m_step_count;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 };
465
Greg Claytona7015092010-09-18 01:14:36 +0000466 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
467 const char *name,
468 const char *help,
469 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000470 StepType step_type,
471 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000472 CommandObjectParsed (interpreter, name, help, syntax,
Enrico Granatae87764f2015-05-27 05:04:35 +0000473 eCommandRequiresProcess |
474 eCommandRequiresThread |
475 eCommandTryTargetAPILock |
476 eCommandProcessMustBeLaunched |
477 eCommandProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 m_step_type (step_type),
479 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000480 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481 {
Caroline Tice405fe672010-10-04 22:28:36 +0000482 CommandArgumentEntry arg;
483 CommandArgumentData thread_id_arg;
484
485 // Define the first (and only) variant of this arg.
486 thread_id_arg.arg_type = eArgTypeThreadID;
487 thread_id_arg.arg_repetition = eArgRepeatOptional;
488
489 // There is only one variant this argument could be; put it into the argument entry.
490 arg.push_back (thread_id_arg);
491
492 // Push the data for the first argument into the m_arguments vector.
493 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 }
495
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000496 ~CommandObjectThreadStepWithTypeAndScope () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497 {
498 }
499
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000501 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502 {
503 return &m_options;
504 }
505
Jim Ingham5a988412012-06-08 21:56:10 +0000506protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000507 bool
508 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000509 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000510 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000511 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512
Greg Claytonf9fc6092013-01-09 19:44:40 +0000513 const uint32_t num_threads = process->GetThreadList().GetSize();
514 Thread *thread = NULL;
515
516 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000518 thread = process->GetThreadList().GetSelectedThread().get();
519 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000521 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000523 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000525 }
526 else
527 {
528 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
Vince Harron5275aaa2015-01-15 20:08:35 +0000529 uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000530 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000531 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000532 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
533 result.SetStatus (eReturnStatusFailed);
534 return false;
535 }
536 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
537 if (thread == NULL)
538 {
539 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
540 step_thread_idx, num_threads);
541 result.SetStatus (eReturnStatusFailed);
542 return false;
543 }
544 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000545
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000546 if (m_step_type == eStepTypeScripted)
547 {
548 if (m_options.m_class_name.empty())
549 {
550 result.AppendErrorWithFormat ("empty class name for scripted step.");
551 result.SetStatus(eReturnStatusFailed);
552 return false;
553 }
554 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
555 {
556 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
557 result.SetStatus(eReturnStatusFailed);
558 return false;
559 }
560 }
561
Greg Claytonf9fc6092013-01-09 19:44:40 +0000562 const bool abort_other_plans = false;
563 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
564
565 // This is a bit unfortunate, but not all the commands in this command object support
566 // only while stepping, so I use the bool for them.
567 bool bool_stop_other_threads;
568 if (m_options.m_run_mode == eAllThreads)
569 bool_stop_other_threads = false;
570 else if (m_options.m_run_mode == eOnlyDuringStepping)
571 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000572 if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000573 bool_stop_other_threads = false;
574 else
575 bool_stop_other_threads = true;
576 }
577 else
578 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000579
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000580 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000581
582 if (m_step_type == eStepTypeInto)
583 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000584 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Stephane Sezerca05ae22015-03-26 17:47:34 +0000585 assert(frame != nullptr);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000586
Stephane Sezerca05ae22015-03-26 17:47:34 +0000587 if (frame->HasDebugInformation ())
Greg Claytonf9fc6092013-01-09 19:44:40 +0000588 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000589 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Jason Molenda25d5b102015-12-15 00:40:30 +0000590 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000591 frame->GetSymbolContext(eSymbolContextEverything),
592 m_options.m_step_in_target.c_str(),
593 stop_other_threads,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000594 m_options.m_step_in_avoid_no_debug,
595 m_options.m_step_out_avoid_no_debug);
596
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000597 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000598 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000599 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000600 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000601 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000602 }
603 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000604 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000605
606 }
607 else if (m_step_type == eStepTypeOver)
608 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000609 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000610
611 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000612 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Jason Molenda25d5b102015-12-15 00:40:30 +0000613 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000614 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000615 stop_other_threads,
616 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000617 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000618 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000619 abort_other_plans,
620 bool_stop_other_threads);
621
622 }
623 else if (m_step_type == eStepTypeTrace)
624 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000625 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000626 }
627 else if (m_step_type == eStepTypeTraceOver)
628 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000629 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000630 }
631 else if (m_step_type == eStepTypeOut)
632 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000633 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000634 NULL,
635 false,
636 bool_stop_other_threads,
637 eVoteYes,
638 eVoteNoOpinion,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000639 thread->GetSelectedFrameIndex(),
640 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000641 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000642 else if (m_step_type == eStepTypeScripted)
643 {
644 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
645 m_options.m_class_name.c_str(),
646 bool_stop_other_threads);
647 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000648 else
649 {
650 result.AppendError ("step type is not supported");
651 result.SetStatus (eReturnStatusFailed);
652 return false;
653 }
654
655 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
656 // so that they can be interruptible). Then resume the process.
657
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000658 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000659 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000660 new_plan_sp->SetIsMasterPlan (true);
661 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000662
663 if (m_options.m_step_count > 1)
664 {
Zachary Turner40411162014-07-16 20:28:24 +0000665 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
Jim Ingham7a88ec92014-07-08 19:28:57 +0000666 {
667 result.AppendWarning ("step operation does not support iteration count.");
668 }
669 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000670
Greg Claytondc6224e2014-10-21 01:00:42 +0000671
Greg Claytonf9fc6092013-01-09 19:44:40 +0000672 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000673
Pavel Labath44464872015-05-27 12:40:32 +0000674 const uint32_t iohandler_id = process->GetIOHandlerID();
675
Greg Claytondc6224e2014-10-21 01:00:42 +0000676 StreamString stream;
677 Error error;
678 if (synchronous_execution)
679 error = process->ResumeSynchronous (&stream);
680 else
681 error = process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000682
683 // There is a race condition where this thread will return up the call stack to the main command handler
684 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
685 // a chance to call PushProcessIOHandler().
Pavel Labath44464872015-05-27 12:40:32 +0000686 process->SyncIOHandler(iohandler_id, 2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000687
688 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000689 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000690 // If any state changed events had anything to say, add that to the result
691 if (stream.GetData())
692 result.AppendMessage(stream.GetData());
693
Greg Claytonf9fc6092013-01-09 19:44:40 +0000694 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
695 result.SetDidChangeProcessState (true);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000696 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000698 else
699 {
700 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
701 }
702 }
703 else
704 {
705 result.AppendError ("Couldn't find thread plan to implement step type.");
706 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000707 }
708 return result.Succeeded();
709 }
710
711protected:
712 StepType m_step_type;
713 StepScope m_step_scope;
714 CommandOptions m_options;
715};
716
Greg Claytone0d378b2011-03-24 21:19:54 +0000717static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718g_tri_running_mode[] =
719{
Greg Claytoned8a7052010-09-18 03:37:20 +0000720{ eOnlyThisThread, "this-thread", "Run only this thread"},
721{ eAllThreads, "all-threads", "Run all threads"},
722{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000723{ 0, NULL, NULL }
724};
725
Greg Claytone0d378b2011-03-24 21:19:54 +0000726static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727g_duo_running_mode[] =
728{
Greg Claytoned8a7052010-09-18 03:37:20 +0000729{ eOnlyThisThread, "this-thread", "Run only this thread"},
730{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731{ 0, NULL, NULL }
732};
733
Greg Claytone0d378b2011-03-24 21:19:54 +0000734OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
736{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000737{ 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."},
738{ 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 +0000739{ 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."},
740{ 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."},
741{ 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."},
742{ 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."},
743{ 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 +0000744{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000745};
746
747
748//-------------------------------------------------------------------------
749// CommandObjectThreadContinue
750//-------------------------------------------------------------------------
751
Jim Ingham5a988412012-06-08 21:56:10 +0000752class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000753{
754public:
755
Greg Claytona7015092010-09-18 01:14:36 +0000756 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000757 CommandObjectParsed (interpreter,
758 "thread continue",
759 "Continue execution of one or more threads in an active process.",
760 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +0000761 eCommandRequiresThread |
762 eCommandTryTargetAPILock |
763 eCommandProcessMustBeLaunched |
764 eCommandProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000765 {
Caroline Tice405fe672010-10-04 22:28:36 +0000766 CommandArgumentEntry arg;
767 CommandArgumentData thread_idx_arg;
768
769 // Define the first (and only) variant of this arg.
770 thread_idx_arg.arg_type = eArgTypeThreadIndex;
771 thread_idx_arg.arg_repetition = eArgRepeatPlus;
772
773 // There is only one variant this argument could be; put it into the argument entry.
774 arg.push_back (thread_idx_arg);
775
776 // Push the data for the first argument into the m_arguments vector.
777 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000778 }
779
780
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000781 ~CommandObjectThreadContinue () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 {
783 }
784
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000785 bool
786 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787 {
Greg Claytona7015092010-09-18 01:14:36 +0000788 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789
Greg Claytona7015092010-09-18 01:14:36 +0000790 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000791 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000792 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000793 result.SetStatus (eReturnStatusFailed);
794 return false;
795 }
796
Greg Claytonf9fc6092013-01-09 19:44:40 +0000797 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798 if (process == NULL)
799 {
800 result.AppendError ("no process exists. Cannot continue");
801 result.SetStatus (eReturnStatusFailed);
802 return false;
803 }
804
805 StateType state = process->GetState();
806 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
807 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000808 const size_t argc = command.GetArgumentCount();
809 if (argc > 0)
810 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000811 // These two lines appear at the beginning of both blocks in
812 // this if..else, but that is because we need to release the
813 // lock before calling process->Resume below.
814 Mutex::Locker locker (process->GetThreadList().GetMutex());
815 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000816 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817 for (uint32_t i=0; i<argc; ++i)
818 {
Jim Inghamce76c622012-05-31 20:48:41 +0000819 bool success;
820 const int base = 0;
Vince Harron5275aaa2015-01-15 20:08:35 +0000821 uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000822 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000823 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000824 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000825
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000826 if (thread)
827 {
828 resume_threads.push_back(thread);
829 }
830 else
831 {
832 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
833 result.SetStatus (eReturnStatusFailed);
834 return false;
835 }
Jim Inghamce76c622012-05-31 20:48:41 +0000836 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837 else
Jim Inghamce76c622012-05-31 20:48:41 +0000838 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000839 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000840 result.SetStatus (eReturnStatusFailed);
841 return false;
842 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000844
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000845 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846 {
847 result.AppendError ("no valid thread indexes were specified");
848 result.SetStatus (eReturnStatusFailed);
849 return false;
850 }
851 else
852 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000853 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000854 result.AppendMessageWithFormat ("Resuming thread: ");
855 else
856 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000857
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000858 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000859 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000860 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
861 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000862
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000863 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000864 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000865 resume_threads.erase(this_thread_pos);
866 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000867 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
868 else
869 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000870
871 const bool override_suspend = true;
872 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873 }
874 else
875 {
876 thread->SetResumeState (eStateSuspended);
877 }
878 }
Daniel Malead01b2952012-11-29 21:49:15 +0000879 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880 }
881 }
882 else
883 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000884 // These two lines appear at the beginning of both blocks in
885 // this if..else, but that is because we need to release the
886 // lock before calling process->Resume below.
887 Mutex::Locker locker (process->GetThreadList().GetMutex());
888 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000889 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000890 if (current_thread == NULL)
891 {
892 result.AppendError ("the process doesn't have a current thread");
893 result.SetStatus (eReturnStatusFailed);
894 return false;
895 }
896 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000897 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000899 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900 if (thread == current_thread)
901 {
Daniel Malead01b2952012-11-29 21:49:15 +0000902 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000903 const bool override_suspend = true;
904 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905 }
906 else
907 {
908 thread->SetResumeState (eStateSuspended);
909 }
910 }
911 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000912
Greg Claytondc6224e2014-10-21 01:00:42 +0000913
914 StreamString stream;
915 Error error;
916 if (synchronous_execution)
917 error = process->ResumeSynchronous (&stream);
918 else
919 error = process->Resume ();
920
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000921 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000922 if (error.Success())
923 {
Daniel Malead01b2952012-11-29 21:49:15 +0000924 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 if (synchronous_execution)
926 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000927 // If any state changed events had anything to say, add that to the result
928 if (stream.GetData())
929 result.AppendMessage(stream.GetData());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000930
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932 result.SetStatus (eReturnStatusSuccessFinishNoResult);
933 }
934 else
935 {
936 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
937 }
938 }
939 else
940 {
941 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
942 result.SetStatus (eReturnStatusFailed);
943 }
944 }
945 else
946 {
947 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
948 StateAsCString(state));
949 result.SetStatus (eReturnStatusFailed);
950 }
951
952 return result.Succeeded();
953 }
954
955};
956
957//-------------------------------------------------------------------------
958// CommandObjectThreadUntil
959//-------------------------------------------------------------------------
960
Jim Ingham5a988412012-06-08 21:56:10 +0000961class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962{
963public:
964
965 class CommandOptions : public Options
966 {
967 public:
968 uint32_t m_thread_idx;
969 uint32_t m_frame_idx;
970
Greg Claytoneb0103f2011-04-07 22:46:35 +0000971 CommandOptions (CommandInterpreter &interpreter) :
972 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973 m_thread_idx(LLDB_INVALID_THREAD_ID),
974 m_frame_idx(LLDB_INVALID_FRAME_ID)
975 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000976 // Keep default values of all options in one place: OptionParsingStarting ()
977 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000978 }
979
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000980 ~CommandOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981 {
982 }
983
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000984 Error
985 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000986 {
987 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000988 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000989
990 switch (short_option)
991 {
Jim Ingham9bdea542015-02-06 02:10:56 +0000992 case 'a':
993 {
994 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
995 lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
996 if (error.Success())
997 m_until_addrs.push_back(tmp_addr);
998 }
999 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001000 case 't':
1001 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001002 m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001003 if (m_thread_idx == LLDB_INVALID_INDEX32)
1004 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001005 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001006 }
1007 }
1008 break;
1009 case 'f':
1010 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001011 m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001012 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1013 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001014 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 }
1016 }
1017 break;
1018 case 'm':
1019 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001020 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001021 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001023 if (error.Success())
1024 {
1025 if (run_mode == eAllThreads)
1026 m_stop_others = false;
1027 else
1028 m_stop_others = true;
1029 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030 }
1031 break;
1032 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001033 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034 break;
1035
1036 }
1037 return error;
1038 }
1039
1040 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001041 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 m_thread_idx = LLDB_INVALID_THREAD_ID;
1044 m_frame_idx = 0;
1045 m_stop_others = false;
Jim Ingham9bdea542015-02-06 02:10:56 +00001046 m_until_addrs.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047 }
1048
Greg Claytone0d378b2011-03-24 21:19:54 +00001049 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001050 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051 {
1052 return g_option_table;
1053 }
1054
1055 uint32_t m_step_thread_idx;
1056 bool m_stop_others;
Jim Ingham9bdea542015-02-06 02:10:56 +00001057 std::vector<lldb::addr_t> m_until_addrs;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001058
1059 // Options table: Required for subclasses of Options.
1060
Greg Claytone0d378b2011-03-24 21:19:54 +00001061 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062
1063 // Instance variables to hold the values for command options.
1064 };
1065
Greg Claytona7015092010-09-18 01:14:36 +00001066 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001067 CommandObjectParsed (interpreter,
1068 "thread until",
Jim Ingham9bdea542015-02-06 02:10:56 +00001069 "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 +00001070 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00001071 eCommandRequiresThread |
1072 eCommandTryTargetAPILock |
1073 eCommandProcessMustBeLaunched |
1074 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001075 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001076 {
Caroline Tice405fe672010-10-04 22:28:36 +00001077 CommandArgumentEntry arg;
1078 CommandArgumentData line_num_arg;
1079
1080 // Define the first (and only) variant of this arg.
1081 line_num_arg.arg_type = eArgTypeLineNum;
1082 line_num_arg.arg_repetition = eArgRepeatPlain;
1083
1084 // There is only one variant this argument could be; put it into the argument entry.
1085 arg.push_back (line_num_arg);
1086
1087 // Push the data for the first argument into the m_arguments vector.
1088 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089 }
1090
1091
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001092 ~CommandObjectThreadUntil () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093 {
1094 }
1095
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001097 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001098 {
1099 return &m_options;
1100 }
1101
Jim Ingham5a988412012-06-08 21:56:10 +00001102protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001103 bool
1104 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001105 {
Greg Claytona7015092010-09-18 01:14:36 +00001106 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001107
Greg Claytona7015092010-09-18 01:14:36 +00001108 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +00001109 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001111 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001112 result.SetStatus (eReturnStatusFailed);
1113 return false;
1114 }
1115
Greg Claytonf9fc6092013-01-09 19:44:40 +00001116 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 if (process == NULL)
1118 {
1119 result.AppendError ("need a valid process to step");
1120 result.SetStatus (eReturnStatusFailed);
1121
1122 }
1123 else
1124 {
1125 Thread *thread = NULL;
Jim Ingham9bdea542015-02-06 02:10:56 +00001126 std::vector<uint32_t> line_numbers;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127
Jim Ingham9bdea542015-02-06 02:10:56 +00001128 if (command.GetArgumentCount() >= 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001130 size_t num_args = command.GetArgumentCount();
1131 for (size_t i = 0; i < num_args; i++)
1132 {
1133 uint32_t line_number;
1134 line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1135 if (line_number == UINT32_MAX)
1136 {
1137 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1138 result.SetStatus (eReturnStatusFailed);
1139 return false;
1140 }
1141 else
1142 line_numbers.push_back(line_number);
1143 }
1144 }
1145 else if (m_options.m_until_addrs.empty())
1146 {
1147 result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148 result.SetStatus (eReturnStatusFailed);
1149 return false;
1150 }
1151
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152
1153 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1154 {
Jim Ingham2976d002010-08-26 21:32:51 +00001155 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001156 }
1157 else
1158 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001159 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001160 }
1161
1162 if (thread == NULL)
1163 {
1164 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001165 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1166 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001167 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168 result.SetStatus (eReturnStatusFailed);
1169 return false;
1170 }
1171
Jim Ingham7ba6e992012-05-11 23:47:32 +00001172 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001173
Jason Molendab57e4a12013-11-04 09:33:30 +00001174 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001175 if (frame == NULL)
1176 {
1177
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001178 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1179 m_options.m_frame_idx,
1180 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181 result.SetStatus (eReturnStatusFailed);
1182 return false;
1183 }
1184
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001185 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186
1187 if (frame->HasDebugInformation ())
1188 {
1189 // Finally we got here... Translate the given line number to a bunch of addresses:
1190 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1191 LineTable *line_table = NULL;
1192 if (sc.comp_unit)
1193 line_table = sc.comp_unit->GetLineTable();
1194
1195 if (line_table == NULL)
1196 {
1197 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1198 m_options.m_frame_idx, m_options.m_thread_idx);
1199 result.SetStatus (eReturnStatusFailed);
1200 return false;
1201 }
1202
1203 LineEntry function_start;
1204 uint32_t index_ptr = 0, end_ptr;
1205 std::vector<addr_t> address_list;
1206
1207 // Find the beginning & end index of the
1208 AddressRange fun_addr_range = sc.function->GetAddressRange();
1209 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1210 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1211
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001212 Address fun_end_addr(fun_start_addr.GetSection(),
1213 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001215 bool all_in_function = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001216
Jim Ingham9bdea542015-02-06 02:10:56 +00001217 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1218
1219 for (uint32_t line_number : line_numbers)
1220 {
1221 uint32_t start_idx_ptr = index_ptr;
1222 while (start_idx_ptr <= end_ptr)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001223 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001224 LineEntry line_entry;
1225 const bool exact = false;
1226 start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
1227 if (start_idx_ptr == UINT32_MAX)
1228 break;
1229
1230 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1231 if (address != LLDB_INVALID_ADDRESS)
1232 {
1233 if (fun_addr_range.ContainsLoadAddress (address, target))
1234 address_list.push_back (address);
1235 else
1236 all_in_function = false;
1237 }
1238 start_idx_ptr++;
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001239 }
Jim Ingham9bdea542015-02-06 02:10:56 +00001240 }
1241
1242 for (lldb::addr_t address : m_options.m_until_addrs)
1243 {
1244 if (fun_addr_range.ContainsLoadAddress (address, target))
1245 address_list.push_back (address);
1246 else
1247 all_in_function = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001248 }
1249
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001250 if (address_list.size() == 0)
1251 {
1252 if (all_in_function)
1253 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1254 else
1255 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1256
1257 result.SetStatus (eReturnStatusFailed);
1258 return false;
1259 }
1260
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001261 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001262 &address_list.front(),
1263 address_list.size(),
1264 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001265 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001266 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1267 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1268 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001269 new_plan_sp->SetIsMasterPlan (true);
1270 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271 }
1272 else
1273 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001274 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1275 m_options.m_frame_idx,
1276 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001277 result.SetStatus (eReturnStatusFailed);
1278 return false;
1279
1280 }
1281
Greg Claytondc6224e2014-10-21 01:00:42 +00001282
1283
Jim Ingham2976d002010-08-26 21:32:51 +00001284 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Greg Claytondc6224e2014-10-21 01:00:42 +00001285
1286 StreamString stream;
1287 Error error;
1288 if (synchronous_execution)
1289 error = process->ResumeSynchronous (&stream);
1290 else
1291 error = process->Resume ();
1292
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001293 if (error.Success())
1294 {
Daniel Malead01b2952012-11-29 21:49:15 +00001295 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296 if (synchronous_execution)
1297 {
Greg Claytondc6224e2014-10-21 01:00:42 +00001298 // If any state changed events had anything to say, add that to the result
1299 if (stream.GetData())
1300 result.AppendMessage(stream.GetData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001301
1302 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001303 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1304 }
1305 else
1306 {
1307 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1308 }
1309 }
1310 else
1311 {
1312 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1313 result.SetStatus (eReturnStatusFailed);
1314 }
1315
1316 }
1317 return result.Succeeded();
1318 }
Jim Ingham5a988412012-06-08 21:56:10 +00001319
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001320 CommandOptions m_options;
1321
1322};
1323
Greg Claytone0d378b2011-03-24 21:19:54 +00001324OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001325CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1326{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001327{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1328{ 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 +00001329{ 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"},
1330{ 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 +00001331{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332};
1333
1334
1335//-------------------------------------------------------------------------
1336// CommandObjectThreadSelect
1337//-------------------------------------------------------------------------
1338
Jim Ingham5a988412012-06-08 21:56:10 +00001339class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001340{
1341public:
1342
Greg Claytona7015092010-09-18 01:14:36 +00001343 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001344 CommandObjectParsed (interpreter,
1345 "thread select",
1346 "Select a thread as the currently active thread.",
1347 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00001348 eCommandRequiresProcess |
1349 eCommandTryTargetAPILock |
1350 eCommandProcessMustBeLaunched |
1351 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352 {
Caroline Tice405fe672010-10-04 22:28:36 +00001353 CommandArgumentEntry arg;
1354 CommandArgumentData thread_idx_arg;
1355
1356 // Define the first (and only) variant of this arg.
1357 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1358 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1359
1360 // There is only one variant this argument could be; put it into the argument entry.
1361 arg.push_back (thread_idx_arg);
1362
1363 // Push the data for the first argument into the m_arguments vector.
1364 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001365 }
1366
1367
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001368 ~CommandObjectThreadSelect () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001369 {
1370 }
1371
Jim Ingham5a988412012-06-08 21:56:10 +00001372protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001373 bool
1374 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001375 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001376 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001377 if (process == NULL)
1378 {
1379 result.AppendError ("no process");
1380 result.SetStatus (eReturnStatusFailed);
1381 return false;
1382 }
1383 else if (command.GetArgumentCount() != 1)
1384 {
Jason Molendafd54b362011-09-20 21:44:10 +00001385 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 +00001386 result.SetStatus (eReturnStatusFailed);
1387 return false;
1388 }
1389
Vince Harron5275aaa2015-01-15 20:08:35 +00001390 uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001391
1392 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1393 if (new_thread == NULL)
1394 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001395 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001396 result.SetStatus (eReturnStatusFailed);
1397 return false;
1398 }
1399
Jim Inghamc3faa192012-12-11 02:31:48 +00001400 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001401 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001402
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403 return result.Succeeded();
1404 }
1405
1406};
1407
1408
1409//-------------------------------------------------------------------------
1410// CommandObjectThreadList
1411//-------------------------------------------------------------------------
1412
Jim Ingham5a988412012-06-08 21:56:10 +00001413class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001414{
Greg Clayton66111032010-06-23 01:19:29 +00001415public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001416
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417
Greg Claytona7015092010-09-18 01:14:36 +00001418 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001419 CommandObjectParsed (interpreter,
1420 "thread list",
1421 "Show a summary of all current threads in a process.",
1422 "thread list",
Enrico Granatae87764f2015-05-27 05:04:35 +00001423 eCommandRequiresProcess |
1424 eCommandTryTargetAPILock |
1425 eCommandProcessMustBeLaunched |
1426 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001427 {
Greg Clayton66111032010-06-23 01:19:29 +00001428 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001429
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001430 ~CommandObjectThreadList() override
Greg Clayton66111032010-06-23 01:19:29 +00001431 {
1432 }
1433
Jim Ingham5a988412012-06-08 21:56:10 +00001434protected:
Greg Clayton66111032010-06-23 01:19:29 +00001435 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001436 DoExecute (Args& command, CommandReturnObject &result) override
Greg Clayton66111032010-06-23 01:19:29 +00001437 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001438 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001439 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001440 Process *process = m_exe_ctx.GetProcessPtr();
1441 const bool only_threads_with_stop_reason = false;
1442 const uint32_t start_frame = 0;
1443 const uint32_t num_frames = 0;
1444 const uint32_t num_frames_with_source = 0;
1445 process->GetStatus(strm);
1446 process->GetThreadStatus (strm,
1447 only_threads_with_stop_reason,
1448 start_frame,
1449 num_frames,
1450 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001451 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001452 }
Greg Clayton66111032010-06-23 01:19:29 +00001453};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001454
Jim Ingham93208b82013-01-31 21:46:01 +00001455//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001456// CommandObjectThreadInfo
1457//-------------------------------------------------------------------------
1458
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001459class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001460{
1461public:
1462
1463 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001464 CommandObjectIterateOverThreads (interpreter,
1465 "thread info",
1466 "Show an extended summary of information about thread(s) in a process.",
1467 "thread info",
Enrico Granatae87764f2015-05-27 05:04:35 +00001468 eCommandRequiresProcess |
1469 eCommandTryTargetAPILock |
1470 eCommandProcessMustBeLaunched |
1471 eCommandProcessMustBePaused),
Jason Molenda705b1802014-06-13 02:37:02 +00001472 m_options (interpreter)
1473 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001474 m_add_return = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001475 }
1476
1477 class CommandOptions : public Options
1478 {
1479 public:
1480
1481 CommandOptions (CommandInterpreter &interpreter) :
1482 Options (interpreter)
1483 {
1484 OptionParsingStarting ();
1485 }
1486
1487 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001488 OptionParsingStarting () override
Jason Molenda705b1802014-06-13 02:37:02 +00001489 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001490 m_json_thread = false;
1491 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001492 }
1493
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001494 ~CommandOptions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001495 {
1496 }
1497
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001498 Error
1499 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jason Molenda705b1802014-06-13 02:37:02 +00001500 {
1501 const int short_option = m_getopt_table[option_idx].val;
1502 Error error;
1503
1504 switch (short_option)
1505 {
1506 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001507 m_json_thread = true;
1508 break;
1509
1510 case 's':
1511 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001512 break;
1513
Kuba Breckaafdf8422014-10-10 23:43:03 +00001514 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001515 return Error("invalid short option character '%c'", short_option);
1516
1517 }
1518 return error;
1519 }
1520
1521 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001522 GetDefinitions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001523 {
1524 return g_option_table;
1525 }
1526
Kuba Breckaafdf8422014-10-10 23:43:03 +00001527 bool m_json_thread;
1528 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001529
1530 static OptionDefinition g_option_table[];
1531 };
1532
Jason Molenda705b1802014-06-13 02:37:02 +00001533 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001534 GetOptions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001535 {
1536 return &m_options;
1537 }
1538
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001539 ~CommandObjectThreadInfo () override
Jason Molenda705b1802014-06-13 02:37:02 +00001540 {
1541 }
1542
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001543 bool
1544 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jason Molenda705b1802014-06-13 02:37:02 +00001545 {
Jason Molenda705b1802014-06-13 02:37:02 +00001546 Stream &strm = result.GetOutputStream();
Kuba Breckaafdf8422014-10-10 23:43:03 +00001547 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
Jason Molenda705b1802014-06-13 02:37:02 +00001548 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001549 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1550 result.SetStatus (eReturnStatusFailed);
1551 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001552 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001553 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001554 }
1555
1556 CommandOptions m_options;
1557
1558};
1559
1560OptionDefinition
1561CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1562{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001563 { 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 +00001564 { 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 +00001565
Zachary Turnerd37221d2014-07-09 16:31:49 +00001566 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jason Molenda705b1802014-06-13 02:37:02 +00001567};
1568
1569
1570//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001571// CommandObjectThreadReturn
1572//-------------------------------------------------------------------------
1573
Jim Inghamcb640dd2012-09-14 02:14:15 +00001574class CommandObjectThreadReturn : public CommandObjectRaw
1575{
1576public:
Jim Ingham93208b82013-01-31 21:46:01 +00001577 class CommandOptions : public Options
1578 {
1579 public:
1580
1581 CommandOptions (CommandInterpreter &interpreter) :
1582 Options (interpreter),
1583 m_from_expression (false)
1584 {
1585 // Keep default values of all options in one place: OptionParsingStarting ()
1586 OptionParsingStarting ();
1587 }
1588
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001589 ~CommandOptions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001590 {
1591 }
1592
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001593 Error
1594 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham93208b82013-01-31 21:46:01 +00001595 {
1596 Error error;
1597 const int short_option = m_getopt_table[option_idx].val;
1598
1599 switch (short_option)
1600 {
1601 case 'x':
1602 {
1603 bool success;
1604 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1605 if (success)
1606 m_from_expression = tmp_value;
1607 else
1608 {
1609 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1610 }
1611 }
1612 break;
1613 default:
1614 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1615 break;
1616
1617 }
1618 return error;
1619 }
1620
1621 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001622 OptionParsingStarting () override
Jim Ingham93208b82013-01-31 21:46:01 +00001623 {
1624 m_from_expression = false;
1625 }
1626
1627 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001628 GetDefinitions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001629 {
1630 return g_option_table;
1631 }
1632
1633 bool m_from_expression;
1634
1635 // Options table: Required for subclasses of Options.
1636
1637 static OptionDefinition g_option_table[];
1638
1639 // Instance variables to hold the values for command options.
1640 };
1641
Jim Ingham93208b82013-01-31 21:46:01 +00001642 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001643 GetOptions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001644 {
1645 return &m_options;
1646 }
1647
Jim Inghamcb640dd2012-09-14 02:14:15 +00001648 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1649 CommandObjectRaw (interpreter,
1650 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001651 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1652 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001653 "thread return",
Enrico Granatae87764f2015-05-27 05:04:35 +00001654 eCommandRequiresFrame |
1655 eCommandTryTargetAPILock |
1656 eCommandProcessMustBeLaunched |
1657 eCommandProcessMustBePaused ),
Jim Ingham93208b82013-01-31 21:46:01 +00001658 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001659 {
1660 CommandArgumentEntry arg;
1661 CommandArgumentData expression_arg;
1662
1663 // Define the first (and only) variant of this arg.
1664 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001665 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001666
1667 // There is only one variant this argument could be; put it into the argument entry.
1668 arg.push_back (expression_arg);
1669
1670 // Push the data for the first argument into the m_arguments vector.
1671 m_arguments.push_back (arg);
1672
1673
1674 }
1675
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001676 ~CommandObjectThreadReturn() override
Jim Inghamcb640dd2012-09-14 02:14:15 +00001677 {
1678 }
1679
1680protected:
1681
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001682 bool
1683 DoExecute (const char *command, CommandReturnObject &result) override
Jim Inghamcb640dd2012-09-14 02:14:15 +00001684 {
Jim Ingham93208b82013-01-31 21:46:01 +00001685 // I am going to handle this by hand, because I don't want you to have to say:
1686 // "thread return -- -5".
1687 if (command[0] == '-' && command[1] == 'x')
1688 {
1689 if (command && command[2] != '\0')
1690 result.AppendWarning("Return values ignored when returning from user called expressions");
1691
1692 Thread *thread = m_exe_ctx.GetThreadPtr();
1693 Error error;
1694 error = thread->UnwindInnermostExpression();
1695 if (!error.Success())
1696 {
1697 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1698 result.SetStatus (eReturnStatusFailed);
1699 }
1700 else
1701 {
1702 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1703 if (success)
1704 {
1705 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1706 result.SetStatus (eReturnStatusSuccessFinishResult);
1707 }
1708 else
1709 {
1710 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1711 result.SetStatus (eReturnStatusFailed);
1712 }
1713 }
1714 return result.Succeeded();
1715 }
1716
Jim Inghamcb640dd2012-09-14 02:14:15 +00001717 ValueObjectSP return_valobj_sp;
1718
Jason Molendab57e4a12013-11-04 09:33:30 +00001719 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001720 uint32_t frame_idx = frame_sp->GetFrameIndex();
1721
1722 if (frame_sp->IsInlined())
1723 {
1724 result.AppendError("Don't know how to return from inlined frames.");
1725 result.SetStatus (eReturnStatusFailed);
1726 return false;
1727 }
1728
1729 if (command && command[0] != '\0')
1730 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001731 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001732 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001733
1734 options.SetUnwindOnError(true);
1735 options.SetUseDynamic(eNoDynamicValues);
1736
Jim Ingham8646d3c2014-05-05 02:47:44 +00001737 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001738 exe_results = target->EvaluateExpression (command,
1739 frame_sp.get(),
1740 return_valobj_sp,
1741 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001742 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001743 {
1744 if (return_valobj_sp)
1745 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1746 else
1747 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1748 result.SetStatus (eReturnStatusFailed);
1749 return false;
1750
1751 }
1752 }
1753
1754 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001755 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001756 const bool broadcast = true;
1757 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001758 if (!error.Success())
1759 {
1760 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1761 result.SetStatus (eReturnStatusFailed);
1762 return false;
1763 }
1764
Jim Inghamcb640dd2012-09-14 02:14:15 +00001765 result.SetStatus (eReturnStatusSuccessFinishResult);
1766 return true;
1767 }
Jim Ingham93208b82013-01-31 21:46:01 +00001768
1769 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001770
1771};
Jim Ingham93208b82013-01-31 21:46:01 +00001772OptionDefinition
1773CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1774{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001775{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1776{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham93208b82013-01-31 21:46:01 +00001777};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001778
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001779//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001780// CommandObjectThreadJump
1781//-------------------------------------------------------------------------
1782
1783class CommandObjectThreadJump : public CommandObjectParsed
1784{
1785public:
1786 class CommandOptions : public Options
1787 {
1788 public:
1789
1790 CommandOptions (CommandInterpreter &interpreter) :
1791 Options (interpreter)
1792 {
1793 OptionParsingStarting ();
1794 }
1795
1796 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001797 OptionParsingStarting () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001798 {
1799 m_filenames.Clear();
1800 m_line_num = 0;
1801 m_line_offset = 0;
1802 m_load_addr = LLDB_INVALID_ADDRESS;
1803 m_force = false;
1804 }
1805
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001806 ~CommandOptions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001807 {
1808 }
1809
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001810 Error
1811 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001812 {
1813 bool success;
1814 const int short_option = m_getopt_table[option_idx].val;
1815 Error error;
1816
1817 switch (short_option)
1818 {
1819 case 'f':
1820 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1821 if (m_filenames.GetSize() > 1)
1822 return Error("only one source file expected.");
1823 break;
1824 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001825 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001826 if (!success || m_line_num == 0)
1827 return Error("invalid line number: '%s'.", option_arg);
1828 break;
1829 case 'b':
Vince Harron5275aaa2015-01-15 20:08:35 +00001830 m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001831 if (!success)
1832 return Error("invalid line offset: '%s'.", option_arg);
1833 break;
1834 case 'a':
1835 {
1836 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1837 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1838 }
1839 break;
1840 case 'r':
1841 m_force = true;
1842 break;
1843
1844 default:
1845 return Error("invalid short option character '%c'", short_option);
1846
1847 }
1848 return error;
1849 }
1850
1851 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001852 GetDefinitions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001853 {
1854 return g_option_table;
1855 }
1856
1857 FileSpecList m_filenames;
1858 uint32_t m_line_num;
1859 int32_t m_line_offset;
1860 lldb::addr_t m_load_addr;
1861 bool m_force;
1862
1863 static OptionDefinition g_option_table[];
1864 };
1865
Richard Mittonf86248d2013-09-12 02:20:34 +00001866 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001867 GetOptions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001868 {
1869 return &m_options;
1870 }
1871
1872 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1873 CommandObjectParsed (interpreter,
1874 "thread jump",
1875 "Sets the program counter to a new address.",
1876 "thread jump",
Enrico Granatae87764f2015-05-27 05:04:35 +00001877 eCommandRequiresFrame |
1878 eCommandTryTargetAPILock |
1879 eCommandProcessMustBeLaunched |
1880 eCommandProcessMustBePaused ),
Richard Mittonf86248d2013-09-12 02:20:34 +00001881 m_options (interpreter)
1882 {
1883 }
1884
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001885 ~CommandObjectThreadJump() override
Richard Mittonf86248d2013-09-12 02:20:34 +00001886 {
1887 }
1888
1889protected:
1890
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001891 bool DoExecute (Args& args, CommandReturnObject &result) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001892 {
1893 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001894 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001895 Thread *thread = m_exe_ctx.GetThreadPtr();
1896 Target *target = m_exe_ctx.GetTargetPtr();
1897 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1898
1899 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1900 {
1901 // Use this address directly.
1902 Address dest = Address(m_options.m_load_addr);
1903
1904 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1905 if (callAddr == LLDB_INVALID_ADDRESS)
1906 {
1907 result.AppendErrorWithFormat ("Invalid destination address.");
1908 result.SetStatus (eReturnStatusFailed);
1909 return false;
1910 }
1911
1912 if (!reg_ctx->SetPC (callAddr))
1913 {
1914 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1915 result.SetStatus (eReturnStatusFailed);
1916 return false;
1917 }
1918 }
1919 else
1920 {
1921 // Pick either the absolute line, or work out a relative one.
1922 int32_t line = (int32_t)m_options.m_line_num;
1923 if (line == 0)
1924 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1925
1926 // Try the current file, but override if asked.
1927 FileSpec file = sym_ctx.line_entry.file;
1928 if (m_options.m_filenames.GetSize() == 1)
1929 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1930
1931 if (!file)
1932 {
1933 result.AppendErrorWithFormat ("No source file available for the current location.");
1934 result.SetStatus (eReturnStatusFailed);
1935 return false;
1936 }
1937
1938 std::string warnings;
1939 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1940
1941 if (err.Fail())
1942 {
1943 result.SetError (err);
1944 return false;
1945 }
1946
1947 if (!warnings.empty())
1948 result.AppendWarning (warnings.c_str());
1949 }
1950
1951 result.SetStatus (eReturnStatusSuccessFinishResult);
1952 return true;
1953 }
1954
1955 CommandOptions m_options;
1956};
1957OptionDefinition
1958CommandObjectThreadJump::CommandOptions::g_option_table[] =
1959{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001960 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001961 "Specifies the source file to jump to."},
1962
Zachary Turnerd37221d2014-07-09 16:31:49 +00001963 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001964 "Specifies the line number to jump to."},
1965
Zachary Turnerd37221d2014-07-09 16:31:49 +00001966 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001967 "Jumps by a relative line offset from the current line."},
1968
Zachary Turnerd37221d2014-07-09 16:31:49 +00001969 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001970 "Jumps to a specific address."},
1971
1972 { LLDB_OPT_SET_1|
1973 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +00001974 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 +00001975
Zachary Turnerd37221d2014-07-09 16:31:49 +00001976 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Richard Mittonf86248d2013-09-12 02:20:34 +00001977};
1978
1979//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001980// Next are the subcommands of CommandObjectMultiwordThreadPlan
1981//-------------------------------------------------------------------------
1982
1983
1984//-------------------------------------------------------------------------
1985// CommandObjectThreadPlanList
1986//-------------------------------------------------------------------------
1987class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1988{
1989public:
1990
1991 class CommandOptions : public Options
1992 {
1993 public:
1994
1995 CommandOptions (CommandInterpreter &interpreter) :
1996 Options(interpreter)
1997 {
1998 // Keep default values of all options in one place: OptionParsingStarting ()
1999 OptionParsingStarting ();
2000 }
2001
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002002 ~CommandOptions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002003 {
2004 }
2005
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002006 Error
2007 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002008 {
2009 Error error;
2010 const int short_option = m_getopt_table[option_idx].val;
2011
2012 switch (short_option)
2013 {
2014 case 'i':
2015 {
2016 m_internal = true;
2017 }
2018 break;
2019 case 'v':
2020 {
2021 m_verbose = true;
2022 }
2023 break;
2024 default:
2025 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2026 break;
2027
2028 }
2029 return error;
2030 }
2031
2032 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002033 OptionParsingStarting () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002034 {
2035 m_verbose = false;
2036 m_internal = false;
2037 }
2038
2039 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002040 GetDefinitions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002041 {
2042 return g_option_table;
2043 }
2044
2045 // Options table: Required for subclasses of Options.
2046
2047 static OptionDefinition g_option_table[];
2048
2049 // Instance variables to hold the values for command options.
2050 bool m_verbose;
2051 bool m_internal;
2052 };
2053
2054 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
2055 CommandObjectIterateOverThreads (interpreter,
2056 "thread plan list",
2057 "Show thread plans for one or more threads. If no threads are specified, show the "
2058 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2059 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00002060 eCommandRequiresProcess |
2061 eCommandRequiresThread |
2062 eCommandTryTargetAPILock |
2063 eCommandProcessMustBeLaunched |
2064 eCommandProcessMustBePaused ),
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002065 m_options(interpreter)
2066 {
2067 }
2068
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002069 ~CommandObjectThreadPlanList () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002070 {
2071 }
2072
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002073 Options *
2074 GetOptions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002075 {
2076 return &m_options;
2077 }
2078
2079protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002080 bool
2081 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002082 {
2083 Stream &strm = result.GetOutputStream();
2084 DescriptionLevel desc_level = eDescriptionLevelFull;
2085 if (m_options.m_verbose)
2086 desc_level = eDescriptionLevelVerbose;
2087
2088 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2089 return true;
2090 }
2091 CommandOptions m_options;
2092};
2093
2094OptionDefinition
2095CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2096{
2097{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
2098{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2099{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2100};
2101
2102class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2103{
2104public:
2105 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
2106 CommandObjectParsed (interpreter,
2107 "thread plan discard",
2108 "Discards thread plans up to and including the plan passed as the command argument."
2109 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2110 " without the \"-i\" argument.",
2111 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00002112 eCommandRequiresProcess |
2113 eCommandRequiresThread |
2114 eCommandTryTargetAPILock |
2115 eCommandProcessMustBeLaunched |
2116 eCommandProcessMustBePaused )
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002117 {
2118 CommandArgumentEntry arg;
2119 CommandArgumentData plan_index_arg;
2120
2121 // Define the first (and only) variant of this arg.
2122 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2123 plan_index_arg.arg_repetition = eArgRepeatPlain;
2124
2125 // There is only one variant this argument could be; put it into the argument entry.
2126 arg.push_back (plan_index_arg);
2127
2128 // Push the data for the first argument into the m_arguments vector.
2129 m_arguments.push_back (arg);
2130 }
2131
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002132 ~CommandObjectThreadPlanDiscard () override {}
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002133
2134 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002135 DoExecute (Args& args, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002136 {
2137 Thread *thread = m_exe_ctx.GetThreadPtr();
2138 if (args.GetArgumentCount() != 1)
2139 {
2140 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2141 args.GetArgumentCount());
2142 result.SetStatus (eReturnStatusFailed);
2143 return false;
2144 }
2145
2146 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00002147 uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002148 if (!success)
2149 {
2150 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2151 args.GetArgumentAtIndex(0));
2152 result.SetStatus (eReturnStatusFailed);
2153 return false;
2154 }
2155
2156 if (thread_plan_idx == 0)
2157 {
2158 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2159 result.SetStatus (eReturnStatusFailed);
2160 return false;
2161 }
2162
2163 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2164 {
2165 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2166 return true;
2167 }
2168 else
2169 {
2170 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2171 args.GetArgumentAtIndex(0));
2172 result.SetStatus (eReturnStatusFailed);
2173 return false;
2174 }
2175 }
2176};
2177
2178//-------------------------------------------------------------------------
2179// CommandObjectMultiwordThreadPlan
2180//-------------------------------------------------------------------------
2181
2182class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2183{
2184public:
2185 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2186 CommandObjectMultiword (interpreter,
2187 "plan",
2188 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2189 "thread plan <subcommand> [<subcommand objects]")
2190 {
2191 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2192 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2193 }
2194
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002195 ~CommandObjectMultiwordThreadPlan () override {}
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002196
2197
2198};
2199
2200//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002201// CommandObjectMultiwordThread
2202//-------------------------------------------------------------------------
2203
Greg Clayton66111032010-06-23 01:19:29 +00002204CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002205 CommandObjectMultiword (interpreter,
2206 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002207 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002208 "thread <subcommand> [<subcommand-options>]")
2209{
Greg Claytona7015092010-09-18 01:14:36 +00002210 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2211 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2212 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002213 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002214 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002215 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2216 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002217 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002218 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2219 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002220 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002221 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002222 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002223 eStepTypeInto,
2224 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00002225
Greg Claytona7015092010-09-18 01:14:36 +00002226 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2227 interpreter,
2228 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002229 "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 +00002230 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002231 eStepTypeOut,
2232 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002233
Greg Claytona7015092010-09-18 01:14:36 +00002234 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2235 interpreter,
2236 "thread step-over",
2237 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002238 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002239 eStepTypeOver,
2240 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002241
Greg Claytona7015092010-09-18 01:14:36 +00002242 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2243 interpreter,
2244 "thread step-inst",
2245 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002246 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002247 eStepTypeTrace,
2248 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002249
Greg Claytona7015092010-09-18 01:14:36 +00002250 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2251 interpreter,
2252 "thread step-inst-over",
2253 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002254 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002255 eStepTypeTraceOver,
2256 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002257
2258 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2259 interpreter,
2260 "thread step-scripted",
2261 "Step as instructed by the script class passed in the -C option.",
2262 NULL,
2263 eStepTypeScripted,
2264 eStepScopeSource)));
2265
2266 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002267}
2268
2269CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
2270{
2271}
2272
2273