blob: 988eb5026a8f742dac196ada0b439bb4472adb56 [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 +000040using namespace lldb;
41using namespace lldb_private;
42
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043//-------------------------------------------------------------------------
44// CommandObjectThreadBacktrace
45//-------------------------------------------------------------------------
46
Jim Ingham2bdbfd52014-09-29 23:17:18 +000047class CommandObjectIterateOverThreads : public CommandObjectParsed
48{
49public:
50 CommandObjectIterateOverThreads (CommandInterpreter &interpreter,
51 const char *name,
52 const char *help,
53 const char *syntax,
54 uint32_t flags) :
55 CommandObjectParsed (interpreter, name, help, syntax, flags)
56 {
57 }
58
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +000059 ~CommandObjectIterateOverThreads() override = default;
Bruce Mitchener13d21e92015-10-07 16:56:17 +000060
61 bool
62 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +000063 {
64 result.SetStatus (m_success_return);
65
66 if (command.GetArgumentCount() == 0)
67 {
68 Thread *thread = m_exe_ctx.GetThreadPtr();
69 if (!HandleOneThread (*thread, result))
70 return false;
71 }
72 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
73 {
74 Process *process = m_exe_ctx.GetProcessPtr();
75 uint32_t idx = 0;
76 for (ThreadSP thread_sp : process->Threads())
77 {
78 if (idx != 0 && m_add_return)
79 result.AppendMessage("");
80
81 if (!HandleOneThread(*(thread_sp.get()), result))
82 return false;
83 ++idx;
84 }
85 }
86 else
87 {
88 const size_t num_args = command.GetArgumentCount();
89 Process *process = m_exe_ctx.GetProcessPtr();
90 Mutex::Locker locker (process->GetThreadList().GetMutex());
91 std::vector<ThreadSP> thread_sps;
92
93 for (size_t i = 0; i < num_args; i++)
94 {
95 bool success;
96
Vince Harron5275aaa2015-01-15 20:08:35 +000097 uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +000098 if (!success)
99 {
100 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
101 result.SetStatus (eReturnStatusFailed);
102 return false;
103 }
104
105 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
106
107 if (!thread_sps[i])
108 {
109 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
110 result.SetStatus (eReturnStatusFailed);
111 return false;
112 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000113 }
114
115 for (uint32_t i = 0; i < num_args; i++)
116 {
117 if (!HandleOneThread (*(thread_sps[i].get()), result))
118 return false;
119
120 if (i < num_args - 1 && m_add_return)
121 result.AppendMessage("");
122 }
123 }
124 return result.Succeeded();
125 }
126
127protected:
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000128 // Override this to do whatever you need to do for one thread.
129 //
130 // If you return false, the iteration will stop, otherwise it will proceed.
131 // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
132 // so you only need to set the return status in HandleOneThread if you want to indicate an error.
133 // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
134
135 virtual bool
136 HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
137
138 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
139 bool m_add_return = true;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000140};
141
142//-------------------------------------------------------------------------
143// CommandObjectThreadBacktrace
144//-------------------------------------------------------------------------
145
146class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147{
148public:
Jim Inghame2e0b452010-08-26 23:36:03 +0000149 class CommandOptions : public Options
150 {
151 public:
Greg Claytoneb0103f2011-04-07 22:46:35 +0000152 CommandOptions (CommandInterpreter &interpreter) :
153 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +0000154 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000155 // Keep default values of all options in one place: OptionParsingStarting ()
156 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +0000157 }
158
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000159 ~CommandOptions() override = default;
Jim Inghame2e0b452010-08-26 23:36:03 +0000160
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000161 Error
162 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Inghame2e0b452010-08-26 23:36:03 +0000163 {
164 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000165 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame2e0b452010-08-26 23:36:03 +0000166
167 switch (short_option)
168 {
169 case 'c':
170 {
171 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +0000172 int32_t input_count = StringConvert::ToSInt32 (option_arg, -1, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000173 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000174 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000175 if (input_count < -1)
176 m_count = UINT32_MAX;
177 else
178 m_count = input_count;
179 }
180 break;
181 case 's':
182 {
183 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +0000184 m_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000185 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000186 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000187 }
Jim Ingham1f5fcf82016-02-06 00:31:23 +0000188 break;
Jason Molenda750ea692013-11-12 07:02:07 +0000189 case 'e':
190 {
191 bool success;
192 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
193 if (!success)
194 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
195 }
Jim Inghame2e0b452010-08-26 23:36:03 +0000196 break;
197 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000198 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000199 break;
Jim Inghame2e0b452010-08-26 23:36:03 +0000200 }
201 return error;
202 }
203
204 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000205 OptionParsingStarting () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000206 {
Greg Clayton7260f622011-04-18 08:33:37 +0000207 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000208 m_start = 0;
Jason Molenda750ea692013-11-12 07:02:07 +0000209 m_extended_backtrace = false;
Jim Inghame2e0b452010-08-26 23:36:03 +0000210 }
211
Greg Claytone0d378b2011-03-24 21:19:54 +0000212 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000213 GetDefinitions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000214 {
215 return g_option_table;
216 }
217
218 // Options table: Required for subclasses of Options.
219
Greg Claytone0d378b2011-03-24 21:19:54 +0000220 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000221
222 // Instance variables to hold the values for command options.
223 uint32_t m_count;
224 uint32_t m_start;
Jason Molenda750ea692013-11-12 07:02:07 +0000225 bool m_extended_backtrace;
Jim Inghame2e0b452010-08-26 23:36:03 +0000226 };
227
Greg Claytona7015092010-09-18 01:14:36 +0000228 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000229 CommandObjectIterateOverThreads(interpreter,
230 "thread backtrace",
231 "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.",
232 nullptr,
233 eCommandRequiresProcess |
234 eCommandRequiresThread |
235 eCommandTryTargetAPILock |
236 eCommandProcessMustBeLaunched |
237 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000238 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239 {
240 }
241
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000242 ~CommandObjectThreadBacktrace() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000244 Options *
245 GetOptions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000246 {
247 return &m_options;
248 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249
Jim Ingham5a988412012-06-08 21:56:10 +0000250protected:
Jason Molenda750ea692013-11-12 07:02:07 +0000251 void
252 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
253 {
254 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
255 if (runtime)
256 {
257 Stream &strm = result.GetOutputStream();
258 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
259 for (auto type : types)
260 {
Jason Molenda008c45f2013-11-12 23:33:32 +0000261 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
Jason Molenda750ea692013-11-12 07:02:07 +0000262 if (ext_thread_sp && ext_thread_sp->IsValid ())
263 {
264 const uint32_t num_frames_with_source = 0;
265 if (ext_thread_sp->GetStatus (strm,
266 m_options.m_start,
267 m_options.m_count,
268 num_frames_with_source))
269 {
270 DoExtendedBacktrace (ext_thread_sp.get(), result);
271 }
272 }
273 }
274 }
275 }
276
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000277 bool
278 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000279 {
Greg Clayton7260f622011-04-18 08:33:37 +0000280 Stream &strm = result.GetOutputStream();
281
282 // Don't show source context when doing backtraces.
283 const uint32_t num_frames_with_source = 0;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000284
285 if (!thread.GetStatus (strm,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000286 m_options.m_start,
287 m_options.m_count,
288 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000289 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000290 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID());
291 result.SetStatus (eReturnStatusFailed);
292 return false;
Jim Ingham09b263e2010-08-27 00:58:05 +0000293 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000294 if (m_options.m_extended_backtrace)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000296 DoExtendedBacktrace (&thread, result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000298
299 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 }
Jim Ingham5a988412012-06-08 21:56:10 +0000301
Jim Inghame2e0b452010-08-26 23:36:03 +0000302 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303};
304
Greg Claytone0d378b2011-03-24 21:19:54 +0000305OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000306CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
307{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000308{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
309{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
310{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
311{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Inghame2e0b452010-08-26 23:36:03 +0000312};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313
Greg Clayton69b518f2010-07-07 17:07:17 +0000314enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315{
316 eStepScopeSource,
317 eStepScopeInstruction
318};
319
Jim Ingham5a988412012-06-08 21:56:10 +0000320class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321{
322public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323 class CommandOptions : public Options
324 {
325 public:
Greg Claytoneb0103f2011-04-07 22:46:35 +0000326 CommandOptions (CommandInterpreter &interpreter) :
327 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000329 // Keep default values of all options in one place: OptionParsingStarting ()
330 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 }
332
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000333 ~CommandOptions() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000335 Error
336 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 {
338 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000339 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340
341 switch (short_option)
342 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000343 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 {
345 bool success;
Jim Ingham4b4b2472014-03-13 02:47:14 +0000346 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000348 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000349 else
350 {
351 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
352 }
353 }
354 break;
355
356 case 'A':
357 {
358 bool success;
359 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
360 if (!success)
361 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
362 else
363 {
364 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
365 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 }
367 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000368
Jim Ingham7a88ec92014-07-08 19:28:57 +0000369 case 'c':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000370 m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
371 if (m_step_count == UINT32_MAX)
372 error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000373 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000374
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000375 case 'C':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000376 m_class_name.clear();
377 m_class_name.assign(option_arg);
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000378 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000379
Greg Clayton8087ca22010-10-08 04:20:14 +0000380 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000383 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 }
385 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000386
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000387 case 'e':
388 {
Jim Ingham970bb9e2016-02-26 01:37:30 +0000389 if (strcmp(option_arg, "block") == 0)
390 {
391 m_end_line_is_block_end = 1;
392 break;
393 }
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000394 uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
395 if (tmp_end_line == UINT32_MAX)
396 error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg);
397 else
398 m_end_line = tmp_end_line;
399 break;
400 }
401 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000402
Greg Clayton8087ca22010-10-08 04:20:14 +0000403 case 'r':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000404 m_avoid_regexp.clear();
405 m_avoid_regexp.assign(option_arg);
Jim Inghama56c8002010-07-10 02:27:39 +0000406 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000407
Jim Inghamc6276822012-12-12 19:58:40 +0000408 case 't':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000409 m_step_in_target.clear();
410 m_step_in_target.assign(option_arg);
Jim Inghamc6276822012-12-12 19:58:40 +0000411 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000412
Greg Clayton8087ca22010-10-08 04:20:14 +0000413 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000414 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000415 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 }
417 return error;
418 }
419
420 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000421 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000423 m_step_in_avoid_no_debug = eLazyBoolCalculate;
424 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425 m_run_mode = eOnlyDuringStepping;
Ewan Crawford78baa192015-05-13 09:18:18 +0000426
427 // Check if we are in Non-Stop mode
428 lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000429 if (target_sp && target_sp->GetNonStopModeEnabled())
Ewan Crawford78baa192015-05-13 09:18:18 +0000430 m_run_mode = eOnlyThisThread;
431
Jim Inghama56c8002010-07-10 02:27:39 +0000432 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000433 m_step_in_target.clear();
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000434 m_class_name.clear();
Jim Ingham7a88ec92014-07-08 19:28:57 +0000435 m_step_count = 1;
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000436 m_end_line = LLDB_INVALID_LINE_NUMBER;
Jim Ingham970bb9e2016-02-26 01:37:30 +0000437 m_end_line_is_block_end = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 }
439
Greg Claytone0d378b2011-03-24 21:19:54 +0000440 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000441 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442 {
443 return g_option_table;
444 }
445
446 // Options table: Required for subclasses of Options.
447
Greg Claytone0d378b2011-03-24 21:19:54 +0000448 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449
450 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000451 LazyBool m_step_in_avoid_no_debug;
452 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000454 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000455 std::string m_step_in_target;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000456 std::string m_class_name;
Zachary Turner898e10e2015-01-09 20:15:21 +0000457 uint32_t m_step_count;
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000458 uint32_t m_end_line;
Jim Ingham970bb9e2016-02-26 01:37:30 +0000459 bool m_end_line_is_block_end;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000460 };
461
Greg Claytona7015092010-09-18 01:14:36 +0000462 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
463 const char *name,
464 const char *help,
465 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000466 StepType step_type,
467 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000468 CommandObjectParsed (interpreter, name, help, syntax,
Enrico Granatae87764f2015-05-27 05:04:35 +0000469 eCommandRequiresProcess |
470 eCommandRequiresThread |
471 eCommandTryTargetAPILock |
472 eCommandProcessMustBeLaunched |
473 eCommandProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474 m_step_type (step_type),
475 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000476 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477 {
Caroline Tice405fe672010-10-04 22:28:36 +0000478 CommandArgumentEntry arg;
479 CommandArgumentData thread_id_arg;
480
481 // Define the first (and only) variant of this arg.
482 thread_id_arg.arg_type = eArgTypeThreadID;
483 thread_id_arg.arg_repetition = eArgRepeatOptional;
484
485 // There is only one variant this argument could be; put it into the argument entry.
486 arg.push_back (thread_id_arg);
487
488 // Push the data for the first argument into the m_arguments vector.
489 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490 }
491
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000492 ~CommandObjectThreadStepWithTypeAndScope() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000495 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 {
497 return &m_options;
498 }
499
Jim Ingham5a988412012-06-08 21:56:10 +0000500protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000501 bool
502 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000503 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000504 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000505 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506
Greg Claytonf9fc6092013-01-09 19:44:40 +0000507 const uint32_t num_threads = process->GetThreadList().GetSize();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000508 Thread *thread = nullptr;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000509
510 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511 {
Jim Ingham8d94ba02016-03-12 02:45:34 +0000512 thread = GetDefaultThread();
513
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000514 if (thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000516 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000518 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000520 }
521 else
522 {
523 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
Vince Harron5275aaa2015-01-15 20:08:35 +0000524 uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000525 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000527 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
528 result.SetStatus (eReturnStatusFailed);
529 return false;
530 }
531 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000532 if (thread == nullptr)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000533 {
534 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
535 step_thread_idx, num_threads);
536 result.SetStatus (eReturnStatusFailed);
537 return false;
538 }
539 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000540
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000541 if (m_step_type == eStepTypeScripted)
542 {
543 if (m_options.m_class_name.empty())
544 {
545 result.AppendErrorWithFormat ("empty class name for scripted step.");
546 result.SetStatus(eReturnStatusFailed);
547 return false;
548 }
549 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
550 {
551 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
552 result.SetStatus(eReturnStatusFailed);
553 return false;
554 }
555 }
556
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000557 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER
558 && m_step_type != eStepTypeInto)
559 {
560 result.AppendErrorWithFormat("end line option is only valid for step into");
561 result.SetStatus(eReturnStatusFailed);
562 return false;
563 }
564
Greg Claytonf9fc6092013-01-09 19:44:40 +0000565 const bool abort_other_plans = false;
566 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
567
568 // This is a bit unfortunate, but not all the commands in this command object support
569 // only while stepping, so I use the bool for them.
570 bool bool_stop_other_threads;
571 if (m_options.m_run_mode == eAllThreads)
572 bool_stop_other_threads = false;
573 else if (m_options.m_run_mode == eOnlyDuringStepping)
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000574 bool_stop_other_threads = (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000575 else
576 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000577
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000578 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000579
580 if (m_step_type == eStepTypeInto)
581 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000582 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Stephane Sezerca05ae22015-03-26 17:47:34 +0000583 assert(frame != nullptr);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000584
Stephane Sezerca05ae22015-03-26 17:47:34 +0000585 if (frame->HasDebugInformation ())
Greg Claytonf9fc6092013-01-09 19:44:40 +0000586 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000587 AddressRange range;
588 SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000589 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER)
590 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000591 Error error;
592 if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range, error))
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000593 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000594 result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString());
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000595 result.SetStatus(eReturnStatusFailed);
596 return false;
597 }
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000598 }
Jim Ingham970bb9e2016-02-26 01:37:30 +0000599 else if (m_options.m_end_line_is_block_end)
600 {
601 Error error;
602 Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
603 if (!block)
604 {
605 result.AppendErrorWithFormat("Could not find the current block.");
606 result.SetStatus(eReturnStatusFailed);
607 return false;
608 }
609
610 AddressRange block_range;
611 Address pc_address = frame->GetFrameCodeAddress();
612 block->GetRangeContainingAddress(pc_address, block_range);
613 if (!block_range.GetBaseAddress().IsValid())
614 {
615 result.AppendErrorWithFormat("Could not find the current block address.");
616 result.SetStatus(eReturnStatusFailed);
617 return false;
618 }
619 lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress();
620 lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block;
621 range = AddressRange(pc_address, range_length);
622 }
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000623 else
624 {
625 range = sc.line_entry.range;
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000626 }
627
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000628 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000629 range,
630 frame->GetSymbolContext(eSymbolContextEverything),
631 m_options.m_step_in_target.c_str(),
632 stop_other_threads,
633 m_options.m_step_in_avoid_no_debug,
634 m_options.m_step_out_avoid_no_debug);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000635
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000636 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000637 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000638 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000639 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000640 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000641 }
642 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000643 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000644 }
645 else if (m_step_type == eStepTypeOver)
646 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000647 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000648
649 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000650 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Jason Molenda25d5b102015-12-15 00:40:30 +0000651 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000652 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000653 stop_other_threads,
654 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000655 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000656 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000657 abort_other_plans,
658 bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000659 }
660 else if (m_step_type == eStepTypeTrace)
661 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000662 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000663 }
664 else if (m_step_type == eStepTypeTraceOver)
665 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000666 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000667 }
668 else if (m_step_type == eStepTypeOut)
669 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000670 new_plan_sp = thread->QueueThreadPlanForStepOut(abort_other_plans,
671 nullptr,
672 false,
673 bool_stop_other_threads,
674 eVoteYes,
675 eVoteNoOpinion,
676 thread->GetSelectedFrameIndex(),
677 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000678 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000679 else if (m_step_type == eStepTypeScripted)
680 {
681 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
682 m_options.m_class_name.c_str(),
683 bool_stop_other_threads);
684 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000685 else
686 {
687 result.AppendError ("step type is not supported");
688 result.SetStatus (eReturnStatusFailed);
689 return false;
690 }
691
692 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
693 // so that they can be interruptible). Then resume the process.
694
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000695 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000696 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000697 new_plan_sp->SetIsMasterPlan (true);
698 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000699
700 if (m_options.m_step_count > 1)
701 {
Zachary Turner40411162014-07-16 20:28:24 +0000702 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
Jim Ingham7a88ec92014-07-08 19:28:57 +0000703 {
704 result.AppendWarning ("step operation does not support iteration count.");
705 }
706 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000707
708 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000709
Pavel Labath44464872015-05-27 12:40:32 +0000710 const uint32_t iohandler_id = process->GetIOHandlerID();
711
Greg Claytondc6224e2014-10-21 01:00:42 +0000712 StreamString stream;
713 Error error;
714 if (synchronous_execution)
715 error = process->ResumeSynchronous (&stream);
716 else
717 error = process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000718
719 // There is a race condition where this thread will return up the call stack to the main command handler
720 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
721 // a chance to call PushProcessIOHandler().
Pavel Labath44464872015-05-27 12:40:32 +0000722 process->SyncIOHandler(iohandler_id, 2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000723
724 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000725 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000726 // If any state changed events had anything to say, add that to the result
727 if (stream.GetData())
728 result.AppendMessage(stream.GetData());
729
Greg Claytonf9fc6092013-01-09 19:44:40 +0000730 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
731 result.SetDidChangeProcessState (true);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000732 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000734 else
735 {
736 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
737 }
738 }
739 else
740 {
741 result.AppendError ("Couldn't find thread plan to implement step type.");
742 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743 }
744 return result.Succeeded();
745 }
746
747protected:
748 StepType m_step_type;
749 StepScope m_step_scope;
750 CommandOptions m_options;
751};
752
Greg Claytone0d378b2011-03-24 21:19:54 +0000753static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754g_tri_running_mode[] =
755{
Greg Claytoned8a7052010-09-18 03:37:20 +0000756{ eOnlyThisThread, "this-thread", "Run only this thread"},
757{ eAllThreads, "all-threads", "Run all threads"},
758{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000759{ 0, nullptr, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760};
761
Greg Claytone0d378b2011-03-24 21:19:54 +0000762static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763g_duo_running_mode[] =
764{
Greg Claytoned8a7052010-09-18 03:37:20 +0000765{ eOnlyThisThread, "this-thread", "Run only this thread"},
766{ eAllThreads, "all-threads", "Run all threads"},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000767{ 0, nullptr, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000768};
769
Greg Claytone0d378b2011-03-24 21:19:54 +0000770OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
772{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000773{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
774{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
775{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
Jim Ingham970bb9e2016-02-26 01:37:30 +0000776{ LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over."
777 " You can also pass the string 'block' to step to the end of the current block."
778 " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000779{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
780{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
781{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
782{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
783{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000784};
785
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786//-------------------------------------------------------------------------
787// CommandObjectThreadContinue
788//-------------------------------------------------------------------------
789
Jim Ingham5a988412012-06-08 21:56:10 +0000790class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000791{
792public:
Greg Claytona7015092010-09-18 01:14:36 +0000793 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000794 CommandObjectParsed(interpreter,
795 "thread continue",
796 "Continue execution of one or more threads in an active process.",
797 nullptr,
798 eCommandRequiresThread |
799 eCommandTryTargetAPILock |
800 eCommandProcessMustBeLaunched |
801 eCommandProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000802 {
Caroline Tice405fe672010-10-04 22:28:36 +0000803 CommandArgumentEntry arg;
804 CommandArgumentData thread_idx_arg;
805
806 // Define the first (and only) variant of this arg.
807 thread_idx_arg.arg_type = eArgTypeThreadIndex;
808 thread_idx_arg.arg_repetition = eArgRepeatPlus;
809
810 // There is only one variant this argument could be; put it into the argument entry.
811 arg.push_back (thread_idx_arg);
812
813 // Push the data for the first argument into the m_arguments vector.
814 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000815 }
816
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000817 ~CommandObjectThreadContinue() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000818
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000819 bool
820 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821 {
Greg Claytona7015092010-09-18 01:14:36 +0000822 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000824 if (!m_interpreter.GetDebugger().GetSelectedTarget())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000826 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000827 result.SetStatus (eReturnStatusFailed);
828 return false;
829 }
830
Greg Claytonf9fc6092013-01-09 19:44:40 +0000831 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000832 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000833 {
834 result.AppendError ("no process exists. Cannot continue");
835 result.SetStatus (eReturnStatusFailed);
836 return false;
837 }
838
839 StateType state = process->GetState();
840 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
841 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842 const size_t argc = command.GetArgumentCount();
843 if (argc > 0)
844 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000845 // These two lines appear at the beginning of both blocks in
846 // this if..else, but that is because we need to release the
847 // lock before calling process->Resume below.
848 Mutex::Locker locker (process->GetThreadList().GetMutex());
849 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000850 std::vector<Thread *> resume_threads;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000851 for (uint32_t i = 0; i < argc; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852 {
Jim Inghamce76c622012-05-31 20:48:41 +0000853 bool success;
854 const int base = 0;
Vince Harron5275aaa2015-01-15 20:08:35 +0000855 uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000856 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000857 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000858 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000859
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000860 if (thread)
861 {
862 resume_threads.push_back(thread);
863 }
864 else
865 {
866 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
867 result.SetStatus (eReturnStatusFailed);
868 return false;
869 }
Jim Inghamce76c622012-05-31 20:48:41 +0000870 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871 else
Jim Inghamce76c622012-05-31 20:48:41 +0000872 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000873 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000874 result.SetStatus (eReturnStatusFailed);
875 return false;
876 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000877 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000878
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000879 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880 {
881 result.AppendError ("no valid thread indexes were specified");
882 result.SetStatus (eReturnStatusFailed);
883 return false;
884 }
885 else
886 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000887 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000888 result.AppendMessageWithFormat ("Resuming thread: ");
889 else
890 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000891
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000892 for (uint32_t idx = 0; idx < num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000893 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000894 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
895 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000896
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000897 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000899 resume_threads.erase(this_thread_pos);
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000900 if (!resume_threads.empty())
Jim Inghamce76c622012-05-31 20:48:41 +0000901 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
902 else
903 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000904
905 const bool override_suspend = true;
906 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000907 }
908 else
909 {
910 thread->SetResumeState (eStateSuspended);
911 }
912 }
Daniel Malead01b2952012-11-29 21:49:15 +0000913 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000914 }
915 }
916 else
917 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000918 // These two lines appear at the beginning of both blocks in
919 // this if..else, but that is because we need to release the
920 // lock before calling process->Resume below.
921 Mutex::Locker locker (process->GetThreadList().GetMutex());
922 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham8d94ba02016-03-12 02:45:34 +0000923 Thread *current_thread = GetDefaultThread();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000924 if (current_thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 {
926 result.AppendError ("the process doesn't have a current thread");
927 result.SetStatus (eReturnStatusFailed);
928 return false;
929 }
930 // Set the actions that the threads should each take when resuming
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000931 for (uint32_t idx = 0; idx < num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000933 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934 if (thread == current_thread)
935 {
Daniel Malead01b2952012-11-29 21:49:15 +0000936 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000937 const bool override_suspend = true;
938 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939 }
940 else
941 {
942 thread->SetResumeState (eStateSuspended);
943 }
944 }
945 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000946
Greg Claytondc6224e2014-10-21 01:00:42 +0000947 StreamString stream;
948 Error error;
949 if (synchronous_execution)
950 error = process->ResumeSynchronous (&stream);
951 else
952 error = process->Resume ();
953
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000954 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955 if (error.Success())
956 {
Daniel Malead01b2952012-11-29 21:49:15 +0000957 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000958 if (synchronous_execution)
959 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000960 // If any state changed events had anything to say, add that to the result
961 if (stream.GetData())
962 result.AppendMessage(stream.GetData());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000963
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000965 result.SetStatus (eReturnStatusSuccessFinishNoResult);
966 }
967 else
968 {
969 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
970 }
971 }
972 else
973 {
974 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
975 result.SetStatus (eReturnStatusFailed);
976 }
977 }
978 else
979 {
980 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
981 StateAsCString(state));
982 result.SetStatus (eReturnStatusFailed);
983 }
984
985 return result.Succeeded();
986 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987};
988
989//-------------------------------------------------------------------------
990// CommandObjectThreadUntil
991//-------------------------------------------------------------------------
992
Jim Ingham5a988412012-06-08 21:56:10 +0000993class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994{
995public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996 class CommandOptions : public Options
997 {
998 public:
999 uint32_t m_thread_idx;
1000 uint32_t m_frame_idx;
1001
Greg Claytoneb0103f2011-04-07 22:46:35 +00001002 CommandOptions (CommandInterpreter &interpreter) :
1003 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001004 m_thread_idx(LLDB_INVALID_THREAD_ID),
1005 m_frame_idx(LLDB_INVALID_FRAME_ID)
1006 {
Greg Claytonf6b8b582011-04-13 00:18:08 +00001007 // Keep default values of all options in one place: OptionParsingStarting ()
1008 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009 }
1010
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001011 ~CommandOptions() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001012
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001013 Error
1014 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 {
1016 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001017 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018
1019 switch (short_option)
1020 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001021 case 'a':
1022 {
1023 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1024 lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1025 if (error.Success())
1026 m_until_addrs.push_back(tmp_addr);
1027 }
1028 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 case 't':
Vince Harron5275aaa2015-01-15 20:08:35 +00001030 m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031 if (m_thread_idx == LLDB_INVALID_INDEX32)
1032 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001033 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001035 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036 case 'f':
Vince Harron5275aaa2015-01-15 20:08:35 +00001037 m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1039 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001040 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001041 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001042 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 case 'm':
1044 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001045 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001046 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001048 if (error.Success())
1049 {
1050 if (run_mode == eAllThreads)
1051 m_stop_others = false;
1052 else
1053 m_stop_others = true;
1054 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055 }
1056 break;
1057 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001058 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001059 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060 }
1061 return error;
1062 }
1063
1064 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001065 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 m_thread_idx = LLDB_INVALID_THREAD_ID;
1068 m_frame_idx = 0;
1069 m_stop_others = false;
Jim Ingham9bdea542015-02-06 02:10:56 +00001070 m_until_addrs.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001071 }
1072
Greg Claytone0d378b2011-03-24 21:19:54 +00001073 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001074 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001075 {
1076 return g_option_table;
1077 }
1078
1079 uint32_t m_step_thread_idx;
1080 bool m_stop_others;
Jim Ingham9bdea542015-02-06 02:10:56 +00001081 std::vector<lldb::addr_t> m_until_addrs;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082
1083 // Options table: Required for subclasses of Options.
1084
Greg Claytone0d378b2011-03-24 21:19:54 +00001085 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001086
1087 // Instance variables to hold the values for command options.
1088 };
1089
Greg Claytona7015092010-09-18 01:14:36 +00001090 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001091 CommandObjectParsed(interpreter,
1092 "thread until",
1093 "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
1094 nullptr,
1095 eCommandRequiresThread |
1096 eCommandTryTargetAPILock |
1097 eCommandProcessMustBeLaunched |
1098 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001099 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001100 {
Caroline Tice405fe672010-10-04 22:28:36 +00001101 CommandArgumentEntry arg;
1102 CommandArgumentData line_num_arg;
1103
1104 // Define the first (and only) variant of this arg.
1105 line_num_arg.arg_type = eArgTypeLineNum;
1106 line_num_arg.arg_repetition = eArgRepeatPlain;
1107
1108 // There is only one variant this argument could be; put it into the argument entry.
1109 arg.push_back (line_num_arg);
1110
1111 // Push the data for the first argument into the m_arguments vector.
1112 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113 }
1114
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001115 ~CommandObjectThreadUntil() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001118 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001119 {
1120 return &m_options;
1121 }
1122
Jim Ingham5a988412012-06-08 21:56:10 +00001123protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001124 bool
1125 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126 {
Greg Claytona7015092010-09-18 01:14:36 +00001127 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001128
Greg Claytona7015092010-09-18 01:14:36 +00001129 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001130 if (target == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001132 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 result.SetStatus (eReturnStatusFailed);
1134 return false;
1135 }
1136
Greg Claytonf9fc6092013-01-09 19:44:40 +00001137 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001138 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139 {
1140 result.AppendError ("need a valid process to step");
1141 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001142 }
1143 else
1144 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001145 Thread *thread = nullptr;
Jim Ingham9bdea542015-02-06 02:10:56 +00001146 std::vector<uint32_t> line_numbers;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147
Jim Ingham9bdea542015-02-06 02:10:56 +00001148 if (command.GetArgumentCount() >= 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001150 size_t num_args = command.GetArgumentCount();
1151 for (size_t i = 0; i < num_args; i++)
1152 {
1153 uint32_t line_number;
1154 line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1155 if (line_number == UINT32_MAX)
1156 {
1157 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1158 result.SetStatus (eReturnStatusFailed);
1159 return false;
1160 }
1161 else
1162 line_numbers.push_back(line_number);
1163 }
1164 }
1165 else if (m_options.m_until_addrs.empty())
1166 {
1167 result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168 result.SetStatus (eReturnStatusFailed);
1169 return false;
1170 }
1171
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1173 {
Jim Ingham8d94ba02016-03-12 02:45:34 +00001174 thread = GetDefaultThread();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001175 }
1176 else
1177 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001178 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 }
1180
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001181 if (thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182 {
1183 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001184 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1185 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001186 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187 result.SetStatus (eReturnStatusFailed);
1188 return false;
1189 }
1190
Jim Ingham7ba6e992012-05-11 23:47:32 +00001191 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192
Jason Molendab57e4a12013-11-04 09:33:30 +00001193 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001194 if (frame == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001195 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001196 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1197 m_options.m_frame_idx,
1198 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199 result.SetStatus (eReturnStatusFailed);
1200 return false;
1201 }
1202
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001203 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001204
1205 if (frame->HasDebugInformation ())
1206 {
1207 // Finally we got here... Translate the given line number to a bunch of addresses:
1208 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001209 LineTable *line_table = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001210 if (sc.comp_unit)
1211 line_table = sc.comp_unit->GetLineTable();
1212
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001213 if (line_table == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214 {
1215 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1216 m_options.m_frame_idx, m_options.m_thread_idx);
1217 result.SetStatus (eReturnStatusFailed);
1218 return false;
1219 }
1220
1221 LineEntry function_start;
1222 uint32_t index_ptr = 0, end_ptr;
1223 std::vector<addr_t> address_list;
1224
1225 // Find the beginning & end index of the
1226 AddressRange fun_addr_range = sc.function->GetAddressRange();
1227 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1228 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1229
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001230 Address fun_end_addr(fun_start_addr.GetSection(),
1231 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001232
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001233 bool all_in_function = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001234
Jim Ingham9bdea542015-02-06 02:10:56 +00001235 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1236
1237 for (uint32_t line_number : line_numbers)
1238 {
1239 uint32_t start_idx_ptr = index_ptr;
1240 while (start_idx_ptr <= end_ptr)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001241 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001242 LineEntry line_entry;
1243 const bool exact = false;
1244 start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
1245 if (start_idx_ptr == UINT32_MAX)
1246 break;
1247
1248 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1249 if (address != LLDB_INVALID_ADDRESS)
1250 {
1251 if (fun_addr_range.ContainsLoadAddress (address, target))
1252 address_list.push_back (address);
1253 else
1254 all_in_function = false;
1255 }
1256 start_idx_ptr++;
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001257 }
Jim Ingham9bdea542015-02-06 02:10:56 +00001258 }
1259
1260 for (lldb::addr_t address : m_options.m_until_addrs)
1261 {
1262 if (fun_addr_range.ContainsLoadAddress (address, target))
1263 address_list.push_back (address);
1264 else
1265 all_in_function = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001266 }
1267
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001268 if (address_list.empty())
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001269 {
1270 if (all_in_function)
1271 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1272 else
1273 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1274
1275 result.SetStatus (eReturnStatusFailed);
1276 return false;
1277 }
1278
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001279 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001280 &address_list.front(),
1281 address_list.size(),
1282 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001283 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001284 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1285 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1286 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001287 new_plan_sp->SetIsMasterPlan (true);
1288 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001289 }
1290 else
1291 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001292 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1293 m_options.m_frame_idx,
1294 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295 result.SetStatus (eReturnStatusFailed);
1296 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001297 }
1298
Jim Ingham2976d002010-08-26 21:32:51 +00001299 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Greg Claytondc6224e2014-10-21 01:00:42 +00001300
1301 StreamString stream;
1302 Error error;
1303 if (synchronous_execution)
1304 error = process->ResumeSynchronous (&stream);
1305 else
1306 error = process->Resume ();
1307
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001308 if (error.Success())
1309 {
Daniel Malead01b2952012-11-29 21:49:15 +00001310 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001311 if (synchronous_execution)
1312 {
Greg Claytondc6224e2014-10-21 01:00:42 +00001313 // If any state changed events had anything to say, add that to the result
1314 if (stream.GetData())
1315 result.AppendMessage(stream.GetData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001316
1317 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001318 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1319 }
1320 else
1321 {
1322 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1323 }
1324 }
1325 else
1326 {
1327 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1328 result.SetStatus (eReturnStatusFailed);
1329 }
1330
1331 }
1332 return result.Succeeded();
1333 }
Jim Ingham5a988412012-06-08 21:56:10 +00001334
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001335 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001336};
1337
Greg Claytone0d378b2011-03-24 21:19:54 +00001338OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1340{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001341{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1342{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1343{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"},
1344{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."},
1345{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001346};
1347
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001348//-------------------------------------------------------------------------
1349// CommandObjectThreadSelect
1350//-------------------------------------------------------------------------
1351
Jim Ingham5a988412012-06-08 21:56:10 +00001352class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001353{
1354public:
Greg Claytona7015092010-09-18 01:14:36 +00001355 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001356 CommandObjectParsed(interpreter,
1357 "thread select",
1358 "Select a thread as the currently active thread.",
1359 nullptr,
1360 eCommandRequiresProcess |
1361 eCommandTryTargetAPILock |
1362 eCommandProcessMustBeLaunched |
1363 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001364 {
Caroline Tice405fe672010-10-04 22:28:36 +00001365 CommandArgumentEntry arg;
1366 CommandArgumentData thread_idx_arg;
1367
1368 // Define the first (and only) variant of this arg.
1369 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1370 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1371
1372 // There is only one variant this argument could be; put it into the argument entry.
1373 arg.push_back (thread_idx_arg);
1374
1375 // Push the data for the first argument into the m_arguments vector.
1376 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001377 }
1378
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001379 ~CommandObjectThreadSelect() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380
Jim Ingham5a988412012-06-08 21:56:10 +00001381protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001382 bool
1383 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001384 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001385 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001386 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001387 {
1388 result.AppendError ("no process");
1389 result.SetStatus (eReturnStatusFailed);
1390 return false;
1391 }
1392 else if (command.GetArgumentCount() != 1)
1393 {
Jason Molendafd54b362011-09-20 21:44:10 +00001394 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 +00001395 result.SetStatus (eReturnStatusFailed);
1396 return false;
1397 }
1398
Vince Harron5275aaa2015-01-15 20:08:35 +00001399 uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001400
1401 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001402 if (new_thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001404 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001405 result.SetStatus (eReturnStatusFailed);
1406 return false;
1407 }
1408
Jim Inghamc3faa192012-12-11 02:31:48 +00001409 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001410 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001411
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001412 return result.Succeeded();
1413 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001414};
1415
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001416//-------------------------------------------------------------------------
1417// CommandObjectThreadList
1418//-------------------------------------------------------------------------
1419
Jim Ingham5a988412012-06-08 21:56:10 +00001420class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001421{
Greg Clayton66111032010-06-23 01:19:29 +00001422public:
Greg Claytona7015092010-09-18 01:14:36 +00001423 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001424 CommandObjectParsed (interpreter,
1425 "thread list",
1426 "Show a summary of all current threads in a process.",
1427 "thread list",
Enrico Granatae87764f2015-05-27 05:04:35 +00001428 eCommandRequiresProcess |
1429 eCommandTryTargetAPILock |
1430 eCommandProcessMustBeLaunched |
1431 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001432 {
Greg Clayton66111032010-06-23 01:19:29 +00001433 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001435 ~CommandObjectThreadList() override = default;
Greg Clayton66111032010-06-23 01:19:29 +00001436
Jim Ingham5a988412012-06-08 21:56:10 +00001437protected:
Greg Clayton66111032010-06-23 01:19:29 +00001438 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001439 DoExecute (Args& command, CommandReturnObject &result) override
Greg Clayton66111032010-06-23 01:19:29 +00001440 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001441 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001442 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001443 Process *process = m_exe_ctx.GetProcessPtr();
1444 const bool only_threads_with_stop_reason = false;
1445 const uint32_t start_frame = 0;
1446 const uint32_t num_frames = 0;
1447 const uint32_t num_frames_with_source = 0;
1448 process->GetStatus(strm);
1449 process->GetThreadStatus (strm,
1450 only_threads_with_stop_reason,
1451 start_frame,
1452 num_frames,
1453 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001454 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001455 }
Greg Clayton66111032010-06-23 01:19:29 +00001456};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001457
Jim Ingham93208b82013-01-31 21:46:01 +00001458//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001459// CommandObjectThreadInfo
1460//-------------------------------------------------------------------------
1461
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001462class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001463{
1464public:
Jason Molenda705b1802014-06-13 02:37:02 +00001465 class CommandOptions : public Options
1466 {
1467 public:
Jason Molenda705b1802014-06-13 02:37:02 +00001468 CommandOptions (CommandInterpreter &interpreter) :
1469 Options (interpreter)
1470 {
1471 OptionParsingStarting ();
1472 }
1473
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001474 ~CommandOptions() override = default;
1475
Jason Molenda705b1802014-06-13 02:37:02 +00001476 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001477 OptionParsingStarting () override
Jason Molenda705b1802014-06-13 02:37:02 +00001478 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001479 m_json_thread = false;
1480 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001481 }
1482
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001483 Error
1484 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jason Molenda705b1802014-06-13 02:37:02 +00001485 {
1486 const int short_option = m_getopt_table[option_idx].val;
1487 Error error;
1488
1489 switch (short_option)
1490 {
1491 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001492 m_json_thread = true;
1493 break;
1494
1495 case 's':
1496 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001497 break;
1498
Kuba Breckaafdf8422014-10-10 23:43:03 +00001499 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001500 return Error("invalid short option character '%c'", short_option);
Jason Molenda705b1802014-06-13 02:37:02 +00001501 }
1502 return error;
1503 }
1504
1505 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001506 GetDefinitions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001507 {
1508 return g_option_table;
1509 }
1510
Kuba Breckaafdf8422014-10-10 23:43:03 +00001511 bool m_json_thread;
1512 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001513
1514 static OptionDefinition g_option_table[];
1515 };
1516
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001517 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
1518 CommandObjectIterateOverThreads (interpreter,
1519 "thread info",
1520 "Show an extended summary of information about thread(s) in a process.",
1521 "thread info",
1522 eCommandRequiresProcess |
1523 eCommandTryTargetAPILock |
1524 eCommandProcessMustBeLaunched |
1525 eCommandProcessMustBePaused),
1526 m_options (interpreter)
1527 {
1528 m_add_return = false;
1529 }
1530
1531 ~CommandObjectThreadInfo() override = default;
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 bool
1540 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jason Molenda705b1802014-06-13 02:37:02 +00001541 {
Jason Molenda705b1802014-06-13 02:37:02 +00001542 Stream &strm = result.GetOutputStream();
Kuba Breckaafdf8422014-10-10 23:43:03 +00001543 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
Jason Molenda705b1802014-06-13 02:37:02 +00001544 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001545 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1546 result.SetStatus (eReturnStatusFailed);
1547 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001548 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001549 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001550 }
1551
1552 CommandOptions m_options;
Jason Molenda705b1802014-06-13 02:37:02 +00001553};
1554
1555OptionDefinition
1556CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1557{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001558 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format."},
1559 { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
Jason Molenda705b1802014-06-13 02:37:02 +00001560
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001561 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jason Molenda705b1802014-06-13 02:37:02 +00001562};
1563
Jason Molenda705b1802014-06-13 02:37:02 +00001564//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001565// CommandObjectThreadReturn
1566//-------------------------------------------------------------------------
1567
Jim Inghamcb640dd2012-09-14 02:14:15 +00001568class CommandObjectThreadReturn : public CommandObjectRaw
1569{
1570public:
Jim Ingham93208b82013-01-31 21:46:01 +00001571 class CommandOptions : public Options
1572 {
1573 public:
Jim Ingham93208b82013-01-31 21:46:01 +00001574 CommandOptions (CommandInterpreter &interpreter) :
1575 Options (interpreter),
1576 m_from_expression (false)
1577 {
1578 // Keep default values of all options in one place: OptionParsingStarting ()
1579 OptionParsingStarting ();
1580 }
1581
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001582 ~CommandOptions() override = default;
Jim Ingham93208b82013-01-31 21:46:01 +00001583
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001584 Error
1585 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham93208b82013-01-31 21:46:01 +00001586 {
1587 Error error;
1588 const int short_option = m_getopt_table[option_idx].val;
1589
1590 switch (short_option)
1591 {
1592 case 'x':
1593 {
1594 bool success;
1595 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1596 if (success)
1597 m_from_expression = tmp_value;
1598 else
1599 {
1600 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1601 }
1602 }
1603 break;
1604 default:
1605 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1606 break;
Jim Ingham93208b82013-01-31 21:46:01 +00001607 }
1608 return error;
1609 }
1610
1611 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001612 OptionParsingStarting () override
Jim Ingham93208b82013-01-31 21:46:01 +00001613 {
1614 m_from_expression = false;
1615 }
1616
1617 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001618 GetDefinitions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001619 {
1620 return g_option_table;
1621 }
1622
1623 bool m_from_expression;
1624
1625 // Options table: Required for subclasses of Options.
1626
1627 static OptionDefinition g_option_table[];
1628
1629 // Instance variables to hold the values for command options.
1630 };
1631
Jim Inghamcb640dd2012-09-14 02:14:15 +00001632 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1633 CommandObjectRaw (interpreter,
1634 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001635 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1636 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001637 "thread return",
Enrico Granatae87764f2015-05-27 05:04:35 +00001638 eCommandRequiresFrame |
1639 eCommandTryTargetAPILock |
1640 eCommandProcessMustBeLaunched |
1641 eCommandProcessMustBePaused ),
Jim Ingham93208b82013-01-31 21:46:01 +00001642 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001643 {
1644 CommandArgumentEntry arg;
1645 CommandArgumentData expression_arg;
1646
1647 // Define the first (and only) variant of this arg.
1648 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001649 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001650
1651 // There is only one variant this argument could be; put it into the argument entry.
1652 arg.push_back (expression_arg);
1653
1654 // Push the data for the first argument into the m_arguments vector.
1655 m_arguments.push_back (arg);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001656 }
Jim Inghamcb640dd2012-09-14 02:14:15 +00001657
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001658 ~CommandObjectThreadReturn() override = default;
1659
1660 Options *
1661 GetOptions() override
1662 {
1663 return &m_options;
1664 }
1665
1666protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001667 bool
1668 DoExecute (const char *command, CommandReturnObject &result) override
Jim Inghamcb640dd2012-09-14 02:14:15 +00001669 {
Jim Ingham93208b82013-01-31 21:46:01 +00001670 // I am going to handle this by hand, because I don't want you to have to say:
1671 // "thread return -- -5".
1672 if (command[0] == '-' && command[1] == 'x')
1673 {
1674 if (command && command[2] != '\0')
1675 result.AppendWarning("Return values ignored when returning from user called expressions");
1676
1677 Thread *thread = m_exe_ctx.GetThreadPtr();
1678 Error error;
1679 error = thread->UnwindInnermostExpression();
1680 if (!error.Success())
1681 {
1682 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1683 result.SetStatus (eReturnStatusFailed);
1684 }
1685 else
1686 {
1687 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1688 if (success)
1689 {
1690 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1691 result.SetStatus (eReturnStatusSuccessFinishResult);
1692 }
1693 else
1694 {
1695 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1696 result.SetStatus (eReturnStatusFailed);
1697 }
1698 }
1699 return result.Succeeded();
1700 }
1701
Jim Inghamcb640dd2012-09-14 02:14:15 +00001702 ValueObjectSP return_valobj_sp;
1703
Jason Molendab57e4a12013-11-04 09:33:30 +00001704 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001705 uint32_t frame_idx = frame_sp->GetFrameIndex();
1706
1707 if (frame_sp->IsInlined())
1708 {
1709 result.AppendError("Don't know how to return from inlined frames.");
1710 result.SetStatus (eReturnStatusFailed);
1711 return false;
1712 }
1713
1714 if (command && command[0] != '\0')
1715 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001716 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001717 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001718
1719 options.SetUnwindOnError(true);
1720 options.SetUseDynamic(eNoDynamicValues);
1721
Jim Ingham8646d3c2014-05-05 02:47:44 +00001722 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001723 exe_results = target->EvaluateExpression (command,
1724 frame_sp.get(),
1725 return_valobj_sp,
1726 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001727 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001728 {
1729 if (return_valobj_sp)
1730 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1731 else
1732 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1733 result.SetStatus (eReturnStatusFailed);
1734 return false;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001735 }
1736 }
1737
1738 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001739 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001740 const bool broadcast = true;
1741 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001742 if (!error.Success())
1743 {
1744 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1745 result.SetStatus (eReturnStatusFailed);
1746 return false;
1747 }
1748
Jim Inghamcb640dd2012-09-14 02:14:15 +00001749 result.SetStatus (eReturnStatusSuccessFinishResult);
1750 return true;
1751 }
Jim Ingham93208b82013-01-31 21:46:01 +00001752
1753 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001754};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001755
Jim Ingham93208b82013-01-31 21:46:01 +00001756OptionDefinition
1757CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1758{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001759{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1760{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham93208b82013-01-31 21:46:01 +00001761};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001762
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001763//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001764// CommandObjectThreadJump
1765//-------------------------------------------------------------------------
1766
1767class CommandObjectThreadJump : public CommandObjectParsed
1768{
1769public:
1770 class CommandOptions : public Options
1771 {
1772 public:
Richard Mittonf86248d2013-09-12 02:20:34 +00001773 CommandOptions (CommandInterpreter &interpreter) :
1774 Options (interpreter)
1775 {
1776 OptionParsingStarting ();
1777 }
1778
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001779 ~CommandOptions() override = default;
1780
Richard Mittonf86248d2013-09-12 02:20:34 +00001781 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001782 OptionParsingStarting () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001783 {
1784 m_filenames.Clear();
1785 m_line_num = 0;
1786 m_line_offset = 0;
1787 m_load_addr = LLDB_INVALID_ADDRESS;
1788 m_force = false;
1789 }
1790
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001791 Error
1792 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001793 {
1794 bool success;
1795 const int short_option = m_getopt_table[option_idx].val;
1796 Error error;
1797
1798 switch (short_option)
1799 {
1800 case 'f':
1801 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1802 if (m_filenames.GetSize() > 1)
1803 return Error("only one source file expected.");
1804 break;
1805 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001806 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001807 if (!success || m_line_num == 0)
1808 return Error("invalid line number: '%s'.", option_arg);
1809 break;
1810 case 'b':
Vince Harron5275aaa2015-01-15 20:08:35 +00001811 m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001812 if (!success)
1813 return Error("invalid line offset: '%s'.", option_arg);
1814 break;
1815 case 'a':
1816 {
1817 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1818 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1819 }
1820 break;
1821 case 'r':
1822 m_force = true;
1823 break;
Richard Mittonf86248d2013-09-12 02:20:34 +00001824 default:
1825 return Error("invalid short option character '%c'", short_option);
Richard Mittonf86248d2013-09-12 02:20:34 +00001826 }
1827 return error;
1828 }
1829
1830 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001831 GetDefinitions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001832 {
1833 return g_option_table;
1834 }
1835
1836 FileSpecList m_filenames;
1837 uint32_t m_line_num;
1838 int32_t m_line_offset;
1839 lldb::addr_t m_load_addr;
1840 bool m_force;
1841
1842 static OptionDefinition g_option_table[];
1843 };
1844
Richard Mittonf86248d2013-09-12 02:20:34 +00001845 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1846 CommandObjectParsed (interpreter,
1847 "thread jump",
1848 "Sets the program counter to a new address.",
1849 "thread jump",
Enrico Granatae87764f2015-05-27 05:04:35 +00001850 eCommandRequiresFrame |
1851 eCommandTryTargetAPILock |
1852 eCommandProcessMustBeLaunched |
1853 eCommandProcessMustBePaused ),
Richard Mittonf86248d2013-09-12 02:20:34 +00001854 m_options (interpreter)
1855 {
1856 }
1857
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001858 ~CommandObjectThreadJump() override = default;
1859
1860 Options *
1861 GetOptions() override
Richard Mittonf86248d2013-09-12 02:20:34 +00001862 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001863 return &m_options;
Richard Mittonf86248d2013-09-12 02:20:34 +00001864 }
1865
1866protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001867 bool DoExecute (Args& args, CommandReturnObject &result) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001868 {
1869 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001870 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001871 Thread *thread = m_exe_ctx.GetThreadPtr();
1872 Target *target = m_exe_ctx.GetTargetPtr();
1873 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1874
1875 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1876 {
1877 // Use this address directly.
1878 Address dest = Address(m_options.m_load_addr);
1879
1880 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1881 if (callAddr == LLDB_INVALID_ADDRESS)
1882 {
1883 result.AppendErrorWithFormat ("Invalid destination address.");
1884 result.SetStatus (eReturnStatusFailed);
1885 return false;
1886 }
1887
1888 if (!reg_ctx->SetPC (callAddr))
1889 {
1890 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1891 result.SetStatus (eReturnStatusFailed);
1892 return false;
1893 }
1894 }
1895 else
1896 {
1897 // Pick either the absolute line, or work out a relative one.
1898 int32_t line = (int32_t)m_options.m_line_num;
1899 if (line == 0)
1900 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1901
1902 // Try the current file, but override if asked.
1903 FileSpec file = sym_ctx.line_entry.file;
1904 if (m_options.m_filenames.GetSize() == 1)
1905 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1906
1907 if (!file)
1908 {
1909 result.AppendErrorWithFormat ("No source file available for the current location.");
1910 result.SetStatus (eReturnStatusFailed);
1911 return false;
1912 }
1913
1914 std::string warnings;
1915 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1916
1917 if (err.Fail())
1918 {
1919 result.SetError (err);
1920 return false;
1921 }
1922
1923 if (!warnings.empty())
1924 result.AppendWarning (warnings.c_str());
1925 }
1926
1927 result.SetStatus (eReturnStatusSuccessFinishResult);
1928 return true;
1929 }
1930
1931 CommandOptions m_options;
1932};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001933
Richard Mittonf86248d2013-09-12 02:20:34 +00001934OptionDefinition
1935CommandObjectThreadJump::CommandOptions::g_option_table[] =
1936{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001937 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001938 "Specifies the source file to jump to."},
1939
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001940 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001941 "Specifies the line number to jump to."},
1942
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001943 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001944 "Jumps by a relative line offset from the current line."},
1945
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001946 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001947 "Jumps to a specific address."},
1948
1949 { LLDB_OPT_SET_1|
1950 LLDB_OPT_SET_2|
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001951 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,"Allows the PC to leave the current function."},
Richard Mittonf86248d2013-09-12 02:20:34 +00001952
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001953 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Richard Mittonf86248d2013-09-12 02:20:34 +00001954};
1955
1956//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001957// Next are the subcommands of CommandObjectMultiwordThreadPlan
1958//-------------------------------------------------------------------------
1959
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001960//-------------------------------------------------------------------------
1961// CommandObjectThreadPlanList
1962//-------------------------------------------------------------------------
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001963
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001964class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1965{
1966public:
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001967 class CommandOptions : public Options
1968 {
1969 public:
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001970 CommandOptions (CommandInterpreter &interpreter) :
1971 Options(interpreter)
1972 {
1973 // Keep default values of all options in one place: OptionParsingStarting ()
1974 OptionParsingStarting ();
1975 }
1976
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001977 ~CommandOptions() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001978
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001979 Error
1980 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001981 {
1982 Error error;
1983 const int short_option = m_getopt_table[option_idx].val;
1984
1985 switch (short_option)
1986 {
1987 case 'i':
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001988 m_internal = true;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001989 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001990 case 'v':
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001991 m_verbose = true;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001992 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001993 default:
1994 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1995 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001996 }
1997 return error;
1998 }
1999
2000 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002001 OptionParsingStarting () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002002 {
2003 m_verbose = false;
2004 m_internal = false;
2005 }
2006
2007 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002008 GetDefinitions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002009 {
2010 return g_option_table;
2011 }
2012
2013 // Options table: Required for subclasses of Options.
2014
2015 static OptionDefinition g_option_table[];
2016
2017 // Instance variables to hold the values for command options.
2018 bool m_verbose;
2019 bool m_internal;
2020 };
2021
2022 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002023 CommandObjectIterateOverThreads(interpreter,
2024 "thread plan list",
2025 "Show thread plans for one or more threads. If no threads are specified, show the "
2026 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2027 nullptr,
2028 eCommandRequiresProcess |
2029 eCommandRequiresThread |
2030 eCommandTryTargetAPILock |
2031 eCommandProcessMustBeLaunched |
2032 eCommandProcessMustBePaused ),
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002033 m_options(interpreter)
2034 {
2035 }
2036
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002037 ~CommandObjectThreadPlanList() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002038
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002039 Options *
2040 GetOptions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002041 {
2042 return &m_options;
2043 }
2044
2045protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002046 bool
2047 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002048 {
2049 Stream &strm = result.GetOutputStream();
2050 DescriptionLevel desc_level = eDescriptionLevelFull;
2051 if (m_options.m_verbose)
2052 desc_level = eDescriptionLevelVerbose;
2053
2054 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2055 return true;
2056 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002057
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002058 CommandOptions m_options;
2059};
2060
2061OptionDefinition
2062CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2063{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002064{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans"},
2065{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2066{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002067};
2068
2069class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2070{
2071public:
2072 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002073 CommandObjectParsed(interpreter,
2074 "thread plan discard",
2075 "Discards thread plans up to and including the plan passed as the command argument."
2076 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2077 " without the \"-i\" argument.",
2078 nullptr,
2079 eCommandRequiresProcess |
2080 eCommandRequiresThread |
2081 eCommandTryTargetAPILock |
2082 eCommandProcessMustBeLaunched |
2083 eCommandProcessMustBePaused )
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002084 {
2085 CommandArgumentEntry arg;
2086 CommandArgumentData plan_index_arg;
2087
2088 // Define the first (and only) variant of this arg.
2089 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2090 plan_index_arg.arg_repetition = eArgRepeatPlain;
2091
2092 // There is only one variant this argument could be; put it into the argument entry.
2093 arg.push_back (plan_index_arg);
2094
2095 // Push the data for the first argument into the m_arguments vector.
2096 m_arguments.push_back (arg);
2097 }
2098
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002099 ~CommandObjectThreadPlanDiscard() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002100
2101 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002102 DoExecute (Args& args, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002103 {
2104 Thread *thread = m_exe_ctx.GetThreadPtr();
2105 if (args.GetArgumentCount() != 1)
2106 {
2107 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2108 args.GetArgumentCount());
2109 result.SetStatus (eReturnStatusFailed);
2110 return false;
2111 }
2112
2113 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00002114 uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002115 if (!success)
2116 {
2117 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2118 args.GetArgumentAtIndex(0));
2119 result.SetStatus (eReturnStatusFailed);
2120 return false;
2121 }
2122
2123 if (thread_plan_idx == 0)
2124 {
2125 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2126 result.SetStatus (eReturnStatusFailed);
2127 return false;
2128 }
2129
2130 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2131 {
2132 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2133 return true;
2134 }
2135 else
2136 {
2137 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2138 args.GetArgumentAtIndex(0));
2139 result.SetStatus (eReturnStatusFailed);
2140 return false;
2141 }
2142 }
2143};
2144
2145//-------------------------------------------------------------------------
2146// CommandObjectMultiwordThreadPlan
2147//-------------------------------------------------------------------------
2148
2149class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2150{
2151public:
2152 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2153 CommandObjectMultiword (interpreter,
2154 "plan",
2155 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2156 "thread plan <subcommand> [<subcommand objects]")
2157 {
2158 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2159 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2160 }
2161
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002162 ~CommandObjectMultiwordThreadPlan() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002163};
2164
2165//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002166// CommandObjectMultiwordThread
2167//-------------------------------------------------------------------------
2168
Greg Clayton66111032010-06-23 01:19:29 +00002169CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002170 CommandObjectMultiword (interpreter,
2171 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002172 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002173 "thread <subcommand> [<subcommand-options>]")
2174{
Greg Claytona7015092010-09-18 01:14:36 +00002175 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2176 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2177 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002178 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002179 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002180 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2181 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002182 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002183 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2184 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002185 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002186 "Source level single step in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002187 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002188 eStepTypeInto,
2189 eStepScopeSource)));
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002190
Greg Claytona7015092010-09-18 01:14:36 +00002191 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2192 interpreter,
2193 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002194 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002195 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002196 eStepTypeOut,
2197 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002198
Greg Claytona7015092010-09-18 01:14:36 +00002199 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2200 interpreter,
2201 "thread step-over",
2202 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002203 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002204 eStepTypeOver,
2205 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002206
Greg Claytona7015092010-09-18 01:14:36 +00002207 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2208 interpreter,
2209 "thread step-inst",
2210 "Single step one instruction in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002211 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002212 eStepTypeTrace,
2213 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002214
Greg Claytona7015092010-09-18 01:14:36 +00002215 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2216 interpreter,
2217 "thread step-inst-over",
2218 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002219 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002220 eStepTypeTraceOver,
2221 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002222
2223 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2224 interpreter,
2225 "thread step-scripted",
2226 "Step as instructed by the script class passed in the -C option.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002227 nullptr,
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002228 eStepTypeScripted,
2229 eStepScopeSource)));
2230
2231 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002232}
2233
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002234CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;