blob: fa273d6b7d9665b51f3cda28165791f9a886e5c0 [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 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000512 thread = process->GetThreadList().GetSelectedThread().get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000513 if (thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000515 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000517 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000519 }
520 else
521 {
522 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
Vince Harron5275aaa2015-01-15 20:08:35 +0000523 uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000524 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000526 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
527 result.SetStatus (eReturnStatusFailed);
528 return false;
529 }
530 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000531 if (thread == nullptr)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000532 {
533 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
534 step_thread_idx, num_threads);
535 result.SetStatus (eReturnStatusFailed);
536 return false;
537 }
538 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000539
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000540 if (m_step_type == eStepTypeScripted)
541 {
542 if (m_options.m_class_name.empty())
543 {
544 result.AppendErrorWithFormat ("empty class name for scripted step.");
545 result.SetStatus(eReturnStatusFailed);
546 return false;
547 }
548 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
549 {
550 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
551 result.SetStatus(eReturnStatusFailed);
552 return false;
553 }
554 }
555
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000556 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER
557 && m_step_type != eStepTypeInto)
558 {
559 result.AppendErrorWithFormat("end line option is only valid for step into");
560 result.SetStatus(eReturnStatusFailed);
561 return false;
562 }
563
Greg Claytonf9fc6092013-01-09 19:44:40 +0000564 const bool abort_other_plans = false;
565 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
566
567 // This is a bit unfortunate, but not all the commands in this command object support
568 // only while stepping, so I use the bool for them.
569 bool bool_stop_other_threads;
570 if (m_options.m_run_mode == eAllThreads)
571 bool_stop_other_threads = false;
572 else if (m_options.m_run_mode == eOnlyDuringStepping)
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000573 bool_stop_other_threads = (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000574 else
575 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000576
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000577 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000578
579 if (m_step_type == eStepTypeInto)
580 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000581 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Stephane Sezerca05ae22015-03-26 17:47:34 +0000582 assert(frame != nullptr);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000583
Stephane Sezerca05ae22015-03-26 17:47:34 +0000584 if (frame->HasDebugInformation ())
Greg Claytonf9fc6092013-01-09 19:44:40 +0000585 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000586 AddressRange range;
587 SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000588 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER)
589 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000590 Error error;
591 if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range, error))
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000592 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000593 result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString());
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000594 result.SetStatus(eReturnStatusFailed);
595 return false;
596 }
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000597 }
Jim Ingham970bb9e2016-02-26 01:37:30 +0000598 else if (m_options.m_end_line_is_block_end)
599 {
600 Error error;
601 Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
602 if (!block)
603 {
604 result.AppendErrorWithFormat("Could not find the current block.");
605 result.SetStatus(eReturnStatusFailed);
606 return false;
607 }
608
609 AddressRange block_range;
610 Address pc_address = frame->GetFrameCodeAddress();
611 block->GetRangeContainingAddress(pc_address, block_range);
612 if (!block_range.GetBaseAddress().IsValid())
613 {
614 result.AppendErrorWithFormat("Could not find the current block address.");
615 result.SetStatus(eReturnStatusFailed);
616 return false;
617 }
618 lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress();
619 lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block;
620 range = AddressRange(pc_address, range_length);
621 }
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000622 else
623 {
624 range = sc.line_entry.range;
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000625 }
626
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000627 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000628 range,
629 frame->GetSymbolContext(eSymbolContextEverything),
630 m_options.m_step_in_target.c_str(),
631 stop_other_threads,
632 m_options.m_step_in_avoid_no_debug,
633 m_options.m_step_out_avoid_no_debug);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000634
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000635 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000636 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000637 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000638 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000639 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000640 }
641 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000642 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000643 }
644 else if (m_step_type == eStepTypeOver)
645 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000646 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000647
648 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000649 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Jason Molenda25d5b102015-12-15 00:40:30 +0000650 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000651 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000652 stop_other_threads,
653 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000654 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000655 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000656 abort_other_plans,
657 bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000658 }
659 else if (m_step_type == eStepTypeTrace)
660 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000661 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000662 }
663 else if (m_step_type == eStepTypeTraceOver)
664 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000665 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000666 }
667 else if (m_step_type == eStepTypeOut)
668 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000669 new_plan_sp = thread->QueueThreadPlanForStepOut(abort_other_plans,
670 nullptr,
671 false,
672 bool_stop_other_threads,
673 eVoteYes,
674 eVoteNoOpinion,
675 thread->GetSelectedFrameIndex(),
676 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000677 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000678 else if (m_step_type == eStepTypeScripted)
679 {
680 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
681 m_options.m_class_name.c_str(),
682 bool_stop_other_threads);
683 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000684 else
685 {
686 result.AppendError ("step type is not supported");
687 result.SetStatus (eReturnStatusFailed);
688 return false;
689 }
690
691 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
692 // so that they can be interruptible). Then resume the process.
693
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000694 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000695 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000696 new_plan_sp->SetIsMasterPlan (true);
697 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000698
699 if (m_options.m_step_count > 1)
700 {
Zachary Turner40411162014-07-16 20:28:24 +0000701 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
Jim Ingham7a88ec92014-07-08 19:28:57 +0000702 {
703 result.AppendWarning ("step operation does not support iteration count.");
704 }
705 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000706
707 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000708
Pavel Labath44464872015-05-27 12:40:32 +0000709 const uint32_t iohandler_id = process->GetIOHandlerID();
710
Greg Claytondc6224e2014-10-21 01:00:42 +0000711 StreamString stream;
712 Error error;
713 if (synchronous_execution)
714 error = process->ResumeSynchronous (&stream);
715 else
716 error = process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000717
718 // There is a race condition where this thread will return up the call stack to the main command handler
719 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
720 // a chance to call PushProcessIOHandler().
Pavel Labath44464872015-05-27 12:40:32 +0000721 process->SyncIOHandler(iohandler_id, 2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000722
723 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000724 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000725 // If any state changed events had anything to say, add that to the result
726 if (stream.GetData())
727 result.AppendMessage(stream.GetData());
728
Greg Claytonf9fc6092013-01-09 19:44:40 +0000729 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
730 result.SetDidChangeProcessState (true);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000731 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000732 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000733 else
734 {
735 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
736 }
737 }
738 else
739 {
740 result.AppendError ("Couldn't find thread plan to implement step type.");
741 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000742 }
743 return result.Succeeded();
744 }
745
746protected:
747 StepType m_step_type;
748 StepScope m_step_scope;
749 CommandOptions m_options;
750};
751
Greg Claytone0d378b2011-03-24 21:19:54 +0000752static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000753g_tri_running_mode[] =
754{
Greg Claytoned8a7052010-09-18 03:37:20 +0000755{ eOnlyThisThread, "this-thread", "Run only this thread"},
756{ eAllThreads, "all-threads", "Run all threads"},
757{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000758{ 0, nullptr, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000759};
760
Greg Claytone0d378b2011-03-24 21:19:54 +0000761static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762g_duo_running_mode[] =
763{
Greg Claytoned8a7052010-09-18 03:37:20 +0000764{ eOnlyThisThread, "this-thread", "Run only this thread"},
765{ eAllThreads, "all-threads", "Run all threads"},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000766{ 0, nullptr, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767};
768
Greg Claytone0d378b2011-03-24 21:19:54 +0000769OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
771{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000772{ 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."},
773{ 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."},
774{ 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 +0000775{ 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."
776 " You can also pass the string 'block' to step to the end of the current block."
777 " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000778{ 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."},
779{ 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."},
780{ 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."},
781{ 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."},
782{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783};
784
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785//-------------------------------------------------------------------------
786// CommandObjectThreadContinue
787//-------------------------------------------------------------------------
788
Jim Ingham5a988412012-06-08 21:56:10 +0000789class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000790{
791public:
Greg Claytona7015092010-09-18 01:14:36 +0000792 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000793 CommandObjectParsed(interpreter,
794 "thread continue",
795 "Continue execution of one or more threads in an active process.",
796 nullptr,
797 eCommandRequiresThread |
798 eCommandTryTargetAPILock |
799 eCommandProcessMustBeLaunched |
800 eCommandProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801 {
Caroline Tice405fe672010-10-04 22:28:36 +0000802 CommandArgumentEntry arg;
803 CommandArgumentData thread_idx_arg;
804
805 // Define the first (and only) variant of this arg.
806 thread_idx_arg.arg_type = eArgTypeThreadIndex;
807 thread_idx_arg.arg_repetition = eArgRepeatPlus;
808
809 // There is only one variant this argument could be; put it into the argument entry.
810 arg.push_back (thread_idx_arg);
811
812 // Push the data for the first argument into the m_arguments vector.
813 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814 }
815
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000816 ~CommandObjectThreadContinue() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000818 bool
819 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000820 {
Greg Claytona7015092010-09-18 01:14:36 +0000821 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000823 if (!m_interpreter.GetDebugger().GetSelectedTarget())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000824 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000825 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000826 result.SetStatus (eReturnStatusFailed);
827 return false;
828 }
829
Greg Claytonf9fc6092013-01-09 19:44:40 +0000830 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000831 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832 {
833 result.AppendError ("no process exists. Cannot continue");
834 result.SetStatus (eReturnStatusFailed);
835 return false;
836 }
837
838 StateType state = process->GetState();
839 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
840 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841 const size_t argc = command.GetArgumentCount();
842 if (argc > 0)
843 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000844 // These two lines appear at the beginning of both blocks in
845 // this if..else, but that is because we need to release the
846 // lock before calling process->Resume below.
847 Mutex::Locker locker (process->GetThreadList().GetMutex());
848 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000849 std::vector<Thread *> resume_threads;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000850 for (uint32_t i = 0; i < argc; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851 {
Jim Inghamce76c622012-05-31 20:48:41 +0000852 bool success;
853 const int base = 0;
Vince Harron5275aaa2015-01-15 20:08:35 +0000854 uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000855 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000856 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000857 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000858
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000859 if (thread)
860 {
861 resume_threads.push_back(thread);
862 }
863 else
864 {
865 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
866 result.SetStatus (eReturnStatusFailed);
867 return false;
868 }
Jim Inghamce76c622012-05-31 20:48:41 +0000869 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000870 else
Jim Inghamce76c622012-05-31 20:48:41 +0000871 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000872 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000873 result.SetStatus (eReturnStatusFailed);
874 return false;
875 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000877
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000878 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000879 {
880 result.AppendError ("no valid thread indexes were specified");
881 result.SetStatus (eReturnStatusFailed);
882 return false;
883 }
884 else
885 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000886 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000887 result.AppendMessageWithFormat ("Resuming thread: ");
888 else
889 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000890
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000891 for (uint32_t idx = 0; idx < num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000893 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
894 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000895
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000896 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000897 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000898 resume_threads.erase(this_thread_pos);
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000899 if (!resume_threads.empty())
Jim Inghamce76c622012-05-31 20:48:41 +0000900 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
901 else
902 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000903
904 const bool override_suspend = true;
905 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906 }
907 else
908 {
909 thread->SetResumeState (eStateSuspended);
910 }
911 }
Daniel Malead01b2952012-11-29 21:49:15 +0000912 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913 }
914 }
915 else
916 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000917 // These two lines appear at the beginning of both blocks in
918 // this if..else, but that is because we need to release the
919 // lock before calling process->Resume below.
920 Mutex::Locker locker (process->GetThreadList().GetMutex());
921 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000922 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000923 if (current_thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924 {
925 result.AppendError ("the process doesn't have a current thread");
926 result.SetStatus (eReturnStatusFailed);
927 return false;
928 }
929 // Set the actions that the threads should each take when resuming
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000930 for (uint32_t idx = 0; idx < num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000932 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000933 if (thread == current_thread)
934 {
Daniel Malead01b2952012-11-29 21:49:15 +0000935 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000936 const bool override_suspend = true;
937 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000938 }
939 else
940 {
941 thread->SetResumeState (eStateSuspended);
942 }
943 }
944 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000945
Greg Claytondc6224e2014-10-21 01:00:42 +0000946 StreamString stream;
947 Error error;
948 if (synchronous_execution)
949 error = process->ResumeSynchronous (&stream);
950 else
951 error = process->Resume ();
952
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000953 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954 if (error.Success())
955 {
Daniel Malead01b2952012-11-29 21:49:15 +0000956 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000957 if (synchronous_execution)
958 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000959 // If any state changed events had anything to say, add that to the result
960 if (stream.GetData())
961 result.AppendMessage(stream.GetData());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000962
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964 result.SetStatus (eReturnStatusSuccessFinishNoResult);
965 }
966 else
967 {
968 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
969 }
970 }
971 else
972 {
973 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
974 result.SetStatus (eReturnStatusFailed);
975 }
976 }
977 else
978 {
979 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
980 StateAsCString(state));
981 result.SetStatus (eReturnStatusFailed);
982 }
983
984 return result.Succeeded();
985 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000986};
987
988//-------------------------------------------------------------------------
989// CommandObjectThreadUntil
990//-------------------------------------------------------------------------
991
Jim Ingham5a988412012-06-08 21:56:10 +0000992class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993{
994public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995 class CommandOptions : public Options
996 {
997 public:
998 uint32_t m_thread_idx;
999 uint32_t m_frame_idx;
1000
Greg Claytoneb0103f2011-04-07 22:46:35 +00001001 CommandOptions (CommandInterpreter &interpreter) :
1002 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001003 m_thread_idx(LLDB_INVALID_THREAD_ID),
1004 m_frame_idx(LLDB_INVALID_FRAME_ID)
1005 {
Greg Claytonf6b8b582011-04-13 00:18:08 +00001006 // Keep default values of all options in one place: OptionParsingStarting ()
1007 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001008 }
1009
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001010 ~CommandOptions() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001012 Error
1013 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014 {
1015 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001016 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017
1018 switch (short_option)
1019 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001020 case 'a':
1021 {
1022 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1023 lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1024 if (error.Success())
1025 m_until_addrs.push_back(tmp_addr);
1026 }
1027 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001028 case 't':
Vince Harron5275aaa2015-01-15 20:08:35 +00001029 m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030 if (m_thread_idx == LLDB_INVALID_INDEX32)
1031 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001032 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001034 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035 case 'f':
Vince Harron5275aaa2015-01-15 20:08:35 +00001036 m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1038 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001039 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001040 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001041 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 case 'm':
1043 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001045 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001047 if (error.Success())
1048 {
1049 if (run_mode == eAllThreads)
1050 m_stop_others = false;
1051 else
1052 m_stop_others = true;
1053 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 }
1055 break;
1056 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001057 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001058 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001059 }
1060 return error;
1061 }
1062
1063 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001064 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066 m_thread_idx = LLDB_INVALID_THREAD_ID;
1067 m_frame_idx = 0;
1068 m_stop_others = false;
Jim Ingham9bdea542015-02-06 02:10:56 +00001069 m_until_addrs.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070 }
1071
Greg Claytone0d378b2011-03-24 21:19:54 +00001072 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001073 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 {
1075 return g_option_table;
1076 }
1077
1078 uint32_t m_step_thread_idx;
1079 bool m_stop_others;
Jim Ingham9bdea542015-02-06 02:10:56 +00001080 std::vector<lldb::addr_t> m_until_addrs;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081
1082 // Options table: Required for subclasses of Options.
1083
Greg Claytone0d378b2011-03-24 21:19:54 +00001084 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001085
1086 // Instance variables to hold the values for command options.
1087 };
1088
Greg Claytona7015092010-09-18 01:14:36 +00001089 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001090 CommandObjectParsed(interpreter,
1091 "thread until",
1092 "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
1093 nullptr,
1094 eCommandRequiresThread |
1095 eCommandTryTargetAPILock |
1096 eCommandProcessMustBeLaunched |
1097 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001098 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 {
Caroline Tice405fe672010-10-04 22:28:36 +00001100 CommandArgumentEntry arg;
1101 CommandArgumentData line_num_arg;
1102
1103 // Define the first (and only) variant of this arg.
1104 line_num_arg.arg_type = eArgTypeLineNum;
1105 line_num_arg.arg_repetition = eArgRepeatPlain;
1106
1107 // There is only one variant this argument could be; put it into the argument entry.
1108 arg.push_back (line_num_arg);
1109
1110 // Push the data for the first argument into the m_arguments vector.
1111 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001112 }
1113
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001114 ~CommandObjectThreadUntil() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001115
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001117 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001118 {
1119 return &m_options;
1120 }
1121
Jim Ingham5a988412012-06-08 21:56:10 +00001122protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001123 bool
1124 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125 {
Greg Claytona7015092010-09-18 01:14:36 +00001126 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127
Greg Claytona7015092010-09-18 01:14:36 +00001128 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001129 if (target == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001130 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001131 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132 result.SetStatus (eReturnStatusFailed);
1133 return false;
1134 }
1135
Greg Claytonf9fc6092013-01-09 19:44:40 +00001136 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001137 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001138 {
1139 result.AppendError ("need a valid process to step");
1140 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001141 }
1142 else
1143 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001144 Thread *thread = nullptr;
Jim Ingham9bdea542015-02-06 02:10:56 +00001145 std::vector<uint32_t> line_numbers;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001146
Jim Ingham9bdea542015-02-06 02:10:56 +00001147 if (command.GetArgumentCount() >= 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001149 size_t num_args = command.GetArgumentCount();
1150 for (size_t i = 0; i < num_args; i++)
1151 {
1152 uint32_t line_number;
1153 line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1154 if (line_number == UINT32_MAX)
1155 {
1156 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1157 result.SetStatus (eReturnStatusFailed);
1158 return false;
1159 }
1160 else
1161 line_numbers.push_back(line_number);
1162 }
1163 }
1164 else if (m_options.m_until_addrs.empty())
1165 {
1166 result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 result.SetStatus (eReturnStatusFailed);
1168 return false;
1169 }
1170
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1172 {
Jim Ingham2976d002010-08-26 21:32:51 +00001173 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 }
1175 else
1176 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001177 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001178 }
1179
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001180 if (thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181 {
1182 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001183 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1184 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001185 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186 result.SetStatus (eReturnStatusFailed);
1187 return false;
1188 }
1189
Jim Ingham7ba6e992012-05-11 23:47:32 +00001190 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191
Jason Molendab57e4a12013-11-04 09:33:30 +00001192 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001193 if (frame == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001194 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001195 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1196 m_options.m_frame_idx,
1197 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001198 result.SetStatus (eReturnStatusFailed);
1199 return false;
1200 }
1201
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001202 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001203
1204 if (frame->HasDebugInformation ())
1205 {
1206 // Finally we got here... Translate the given line number to a bunch of addresses:
1207 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001208 LineTable *line_table = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 if (sc.comp_unit)
1210 line_table = sc.comp_unit->GetLineTable();
1211
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001212 if (line_table == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213 {
1214 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1215 m_options.m_frame_idx, m_options.m_thread_idx);
1216 result.SetStatus (eReturnStatusFailed);
1217 return false;
1218 }
1219
1220 LineEntry function_start;
1221 uint32_t index_ptr = 0, end_ptr;
1222 std::vector<addr_t> address_list;
1223
1224 // Find the beginning & end index of the
1225 AddressRange fun_addr_range = sc.function->GetAddressRange();
1226 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1227 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1228
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001229 Address fun_end_addr(fun_start_addr.GetSection(),
1230 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001232 bool all_in_function = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001233
Jim Ingham9bdea542015-02-06 02:10:56 +00001234 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1235
1236 for (uint32_t line_number : line_numbers)
1237 {
1238 uint32_t start_idx_ptr = index_ptr;
1239 while (start_idx_ptr <= end_ptr)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001240 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001241 LineEntry line_entry;
1242 const bool exact = false;
1243 start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
1244 if (start_idx_ptr == UINT32_MAX)
1245 break;
1246
1247 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1248 if (address != LLDB_INVALID_ADDRESS)
1249 {
1250 if (fun_addr_range.ContainsLoadAddress (address, target))
1251 address_list.push_back (address);
1252 else
1253 all_in_function = false;
1254 }
1255 start_idx_ptr++;
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001256 }
Jim Ingham9bdea542015-02-06 02:10:56 +00001257 }
1258
1259 for (lldb::addr_t address : m_options.m_until_addrs)
1260 {
1261 if (fun_addr_range.ContainsLoadAddress (address, target))
1262 address_list.push_back (address);
1263 else
1264 all_in_function = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265 }
1266
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001267 if (address_list.empty())
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001268 {
1269 if (all_in_function)
1270 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1271 else
1272 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1273
1274 result.SetStatus (eReturnStatusFailed);
1275 return false;
1276 }
1277
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001278 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001279 &address_list.front(),
1280 address_list.size(),
1281 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001282 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001283 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1284 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1285 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001286 new_plan_sp->SetIsMasterPlan (true);
1287 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001288 }
1289 else
1290 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001291 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1292 m_options.m_frame_idx,
1293 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294 result.SetStatus (eReturnStatusFailed);
1295 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296 }
1297
Jim Ingham2976d002010-08-26 21:32:51 +00001298 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Greg Claytondc6224e2014-10-21 01:00:42 +00001299
1300 StreamString stream;
1301 Error error;
1302 if (synchronous_execution)
1303 error = process->ResumeSynchronous (&stream);
1304 else
1305 error = process->Resume ();
1306
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001307 if (error.Success())
1308 {
Daniel Malead01b2952012-11-29 21:49:15 +00001309 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001310 if (synchronous_execution)
1311 {
Greg Claytondc6224e2014-10-21 01:00:42 +00001312 // If any state changed events had anything to say, add that to the result
1313 if (stream.GetData())
1314 result.AppendMessage(stream.GetData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001315
1316 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1318 }
1319 else
1320 {
1321 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1322 }
1323 }
1324 else
1325 {
1326 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1327 result.SetStatus (eReturnStatusFailed);
1328 }
1329
1330 }
1331 return result.Succeeded();
1332 }
Jim Ingham5a988412012-06-08 21:56:10 +00001333
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001334 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001335};
1336
Greg Claytone0d378b2011-03-24 21:19:54 +00001337OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001338CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1339{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001340{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1341{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1342{ 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"},
1343{ 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."},
1344{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001345};
1346
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001347//-------------------------------------------------------------------------
1348// CommandObjectThreadSelect
1349//-------------------------------------------------------------------------
1350
Jim Ingham5a988412012-06-08 21:56:10 +00001351class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352{
1353public:
Greg Claytona7015092010-09-18 01:14:36 +00001354 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001355 CommandObjectParsed(interpreter,
1356 "thread select",
1357 "Select a thread as the currently active thread.",
1358 nullptr,
1359 eCommandRequiresProcess |
1360 eCommandTryTargetAPILock |
1361 eCommandProcessMustBeLaunched |
1362 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001363 {
Caroline Tice405fe672010-10-04 22:28:36 +00001364 CommandArgumentEntry arg;
1365 CommandArgumentData thread_idx_arg;
1366
1367 // Define the first (and only) variant of this arg.
1368 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1369 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1370
1371 // There is only one variant this argument could be; put it into the argument entry.
1372 arg.push_back (thread_idx_arg);
1373
1374 // Push the data for the first argument into the m_arguments vector.
1375 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001376 }
1377
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001378 ~CommandObjectThreadSelect() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001379
Jim Ingham5a988412012-06-08 21:56:10 +00001380protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001381 bool
1382 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001383 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001384 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001385 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001386 {
1387 result.AppendError ("no process");
1388 result.SetStatus (eReturnStatusFailed);
1389 return false;
1390 }
1391 else if (command.GetArgumentCount() != 1)
1392 {
Jason Molendafd54b362011-09-20 21:44:10 +00001393 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 +00001394 result.SetStatus (eReturnStatusFailed);
1395 return false;
1396 }
1397
Vince Harron5275aaa2015-01-15 20:08:35 +00001398 uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001399
1400 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001401 if (new_thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001402 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001403 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404 result.SetStatus (eReturnStatusFailed);
1405 return false;
1406 }
1407
Jim Inghamc3faa192012-12-11 02:31:48 +00001408 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001409 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001410
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001411 return result.Succeeded();
1412 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001413};
1414
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001415//-------------------------------------------------------------------------
1416// CommandObjectThreadList
1417//-------------------------------------------------------------------------
1418
Jim Ingham5a988412012-06-08 21:56:10 +00001419class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001420{
Greg Clayton66111032010-06-23 01:19:29 +00001421public:
Greg Claytona7015092010-09-18 01:14:36 +00001422 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001423 CommandObjectParsed (interpreter,
1424 "thread list",
1425 "Show a summary of all current threads in a process.",
1426 "thread list",
Enrico Granatae87764f2015-05-27 05:04:35 +00001427 eCommandRequiresProcess |
1428 eCommandTryTargetAPILock |
1429 eCommandProcessMustBeLaunched |
1430 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001431 {
Greg Clayton66111032010-06-23 01:19:29 +00001432 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001433
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001434 ~CommandObjectThreadList() override = default;
Greg Clayton66111032010-06-23 01:19:29 +00001435
Jim Ingham5a988412012-06-08 21:56:10 +00001436protected:
Greg Clayton66111032010-06-23 01:19:29 +00001437 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001438 DoExecute (Args& command, CommandReturnObject &result) override
Greg Clayton66111032010-06-23 01:19:29 +00001439 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001440 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001441 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001442 Process *process = m_exe_ctx.GetProcessPtr();
1443 const bool only_threads_with_stop_reason = false;
1444 const uint32_t start_frame = 0;
1445 const uint32_t num_frames = 0;
1446 const uint32_t num_frames_with_source = 0;
1447 process->GetStatus(strm);
1448 process->GetThreadStatus (strm,
1449 only_threads_with_stop_reason,
1450 start_frame,
1451 num_frames,
1452 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001453 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001454 }
Greg Clayton66111032010-06-23 01:19:29 +00001455};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001456
Jim Ingham93208b82013-01-31 21:46:01 +00001457//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001458// CommandObjectThreadInfo
1459//-------------------------------------------------------------------------
1460
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001461class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001462{
1463public:
Jason Molenda705b1802014-06-13 02:37:02 +00001464 class CommandOptions : public Options
1465 {
1466 public:
Jason Molenda705b1802014-06-13 02:37:02 +00001467 CommandOptions (CommandInterpreter &interpreter) :
1468 Options (interpreter)
1469 {
1470 OptionParsingStarting ();
1471 }
1472
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001473 ~CommandOptions() override = default;
1474
Jason Molenda705b1802014-06-13 02:37:02 +00001475 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001476 OptionParsingStarting () override
Jason Molenda705b1802014-06-13 02:37:02 +00001477 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001478 m_json_thread = false;
1479 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001480 }
1481
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001482 Error
1483 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jason Molenda705b1802014-06-13 02:37:02 +00001484 {
1485 const int short_option = m_getopt_table[option_idx].val;
1486 Error error;
1487
1488 switch (short_option)
1489 {
1490 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001491 m_json_thread = true;
1492 break;
1493
1494 case 's':
1495 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001496 break;
1497
Kuba Breckaafdf8422014-10-10 23:43:03 +00001498 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001499 return Error("invalid short option character '%c'", short_option);
Jason Molenda705b1802014-06-13 02:37:02 +00001500 }
1501 return error;
1502 }
1503
1504 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001505 GetDefinitions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001506 {
1507 return g_option_table;
1508 }
1509
Kuba Breckaafdf8422014-10-10 23:43:03 +00001510 bool m_json_thread;
1511 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001512
1513 static OptionDefinition g_option_table[];
1514 };
1515
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001516 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
1517 CommandObjectIterateOverThreads (interpreter,
1518 "thread info",
1519 "Show an extended summary of information about thread(s) in a process.",
1520 "thread info",
1521 eCommandRequiresProcess |
1522 eCommandTryTargetAPILock |
1523 eCommandProcessMustBeLaunched |
1524 eCommandProcessMustBePaused),
1525 m_options (interpreter)
1526 {
1527 m_add_return = false;
1528 }
1529
1530 ~CommandObjectThreadInfo() override = default;
1531
Jason Molenda705b1802014-06-13 02:37:02 +00001532 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001533 GetOptions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001534 {
1535 return &m_options;
1536 }
1537
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001538 bool
1539 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jason Molenda705b1802014-06-13 02:37:02 +00001540 {
Jason Molenda705b1802014-06-13 02:37:02 +00001541 Stream &strm = result.GetOutputStream();
Kuba Breckaafdf8422014-10-10 23:43:03 +00001542 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
Jason Molenda705b1802014-06-13 02:37:02 +00001543 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001544 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1545 result.SetStatus (eReturnStatusFailed);
1546 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001547 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001548 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001549 }
1550
1551 CommandOptions m_options;
Jason Molenda705b1802014-06-13 02:37:02 +00001552};
1553
1554OptionDefinition
1555CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1556{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001557 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format."},
1558 { 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 +00001559
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001560 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jason Molenda705b1802014-06-13 02:37:02 +00001561};
1562
Jason Molenda705b1802014-06-13 02:37:02 +00001563//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001564// CommandObjectThreadReturn
1565//-------------------------------------------------------------------------
1566
Jim Inghamcb640dd2012-09-14 02:14:15 +00001567class CommandObjectThreadReturn : public CommandObjectRaw
1568{
1569public:
Jim Ingham93208b82013-01-31 21:46:01 +00001570 class CommandOptions : public Options
1571 {
1572 public:
Jim Ingham93208b82013-01-31 21:46:01 +00001573 CommandOptions (CommandInterpreter &interpreter) :
1574 Options (interpreter),
1575 m_from_expression (false)
1576 {
1577 // Keep default values of all options in one place: OptionParsingStarting ()
1578 OptionParsingStarting ();
1579 }
1580
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001581 ~CommandOptions() override = default;
Jim Ingham93208b82013-01-31 21:46:01 +00001582
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001583 Error
1584 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham93208b82013-01-31 21:46:01 +00001585 {
1586 Error error;
1587 const int short_option = m_getopt_table[option_idx].val;
1588
1589 switch (short_option)
1590 {
1591 case 'x':
1592 {
1593 bool success;
1594 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1595 if (success)
1596 m_from_expression = tmp_value;
1597 else
1598 {
1599 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1600 }
1601 }
1602 break;
1603 default:
1604 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1605 break;
Jim Ingham93208b82013-01-31 21:46:01 +00001606 }
1607 return error;
1608 }
1609
1610 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001611 OptionParsingStarting () override
Jim Ingham93208b82013-01-31 21:46:01 +00001612 {
1613 m_from_expression = false;
1614 }
1615
1616 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001617 GetDefinitions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001618 {
1619 return g_option_table;
1620 }
1621
1622 bool m_from_expression;
1623
1624 // Options table: Required for subclasses of Options.
1625
1626 static OptionDefinition g_option_table[];
1627
1628 // Instance variables to hold the values for command options.
1629 };
1630
Jim Inghamcb640dd2012-09-14 02:14:15 +00001631 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1632 CommandObjectRaw (interpreter,
1633 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001634 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1635 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001636 "thread return",
Enrico Granatae87764f2015-05-27 05:04:35 +00001637 eCommandRequiresFrame |
1638 eCommandTryTargetAPILock |
1639 eCommandProcessMustBeLaunched |
1640 eCommandProcessMustBePaused ),
Jim Ingham93208b82013-01-31 21:46:01 +00001641 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001642 {
1643 CommandArgumentEntry arg;
1644 CommandArgumentData expression_arg;
1645
1646 // Define the first (and only) variant of this arg.
1647 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001648 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001649
1650 // There is only one variant this argument could be; put it into the argument entry.
1651 arg.push_back (expression_arg);
1652
1653 // Push the data for the first argument into the m_arguments vector.
1654 m_arguments.push_back (arg);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001655 }
Jim Inghamcb640dd2012-09-14 02:14:15 +00001656
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001657 ~CommandObjectThreadReturn() override = default;
1658
1659 Options *
1660 GetOptions() override
1661 {
1662 return &m_options;
1663 }
1664
1665protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001666 bool
1667 DoExecute (const char *command, CommandReturnObject &result) override
Jim Inghamcb640dd2012-09-14 02:14:15 +00001668 {
Jim Ingham93208b82013-01-31 21:46:01 +00001669 // I am going to handle this by hand, because I don't want you to have to say:
1670 // "thread return -- -5".
1671 if (command[0] == '-' && command[1] == 'x')
1672 {
1673 if (command && command[2] != '\0')
1674 result.AppendWarning("Return values ignored when returning from user called expressions");
1675
1676 Thread *thread = m_exe_ctx.GetThreadPtr();
1677 Error error;
1678 error = thread->UnwindInnermostExpression();
1679 if (!error.Success())
1680 {
1681 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1682 result.SetStatus (eReturnStatusFailed);
1683 }
1684 else
1685 {
1686 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1687 if (success)
1688 {
1689 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1690 result.SetStatus (eReturnStatusSuccessFinishResult);
1691 }
1692 else
1693 {
1694 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1695 result.SetStatus (eReturnStatusFailed);
1696 }
1697 }
1698 return result.Succeeded();
1699 }
1700
Jim Inghamcb640dd2012-09-14 02:14:15 +00001701 ValueObjectSP return_valobj_sp;
1702
Jason Molendab57e4a12013-11-04 09:33:30 +00001703 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001704 uint32_t frame_idx = frame_sp->GetFrameIndex();
1705
1706 if (frame_sp->IsInlined())
1707 {
1708 result.AppendError("Don't know how to return from inlined frames.");
1709 result.SetStatus (eReturnStatusFailed);
1710 return false;
1711 }
1712
1713 if (command && command[0] != '\0')
1714 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001715 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001716 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001717
1718 options.SetUnwindOnError(true);
1719 options.SetUseDynamic(eNoDynamicValues);
1720
Jim Ingham8646d3c2014-05-05 02:47:44 +00001721 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001722 exe_results = target->EvaluateExpression (command,
1723 frame_sp.get(),
1724 return_valobj_sp,
1725 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001726 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001727 {
1728 if (return_valobj_sp)
1729 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1730 else
1731 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1732 result.SetStatus (eReturnStatusFailed);
1733 return false;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001734 }
1735 }
1736
1737 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001738 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001739 const bool broadcast = true;
1740 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001741 if (!error.Success())
1742 {
1743 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1744 result.SetStatus (eReturnStatusFailed);
1745 return false;
1746 }
1747
Jim Inghamcb640dd2012-09-14 02:14:15 +00001748 result.SetStatus (eReturnStatusSuccessFinishResult);
1749 return true;
1750 }
Jim Ingham93208b82013-01-31 21:46:01 +00001751
1752 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001753};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001754
Jim Ingham93208b82013-01-31 21:46:01 +00001755OptionDefinition
1756CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1757{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001758{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1759{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham93208b82013-01-31 21:46:01 +00001760};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001761
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001762//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001763// CommandObjectThreadJump
1764//-------------------------------------------------------------------------
1765
1766class CommandObjectThreadJump : public CommandObjectParsed
1767{
1768public:
1769 class CommandOptions : public Options
1770 {
1771 public:
Richard Mittonf86248d2013-09-12 02:20:34 +00001772 CommandOptions (CommandInterpreter &interpreter) :
1773 Options (interpreter)
1774 {
1775 OptionParsingStarting ();
1776 }
1777
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001778 ~CommandOptions() override = default;
1779
Richard Mittonf86248d2013-09-12 02:20:34 +00001780 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001781 OptionParsingStarting () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001782 {
1783 m_filenames.Clear();
1784 m_line_num = 0;
1785 m_line_offset = 0;
1786 m_load_addr = LLDB_INVALID_ADDRESS;
1787 m_force = false;
1788 }
1789
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001790 Error
1791 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001792 {
1793 bool success;
1794 const int short_option = m_getopt_table[option_idx].val;
1795 Error error;
1796
1797 switch (short_option)
1798 {
1799 case 'f':
1800 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1801 if (m_filenames.GetSize() > 1)
1802 return Error("only one source file expected.");
1803 break;
1804 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001805 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001806 if (!success || m_line_num == 0)
1807 return Error("invalid line number: '%s'.", option_arg);
1808 break;
1809 case 'b':
Vince Harron5275aaa2015-01-15 20:08:35 +00001810 m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001811 if (!success)
1812 return Error("invalid line offset: '%s'.", option_arg);
1813 break;
1814 case 'a':
1815 {
1816 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1817 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1818 }
1819 break;
1820 case 'r':
1821 m_force = true;
1822 break;
Richard Mittonf86248d2013-09-12 02:20:34 +00001823 default:
1824 return Error("invalid short option character '%c'", short_option);
Richard Mittonf86248d2013-09-12 02:20:34 +00001825 }
1826 return error;
1827 }
1828
1829 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001830 GetDefinitions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001831 {
1832 return g_option_table;
1833 }
1834
1835 FileSpecList m_filenames;
1836 uint32_t m_line_num;
1837 int32_t m_line_offset;
1838 lldb::addr_t m_load_addr;
1839 bool m_force;
1840
1841 static OptionDefinition g_option_table[];
1842 };
1843
Richard Mittonf86248d2013-09-12 02:20:34 +00001844 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1845 CommandObjectParsed (interpreter,
1846 "thread jump",
1847 "Sets the program counter to a new address.",
1848 "thread jump",
Enrico Granatae87764f2015-05-27 05:04:35 +00001849 eCommandRequiresFrame |
1850 eCommandTryTargetAPILock |
1851 eCommandProcessMustBeLaunched |
1852 eCommandProcessMustBePaused ),
Richard Mittonf86248d2013-09-12 02:20:34 +00001853 m_options (interpreter)
1854 {
1855 }
1856
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001857 ~CommandObjectThreadJump() override = default;
1858
1859 Options *
1860 GetOptions() override
Richard Mittonf86248d2013-09-12 02:20:34 +00001861 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001862 return &m_options;
Richard Mittonf86248d2013-09-12 02:20:34 +00001863 }
1864
1865protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001866 bool DoExecute (Args& args, CommandReturnObject &result) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001867 {
1868 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001869 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001870 Thread *thread = m_exe_ctx.GetThreadPtr();
1871 Target *target = m_exe_ctx.GetTargetPtr();
1872 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1873
1874 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1875 {
1876 // Use this address directly.
1877 Address dest = Address(m_options.m_load_addr);
1878
1879 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1880 if (callAddr == LLDB_INVALID_ADDRESS)
1881 {
1882 result.AppendErrorWithFormat ("Invalid destination address.");
1883 result.SetStatus (eReturnStatusFailed);
1884 return false;
1885 }
1886
1887 if (!reg_ctx->SetPC (callAddr))
1888 {
1889 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1890 result.SetStatus (eReturnStatusFailed);
1891 return false;
1892 }
1893 }
1894 else
1895 {
1896 // Pick either the absolute line, or work out a relative one.
1897 int32_t line = (int32_t)m_options.m_line_num;
1898 if (line == 0)
1899 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1900
1901 // Try the current file, but override if asked.
1902 FileSpec file = sym_ctx.line_entry.file;
1903 if (m_options.m_filenames.GetSize() == 1)
1904 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1905
1906 if (!file)
1907 {
1908 result.AppendErrorWithFormat ("No source file available for the current location.");
1909 result.SetStatus (eReturnStatusFailed);
1910 return false;
1911 }
1912
1913 std::string warnings;
1914 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1915
1916 if (err.Fail())
1917 {
1918 result.SetError (err);
1919 return false;
1920 }
1921
1922 if (!warnings.empty())
1923 result.AppendWarning (warnings.c_str());
1924 }
1925
1926 result.SetStatus (eReturnStatusSuccessFinishResult);
1927 return true;
1928 }
1929
1930 CommandOptions m_options;
1931};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001932
Richard Mittonf86248d2013-09-12 02:20:34 +00001933OptionDefinition
1934CommandObjectThreadJump::CommandOptions::g_option_table[] =
1935{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001936 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001937 "Specifies the source file to jump to."},
1938
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001939 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001940 "Specifies the line number to jump to."},
1941
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001942 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001943 "Jumps by a relative line offset from the current line."},
1944
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001945 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001946 "Jumps to a specific address."},
1947
1948 { LLDB_OPT_SET_1|
1949 LLDB_OPT_SET_2|
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001950 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 +00001951
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001952 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Richard Mittonf86248d2013-09-12 02:20:34 +00001953};
1954
1955//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001956// Next are the subcommands of CommandObjectMultiwordThreadPlan
1957//-------------------------------------------------------------------------
1958
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001959//-------------------------------------------------------------------------
1960// CommandObjectThreadPlanList
1961//-------------------------------------------------------------------------
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001962
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001963class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1964{
1965public:
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001966 class CommandOptions : public Options
1967 {
1968 public:
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001969 CommandOptions (CommandInterpreter &interpreter) :
1970 Options(interpreter)
1971 {
1972 // Keep default values of all options in one place: OptionParsingStarting ()
1973 OptionParsingStarting ();
1974 }
1975
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001976 ~CommandOptions() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001977
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001978 Error
1979 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001980 {
1981 Error error;
1982 const int short_option = m_getopt_table[option_idx].val;
1983
1984 switch (short_option)
1985 {
1986 case 'i':
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001987 m_internal = true;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001988 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001989 case 'v':
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001990 m_verbose = true;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001991 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001992 default:
1993 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1994 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001995 }
1996 return error;
1997 }
1998
1999 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002000 OptionParsingStarting () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002001 {
2002 m_verbose = false;
2003 m_internal = false;
2004 }
2005
2006 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002007 GetDefinitions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002008 {
2009 return g_option_table;
2010 }
2011
2012 // Options table: Required for subclasses of Options.
2013
2014 static OptionDefinition g_option_table[];
2015
2016 // Instance variables to hold the values for command options.
2017 bool m_verbose;
2018 bool m_internal;
2019 };
2020
2021 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002022 CommandObjectIterateOverThreads(interpreter,
2023 "thread plan list",
2024 "Show thread plans for one or more threads. If no threads are specified, show the "
2025 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2026 nullptr,
2027 eCommandRequiresProcess |
2028 eCommandRequiresThread |
2029 eCommandTryTargetAPILock |
2030 eCommandProcessMustBeLaunched |
2031 eCommandProcessMustBePaused ),
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002032 m_options(interpreter)
2033 {
2034 }
2035
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002036 ~CommandObjectThreadPlanList() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002037
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002038 Options *
2039 GetOptions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002040 {
2041 return &m_options;
2042 }
2043
2044protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002045 bool
2046 HandleOneThread (Thread &thread, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002047 {
2048 Stream &strm = result.GetOutputStream();
2049 DescriptionLevel desc_level = eDescriptionLevelFull;
2050 if (m_options.m_verbose)
2051 desc_level = eDescriptionLevelVerbose;
2052
2053 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2054 return true;
2055 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002056
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002057 CommandOptions m_options;
2058};
2059
2060OptionDefinition
2061CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2062{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002063{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans"},
2064{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2065{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002066};
2067
2068class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2069{
2070public:
2071 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002072 CommandObjectParsed(interpreter,
2073 "thread plan discard",
2074 "Discards thread plans up to and including the plan passed as the command argument."
2075 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2076 " without the \"-i\" argument.",
2077 nullptr,
2078 eCommandRequiresProcess |
2079 eCommandRequiresThread |
2080 eCommandTryTargetAPILock |
2081 eCommandProcessMustBeLaunched |
2082 eCommandProcessMustBePaused )
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002083 {
2084 CommandArgumentEntry arg;
2085 CommandArgumentData plan_index_arg;
2086
2087 // Define the first (and only) variant of this arg.
2088 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2089 plan_index_arg.arg_repetition = eArgRepeatPlain;
2090
2091 // There is only one variant this argument could be; put it into the argument entry.
2092 arg.push_back (plan_index_arg);
2093
2094 // Push the data for the first argument into the m_arguments vector.
2095 m_arguments.push_back (arg);
2096 }
2097
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002098 ~CommandObjectThreadPlanDiscard() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002099
2100 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002101 DoExecute (Args& args, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002102 {
2103 Thread *thread = m_exe_ctx.GetThreadPtr();
2104 if (args.GetArgumentCount() != 1)
2105 {
2106 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2107 args.GetArgumentCount());
2108 result.SetStatus (eReturnStatusFailed);
2109 return false;
2110 }
2111
2112 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00002113 uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002114 if (!success)
2115 {
2116 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2117 args.GetArgumentAtIndex(0));
2118 result.SetStatus (eReturnStatusFailed);
2119 return false;
2120 }
2121
2122 if (thread_plan_idx == 0)
2123 {
2124 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2125 result.SetStatus (eReturnStatusFailed);
2126 return false;
2127 }
2128
2129 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2130 {
2131 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2132 return true;
2133 }
2134 else
2135 {
2136 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2137 args.GetArgumentAtIndex(0));
2138 result.SetStatus (eReturnStatusFailed);
2139 return false;
2140 }
2141 }
2142};
2143
2144//-------------------------------------------------------------------------
2145// CommandObjectMultiwordThreadPlan
2146//-------------------------------------------------------------------------
2147
2148class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2149{
2150public:
2151 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2152 CommandObjectMultiword (interpreter,
2153 "plan",
2154 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2155 "thread plan <subcommand> [<subcommand objects]")
2156 {
2157 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2158 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2159 }
2160
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002161 ~CommandObjectMultiwordThreadPlan() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002162};
2163
2164//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002165// CommandObjectMultiwordThread
2166//-------------------------------------------------------------------------
2167
Greg Clayton66111032010-06-23 01:19:29 +00002168CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002169 CommandObjectMultiword (interpreter,
2170 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002171 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002172 "thread <subcommand> [<subcommand-options>]")
2173{
Greg Claytona7015092010-09-18 01:14:36 +00002174 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2175 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2176 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002177 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002178 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002179 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2180 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002181 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002182 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2183 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002184 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002185 "Source level single step in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002186 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002187 eStepTypeInto,
2188 eStepScopeSource)));
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002189
Greg Claytona7015092010-09-18 01:14:36 +00002190 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2191 interpreter,
2192 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002193 "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 +00002194 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002195 eStepTypeOut,
2196 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002197
Greg Claytona7015092010-09-18 01:14:36 +00002198 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2199 interpreter,
2200 "thread step-over",
2201 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002202 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002203 eStepTypeOver,
2204 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002205
Greg Claytona7015092010-09-18 01:14:36 +00002206 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2207 interpreter,
2208 "thread step-inst",
2209 "Single step one instruction in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002210 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002211 eStepTypeTrace,
2212 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002213
Greg Claytona7015092010-09-18 01:14:36 +00002214 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2215 interpreter,
2216 "thread step-inst-over",
2217 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002218 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002219 eStepTypeTraceOver,
2220 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002221
2222 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2223 interpreter,
2224 "thread step-scripted",
2225 "Step as instructed by the script class passed in the -C option.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002226 nullptr,
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002227 eStepTypeScripted,
2228 eStepScopeSource)));
2229
2230 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002231}
2232
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002233CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;