blob: d82d99df052e4180d7ccee8423d0bc97028eb4c4 [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();
Stephane Sezerf8104912016-03-17 18:52:41 +000069 if (!HandleOneThread (thread->GetID(), result))
Jim Ingham2bdbfd52014-09-29 23:17:18 +000070 return false;
Stephane Sezerf8104912016-03-17 18:52:41 +000071 return result.Succeeded();
Jim Ingham2bdbfd52014-09-29 23:17:18 +000072 }
Stephane Sezerf8104912016-03-17 18:52:41 +000073
74 // Use tids instead of ThreadSPs to prevent deadlocking problems which result from JIT-ing
75 // code while iterating over the (locked) ThreadSP list.
76 std::vector<lldb::tid_t> tids;
77
78 if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
Jim Ingham2bdbfd52014-09-29 23:17:18 +000079 {
80 Process *process = m_exe_ctx.GetProcessPtr();
Jim Ingham2bdbfd52014-09-29 23:17:18 +000081
Stephane Sezerf8104912016-03-17 18:52:41 +000082 for (ThreadSP thread_sp : process->Threads())
83 tids.push_back(thread_sp->GetID());
Jim Ingham2bdbfd52014-09-29 23:17:18 +000084 }
85 else
86 {
87 const size_t num_args = command.GetArgumentCount();
88 Process *process = m_exe_ctx.GetProcessPtr();
Stephane Sezerf8104912016-03-17 18:52:41 +000089
Jim Ingham2bdbfd52014-09-29 23:17:18 +000090 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Ingham2bdbfd52014-09-29 23:17:18 +000091
92 for (size_t i = 0; i < num_args; i++)
93 {
94 bool success;
Stephane Sezerf8104912016-03-17 18:52:41 +000095
Vince Harron5275aaa2015-01-15 20:08:35 +000096 uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +000097 if (!success)
98 {
99 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
100 result.SetStatus (eReturnStatusFailed);
101 return false;
102 }
Stephane Sezerf8104912016-03-17 18:52:41 +0000103
104 ThreadSP thread = process->GetThreadList().FindThreadByIndexID(thread_idx);
105
106 if (!thread)
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000107 {
108 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
109 result.SetStatus (eReturnStatusFailed);
110 return false;
111 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000112
Stephane Sezerf8104912016-03-17 18:52:41 +0000113 tids.push_back(thread->GetID());
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000114 }
115 }
Stephane Sezerf8104912016-03-17 18:52:41 +0000116
117 uint32_t idx = 0;
118 for (const lldb::tid_t &tid : tids)
119 {
120 if (idx != 0 && m_add_return)
121 result.AppendMessage("");
122
123 if (!HandleOneThread (tid, result))
124 return false;
125
126 ++idx;
127 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000128 return result.Succeeded();
129 }
130
131protected:
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000132 // Override this to do whatever you need to do for one thread.
133 //
134 // If you return false, the iteration will stop, otherwise it will proceed.
135 // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
136 // so you only need to set the return status in HandleOneThread if you want to indicate an error.
137 // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
138
139 virtual bool
Stephane Sezerf8104912016-03-17 18:52:41 +0000140 HandleOneThread (lldb::tid_t, CommandReturnObject &result) = 0;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000141
142 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
143 bool m_add_return = true;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000144};
145
146//-------------------------------------------------------------------------
147// CommandObjectThreadBacktrace
148//-------------------------------------------------------------------------
149
150class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151{
152public:
Jim Inghame2e0b452010-08-26 23:36:03 +0000153 class CommandOptions : public Options
154 {
155 public:
Greg Claytoneb0103f2011-04-07 22:46:35 +0000156 CommandOptions (CommandInterpreter &interpreter) :
157 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +0000158 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000159 // Keep default values of all options in one place: OptionParsingStarting ()
160 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +0000161 }
162
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000163 ~CommandOptions() override = default;
Jim Inghame2e0b452010-08-26 23:36:03 +0000164
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000165 Error
166 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Inghame2e0b452010-08-26 23:36:03 +0000167 {
168 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000169 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame2e0b452010-08-26 23:36:03 +0000170
171 switch (short_option)
172 {
173 case 'c':
174 {
175 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +0000176 int32_t input_count = StringConvert::ToSInt32 (option_arg, -1, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000177 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000178 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000179 if (input_count < -1)
180 m_count = UINT32_MAX;
181 else
182 m_count = input_count;
183 }
184 break;
185 case 's':
186 {
187 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +0000188 m_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000189 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000190 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000191 }
Jim Ingham1f5fcf82016-02-06 00:31:23 +0000192 break;
Jason Molenda750ea692013-11-12 07:02:07 +0000193 case 'e':
194 {
195 bool success;
196 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
197 if (!success)
198 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
199 }
Jim Inghame2e0b452010-08-26 23:36:03 +0000200 break;
201 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000202 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000203 break;
Jim Inghame2e0b452010-08-26 23:36:03 +0000204 }
205 return error;
206 }
207
208 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000209 OptionParsingStarting () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000210 {
Greg Clayton7260f622011-04-18 08:33:37 +0000211 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000212 m_start = 0;
Jason Molenda750ea692013-11-12 07:02:07 +0000213 m_extended_backtrace = false;
Jim Inghame2e0b452010-08-26 23:36:03 +0000214 }
215
Greg Claytone0d378b2011-03-24 21:19:54 +0000216 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000217 GetDefinitions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000218 {
219 return g_option_table;
220 }
221
222 // Options table: Required for subclasses of Options.
223
Greg Claytone0d378b2011-03-24 21:19:54 +0000224 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000225
226 // Instance variables to hold the values for command options.
227 uint32_t m_count;
228 uint32_t m_start;
Jason Molenda750ea692013-11-12 07:02:07 +0000229 bool m_extended_backtrace;
Jim Inghame2e0b452010-08-26 23:36:03 +0000230 };
231
Greg Claytona7015092010-09-18 01:14:36 +0000232 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000233 CommandObjectIterateOverThreads(interpreter,
234 "thread backtrace",
235 "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.",
236 nullptr,
237 eCommandRequiresProcess |
238 eCommandRequiresThread |
239 eCommandTryTargetAPILock |
240 eCommandProcessMustBeLaunched |
241 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000242 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 {
244 }
245
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000246 ~CommandObjectThreadBacktrace() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000248 Options *
249 GetOptions () override
Jim Inghame2e0b452010-08-26 23:36:03 +0000250 {
251 return &m_options;
252 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253
Jim Ingham5a988412012-06-08 21:56:10 +0000254protected:
Jason Molenda750ea692013-11-12 07:02:07 +0000255 void
256 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
257 {
258 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
259 if (runtime)
260 {
261 Stream &strm = result.GetOutputStream();
262 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
263 for (auto type : types)
264 {
Jason Molenda008c45f2013-11-12 23:33:32 +0000265 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
Jason Molenda750ea692013-11-12 07:02:07 +0000266 if (ext_thread_sp && ext_thread_sp->IsValid ())
267 {
268 const uint32_t num_frames_with_source = 0;
269 if (ext_thread_sp->GetStatus (strm,
270 m_options.m_start,
271 m_options.m_count,
272 num_frames_with_source))
273 {
274 DoExtendedBacktrace (ext_thread_sp.get(), result);
275 }
276 }
277 }
278 }
279 }
280
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000281 bool
Stephane Sezerf8104912016-03-17 18:52:41 +0000282 HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000283 {
Stephane Sezerf8104912016-03-17 18:52:41 +0000284 ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
285 if (!thread_sp)
286 {
287 result.AppendErrorWithFormat ("thread disappeared while computing backtraces: 0x%" PRIx64 "\n", tid);
288 result.SetStatus (eReturnStatusFailed);
289 return false;
290 }
291
292 Thread *thread = thread_sp.get();
293
Greg Clayton7260f622011-04-18 08:33:37 +0000294 Stream &strm = result.GetOutputStream();
295
296 // Don't show source context when doing backtraces.
297 const uint32_t num_frames_with_source = 0;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000298
Stephane Sezerf8104912016-03-17 18:52:41 +0000299 if (!thread->GetStatus (strm,
300 m_options.m_start,
301 m_options.m_count,
302 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000303 {
Stephane Sezerf8104912016-03-17 18:52:41 +0000304 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread->GetIndexID());
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000305 result.SetStatus (eReturnStatusFailed);
306 return false;
Jim Ingham09b263e2010-08-27 00:58:05 +0000307 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000308 if (m_options.m_extended_backtrace)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309 {
Stephane Sezerf8104912016-03-17 18:52:41 +0000310 DoExtendedBacktrace (thread, result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000312
313 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 }
Jim Ingham5a988412012-06-08 21:56:10 +0000315
Jim Inghame2e0b452010-08-26 23:36:03 +0000316 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317};
318
Greg Claytone0d378b2011-03-24 21:19:54 +0000319OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000320CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
321{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000322{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
323{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
324{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
325{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Inghame2e0b452010-08-26 23:36:03 +0000326};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327
Greg Clayton69b518f2010-07-07 17:07:17 +0000328enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329{
330 eStepScopeSource,
331 eStepScopeInstruction
332};
333
Jim Ingham5a988412012-06-08 21:56:10 +0000334class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335{
336public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 class CommandOptions : public Options
338 {
339 public:
Greg Claytoneb0103f2011-04-07 22:46:35 +0000340 CommandOptions (CommandInterpreter &interpreter) :
341 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000343 // Keep default values of all options in one place: OptionParsingStarting ()
344 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 }
346
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000347 ~CommandOptions() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000349 Error
350 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351 {
352 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000353 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354
355 switch (short_option)
356 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000357 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358 {
359 bool success;
Jim Ingham4b4b2472014-03-13 02:47:14 +0000360 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000362 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000363 else
364 {
365 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
366 }
367 }
368 break;
369
370 case 'A':
371 {
372 bool success;
373 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
374 if (!success)
375 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
376 else
377 {
378 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
379 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380 }
381 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000382
Jim Ingham7a88ec92014-07-08 19:28:57 +0000383 case 'c':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000384 m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
385 if (m_step_count == UINT32_MAX)
386 error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000387 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000388
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000389 case 'C':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000390 m_class_name.clear();
391 m_class_name.assign(option_arg);
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000392 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000393
Greg Clayton8087ca22010-10-08 04:20:14 +0000394 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000397 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 }
399 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000400
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000401 case 'e':
402 {
Jim Ingham970bb9e2016-02-26 01:37:30 +0000403 if (strcmp(option_arg, "block") == 0)
404 {
405 m_end_line_is_block_end = 1;
406 break;
407 }
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000408 uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
409 if (tmp_end_line == UINT32_MAX)
410 error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg);
411 else
412 m_end_line = tmp_end_line;
413 break;
414 }
415 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000416
Greg Clayton8087ca22010-10-08 04:20:14 +0000417 case 'r':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000418 m_avoid_regexp.clear();
419 m_avoid_regexp.assign(option_arg);
Jim Inghama56c8002010-07-10 02:27:39 +0000420 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000421
Jim Inghamc6276822012-12-12 19:58:40 +0000422 case 't':
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000423 m_step_in_target.clear();
424 m_step_in_target.assign(option_arg);
Jim Inghamc6276822012-12-12 19:58:40 +0000425 break;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000426
Greg Clayton8087ca22010-10-08 04:20:14 +0000427 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000428 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000429 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430 }
431 return error;
432 }
433
434 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000435 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000437 m_step_in_avoid_no_debug = eLazyBoolCalculate;
438 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 m_run_mode = eOnlyDuringStepping;
Ewan Crawford78baa192015-05-13 09:18:18 +0000440
441 // Check if we are in Non-Stop mode
442 lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000443 if (target_sp && target_sp->GetNonStopModeEnabled())
Ewan Crawford78baa192015-05-13 09:18:18 +0000444 m_run_mode = eOnlyThisThread;
445
Jim Inghama56c8002010-07-10 02:27:39 +0000446 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000447 m_step_in_target.clear();
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000448 m_class_name.clear();
Jim Ingham7a88ec92014-07-08 19:28:57 +0000449 m_step_count = 1;
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000450 m_end_line = LLDB_INVALID_LINE_NUMBER;
Jim Ingham970bb9e2016-02-26 01:37:30 +0000451 m_end_line_is_block_end = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452 }
453
Greg Claytone0d378b2011-03-24 21:19:54 +0000454 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000455 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 {
457 return g_option_table;
458 }
459
460 // Options table: Required for subclasses of Options.
461
Greg Claytone0d378b2011-03-24 21:19:54 +0000462 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463
464 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000465 LazyBool m_step_in_avoid_no_debug;
466 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000468 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000469 std::string m_step_in_target;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000470 std::string m_class_name;
Zachary Turner898e10e2015-01-09 20:15:21 +0000471 uint32_t m_step_count;
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000472 uint32_t m_end_line;
Jim Ingham970bb9e2016-02-26 01:37:30 +0000473 bool m_end_line_is_block_end;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474 };
475
Greg Claytona7015092010-09-18 01:14:36 +0000476 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
477 const char *name,
478 const char *help,
479 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000480 StepType step_type,
481 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000482 CommandObjectParsed (interpreter, name, help, syntax,
Enrico Granatae87764f2015-05-27 05:04:35 +0000483 eCommandRequiresProcess |
484 eCommandRequiresThread |
485 eCommandTryTargetAPILock |
486 eCommandProcessMustBeLaunched |
487 eCommandProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488 m_step_type (step_type),
489 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000490 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491 {
Caroline Tice405fe672010-10-04 22:28:36 +0000492 CommandArgumentEntry arg;
493 CommandArgumentData thread_id_arg;
494
495 // Define the first (and only) variant of this arg.
496 thread_id_arg.arg_type = eArgTypeThreadID;
497 thread_id_arg.arg_repetition = eArgRepeatOptional;
498
499 // There is only one variant this argument could be; put it into the argument entry.
500 arg.push_back (thread_id_arg);
501
502 // Push the data for the first argument into the m_arguments vector.
503 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504 }
505
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000506 ~CommandObjectThreadStepWithTypeAndScope() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000509 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510 {
511 return &m_options;
512 }
513
Jim Ingham5a988412012-06-08 21:56:10 +0000514protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000515 bool
516 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000518 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000519 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520
Greg Claytonf9fc6092013-01-09 19:44:40 +0000521 const uint32_t num_threads = process->GetThreadList().GetSize();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000522 Thread *thread = nullptr;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000523
524 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525 {
Jim Ingham8d94ba02016-03-12 02:45:34 +0000526 thread = GetDefaultThread();
527
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000528 if (thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000530 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000531 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000532 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000534 }
535 else
536 {
537 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
Vince Harron5275aaa2015-01-15 20:08:35 +0000538 uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000539 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000541 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
542 result.SetStatus (eReturnStatusFailed);
543 return false;
544 }
545 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000546 if (thread == nullptr)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000547 {
548 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
549 step_thread_idx, num_threads);
550 result.SetStatus (eReturnStatusFailed);
551 return false;
552 }
553 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000554
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000555 if (m_step_type == eStepTypeScripted)
556 {
557 if (m_options.m_class_name.empty())
558 {
559 result.AppendErrorWithFormat ("empty class name for scripted step.");
560 result.SetStatus(eReturnStatusFailed);
561 return false;
562 }
563 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
564 {
565 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
566 result.SetStatus(eReturnStatusFailed);
567 return false;
568 }
569 }
570
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000571 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER
572 && m_step_type != eStepTypeInto)
573 {
574 result.AppendErrorWithFormat("end line option is only valid for step into");
575 result.SetStatus(eReturnStatusFailed);
576 return false;
577 }
578
Greg Claytonf9fc6092013-01-09 19:44:40 +0000579 const bool abort_other_plans = false;
580 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
581
582 // This is a bit unfortunate, but not all the commands in this command object support
583 // only while stepping, so I use the bool for them.
584 bool bool_stop_other_threads;
585 if (m_options.m_run_mode == eAllThreads)
586 bool_stop_other_threads = false;
587 else if (m_options.m_run_mode == eOnlyDuringStepping)
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000588 bool_stop_other_threads = (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000589 else
590 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000591
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000592 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000593
594 if (m_step_type == eStepTypeInto)
595 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000596 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Stephane Sezerca05ae22015-03-26 17:47:34 +0000597 assert(frame != nullptr);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000598
Stephane Sezerca05ae22015-03-26 17:47:34 +0000599 if (frame->HasDebugInformation ())
Greg Claytonf9fc6092013-01-09 19:44:40 +0000600 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000601 AddressRange range;
602 SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000603 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER)
604 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000605 Error error;
606 if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range, error))
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000607 {
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000608 result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString());
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000609 result.SetStatus(eReturnStatusFailed);
610 return false;
611 }
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000612 }
Jim Ingham970bb9e2016-02-26 01:37:30 +0000613 else if (m_options.m_end_line_is_block_end)
614 {
615 Error error;
616 Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
617 if (!block)
618 {
619 result.AppendErrorWithFormat("Could not find the current block.");
620 result.SetStatus(eReturnStatusFailed);
621 return false;
622 }
623
624 AddressRange block_range;
625 Address pc_address = frame->GetFrameCodeAddress();
626 block->GetRangeContainingAddress(pc_address, block_range);
627 if (!block_range.GetBaseAddress().IsValid())
628 {
629 result.AppendErrorWithFormat("Could not find the current block address.");
630 result.SetStatus(eReturnStatusFailed);
631 return false;
632 }
633 lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress();
634 lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block;
635 range = AddressRange(pc_address, range_length);
636 }
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000637 else
638 {
639 range = sc.line_entry.range;
Jim Inghamc17d6bd2016-02-10 03:25:24 +0000640 }
641
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000642 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Jim Inghamcbf6f9b2016-02-13 00:31:47 +0000643 range,
644 frame->GetSymbolContext(eSymbolContextEverything),
645 m_options.m_step_in_target.c_str(),
646 stop_other_threads,
647 m_options.m_step_in_avoid_no_debug,
648 m_options.m_step_out_avoid_no_debug);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000649
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000650 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000651 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000652 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000653 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000654 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000655 }
656 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000657 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000658 }
659 else if (m_step_type == eStepTypeOver)
660 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000661 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000662
663 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000664 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Jason Molenda25d5b102015-12-15 00:40:30 +0000665 frame->GetSymbolContext(eSymbolContextEverything).line_entry,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000666 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000667 stop_other_threads,
668 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000669 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000670 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000671 abort_other_plans,
672 bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000673 }
674 else if (m_step_type == eStepTypeTrace)
675 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000676 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000677 }
678 else if (m_step_type == eStepTypeTraceOver)
679 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000680 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000681 }
682 else if (m_step_type == eStepTypeOut)
683 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000684 new_plan_sp = thread->QueueThreadPlanForStepOut(abort_other_plans,
685 nullptr,
686 false,
687 bool_stop_other_threads,
688 eVoteYes,
689 eVoteNoOpinion,
690 thread->GetSelectedFrameIndex(),
691 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000692 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000693 else if (m_step_type == eStepTypeScripted)
694 {
695 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
696 m_options.m_class_name.c_str(),
697 bool_stop_other_threads);
698 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000699 else
700 {
701 result.AppendError ("step type is not supported");
702 result.SetStatus (eReturnStatusFailed);
703 return false;
704 }
705
706 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
707 // so that they can be interruptible). Then resume the process.
708
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000709 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000710 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000711 new_plan_sp->SetIsMasterPlan (true);
712 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000713
714 if (m_options.m_step_count > 1)
715 {
Zachary Turner40411162014-07-16 20:28:24 +0000716 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
Jim Ingham7a88ec92014-07-08 19:28:57 +0000717 {
718 result.AppendWarning ("step operation does not support iteration count.");
719 }
720 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000721
722 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000723
Pavel Labath44464872015-05-27 12:40:32 +0000724 const uint32_t iohandler_id = process->GetIOHandlerID();
725
Greg Claytondc6224e2014-10-21 01:00:42 +0000726 StreamString stream;
727 Error error;
728 if (synchronous_execution)
729 error = process->ResumeSynchronous (&stream);
730 else
731 error = process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000732
733 // There is a race condition where this thread will return up the call stack to the main command handler
734 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
735 // a chance to call PushProcessIOHandler().
Pavel Labath44464872015-05-27 12:40:32 +0000736 process->SyncIOHandler(iohandler_id, 2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000737
738 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000739 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000740 // If any state changed events had anything to say, add that to the result
741 if (stream.GetData())
742 result.AppendMessage(stream.GetData());
743
Greg Claytonf9fc6092013-01-09 19:44:40 +0000744 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
745 result.SetDidChangeProcessState (true);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000746 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000747 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000748 else
749 {
750 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
751 }
752 }
753 else
754 {
755 result.AppendError ("Couldn't find thread plan to implement step type.");
756 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 }
758 return result.Succeeded();
759 }
760
761protected:
762 StepType m_step_type;
763 StepScope m_step_scope;
764 CommandOptions m_options;
765};
766
Greg Claytone0d378b2011-03-24 21:19:54 +0000767static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000768g_tri_running_mode[] =
769{
Greg Claytoned8a7052010-09-18 03:37:20 +0000770{ eOnlyThisThread, "this-thread", "Run only this thread"},
771{ eAllThreads, "all-threads", "Run all threads"},
772{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000773{ 0, nullptr, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774};
775
Greg Claytone0d378b2011-03-24 21:19:54 +0000776static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000777g_duo_running_mode[] =
778{
Greg Claytoned8a7052010-09-18 03:37:20 +0000779{ eOnlyThisThread, "this-thread", "Run only this thread"},
780{ eAllThreads, "all-threads", "Run all threads"},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000781{ 0, nullptr, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782};
783
Greg Claytone0d378b2011-03-24 21:19:54 +0000784OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
786{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000787{ 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."},
788{ 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."},
789{ 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 +0000790{ 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."
791 " You can also pass the string 'block' to step to the end of the current block."
792 " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."},
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000793{ 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."},
794{ 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."},
795{ 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."},
796{ 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."},
797{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798};
799
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800//-------------------------------------------------------------------------
801// CommandObjectThreadContinue
802//-------------------------------------------------------------------------
803
Jim Ingham5a988412012-06-08 21:56:10 +0000804class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000805{
806public:
Greg Claytona7015092010-09-18 01:14:36 +0000807 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000808 CommandObjectParsed(interpreter,
809 "thread continue",
810 "Continue execution of one or more threads in an active process.",
811 nullptr,
812 eCommandRequiresThread |
813 eCommandTryTargetAPILock |
814 eCommandProcessMustBeLaunched |
815 eCommandProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816 {
Caroline Tice405fe672010-10-04 22:28:36 +0000817 CommandArgumentEntry arg;
818 CommandArgumentData thread_idx_arg;
819
820 // Define the first (and only) variant of this arg.
821 thread_idx_arg.arg_type = eArgTypeThreadIndex;
822 thread_idx_arg.arg_repetition = eArgRepeatPlus;
823
824 // There is only one variant this argument could be; put it into the argument entry.
825 arg.push_back (thread_idx_arg);
826
827 // Push the data for the first argument into the m_arguments vector.
828 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 }
830
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000831 ~CommandObjectThreadContinue() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000833 bool
834 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835 {
Greg Claytona7015092010-09-18 01:14:36 +0000836 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000838 if (!m_interpreter.GetDebugger().GetSelectedTarget())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000839 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000840 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841 result.SetStatus (eReturnStatusFailed);
842 return false;
843 }
844
Greg Claytonf9fc6092013-01-09 19:44:40 +0000845 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000846 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000847 {
848 result.AppendError ("no process exists. Cannot continue");
849 result.SetStatus (eReturnStatusFailed);
850 return false;
851 }
852
853 StateType state = process->GetState();
854 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
855 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856 const size_t argc = command.GetArgumentCount();
857 if (argc > 0)
858 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000859 // These two lines appear at the beginning of both blocks in
860 // this if..else, but that is because we need to release the
861 // lock before calling process->Resume below.
862 Mutex::Locker locker (process->GetThreadList().GetMutex());
863 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000864 std::vector<Thread *> resume_threads;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000865 for (uint32_t i = 0; i < argc; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866 {
Jim Inghamce76c622012-05-31 20:48:41 +0000867 bool success;
868 const int base = 0;
Vince Harron5275aaa2015-01-15 20:08:35 +0000869 uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000870 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000871 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000872 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000873
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000874 if (thread)
875 {
876 resume_threads.push_back(thread);
877 }
878 else
879 {
880 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
881 result.SetStatus (eReturnStatusFailed);
882 return false;
883 }
Jim Inghamce76c622012-05-31 20:48:41 +0000884 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000885 else
Jim Inghamce76c622012-05-31 20:48:41 +0000886 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000887 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000888 result.SetStatus (eReturnStatusFailed);
889 return false;
890 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000891 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000892
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000893 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000894 {
895 result.AppendError ("no valid thread indexes were specified");
896 result.SetStatus (eReturnStatusFailed);
897 return false;
898 }
899 else
900 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000901 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000902 result.AppendMessageWithFormat ("Resuming thread: ");
903 else
904 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000905
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000906 for (uint32_t idx = 0; idx < num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000907 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000908 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
909 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000910
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000911 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000912 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000913 resume_threads.erase(this_thread_pos);
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000914 if (!resume_threads.empty())
Jim Inghamce76c622012-05-31 20:48:41 +0000915 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
916 else
917 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000918
919 const bool override_suspend = true;
920 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921 }
922 else
923 {
924 thread->SetResumeState (eStateSuspended);
925 }
926 }
Daniel Malead01b2952012-11-29 21:49:15 +0000927 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928 }
929 }
930 else
931 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000932 // These two lines appear at the beginning of both blocks in
933 // this if..else, but that is because we need to release the
934 // lock before calling process->Resume below.
935 Mutex::Locker locker (process->GetThreadList().GetMutex());
936 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham8d94ba02016-03-12 02:45:34 +0000937 Thread *current_thread = GetDefaultThread();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000938 if (current_thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939 {
940 result.AppendError ("the process doesn't have a current thread");
941 result.SetStatus (eReturnStatusFailed);
942 return false;
943 }
944 // Set the actions that the threads should each take when resuming
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +0000945 for (uint32_t idx = 0; idx < num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000947 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000948 if (thread == current_thread)
949 {
Daniel Malead01b2952012-11-29 21:49:15 +0000950 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000951 const bool override_suspend = true;
952 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000953 }
954 else
955 {
956 thread->SetResumeState (eStateSuspended);
957 }
958 }
959 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000960
Greg Claytondc6224e2014-10-21 01:00:42 +0000961 StreamString stream;
962 Error error;
963 if (synchronous_execution)
964 error = process->ResumeSynchronous (&stream);
965 else
966 error = process->Resume ();
967
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000968 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000969 if (error.Success())
970 {
Daniel Malead01b2952012-11-29 21:49:15 +0000971 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972 if (synchronous_execution)
973 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000974 // If any state changed events had anything to say, add that to the result
975 if (stream.GetData())
976 result.AppendMessage(stream.GetData());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000977
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000978 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979 result.SetStatus (eReturnStatusSuccessFinishNoResult);
980 }
981 else
982 {
983 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
984 }
985 }
986 else
987 {
988 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
989 result.SetStatus (eReturnStatusFailed);
990 }
991 }
992 else
993 {
994 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
995 StateAsCString(state));
996 result.SetStatus (eReturnStatusFailed);
997 }
998
999 return result.Succeeded();
1000 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001};
1002
1003//-------------------------------------------------------------------------
1004// CommandObjectThreadUntil
1005//-------------------------------------------------------------------------
1006
Jim Ingham5a988412012-06-08 21:56:10 +00001007class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001008{
1009public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010 class CommandOptions : public Options
1011 {
1012 public:
1013 uint32_t m_thread_idx;
1014 uint32_t m_frame_idx;
1015
Greg Claytoneb0103f2011-04-07 22:46:35 +00001016 CommandOptions (CommandInterpreter &interpreter) :
1017 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018 m_thread_idx(LLDB_INVALID_THREAD_ID),
1019 m_frame_idx(LLDB_INVALID_FRAME_ID)
1020 {
Greg Claytonf6b8b582011-04-13 00:18:08 +00001021 // Keep default values of all options in one place: OptionParsingStarting ()
1022 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001023 }
1024
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001025 ~CommandOptions() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001027 Error
1028 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 {
1030 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001031 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032
1033 switch (short_option)
1034 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001035 case 'a':
1036 {
1037 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1038 lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1039 if (error.Success())
1040 m_until_addrs.push_back(tmp_addr);
1041 }
1042 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 case 't':
Vince Harron5275aaa2015-01-15 20:08:35 +00001044 m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001045 if (m_thread_idx == LLDB_INVALID_INDEX32)
1046 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001047 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001049 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050 case 'f':
Vince Harron5275aaa2015-01-15 20:08:35 +00001051 m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1053 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001054 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001056 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057 case 'm':
1058 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001059 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001060 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001062 if (error.Success())
1063 {
1064 if (run_mode == eAllThreads)
1065 m_stop_others = false;
1066 else
1067 m_stop_others = true;
1068 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069 }
1070 break;
1071 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001072 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 }
1075 return error;
1076 }
1077
1078 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001079 OptionParsingStarting () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001080 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081 m_thread_idx = LLDB_INVALID_THREAD_ID;
1082 m_frame_idx = 0;
1083 m_stop_others = false;
Jim Ingham9bdea542015-02-06 02:10:56 +00001084 m_until_addrs.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001085 }
1086
Greg Claytone0d378b2011-03-24 21:19:54 +00001087 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001088 GetDefinitions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089 {
1090 return g_option_table;
1091 }
1092
1093 uint32_t m_step_thread_idx;
1094 bool m_stop_others;
Jim Ingham9bdea542015-02-06 02:10:56 +00001095 std::vector<lldb::addr_t> m_until_addrs;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096
1097 // Options table: Required for subclasses of Options.
1098
Greg Claytone0d378b2011-03-24 21:19:54 +00001099 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001100
1101 // Instance variables to hold the values for command options.
1102 };
1103
Greg Claytona7015092010-09-18 01:14:36 +00001104 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001105 CommandObjectParsed(interpreter,
1106 "thread until",
1107 "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
1108 nullptr,
1109 eCommandRequiresThread |
1110 eCommandTryTargetAPILock |
1111 eCommandProcessMustBeLaunched |
1112 eCommandProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001113 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001114 {
Caroline Tice405fe672010-10-04 22:28:36 +00001115 CommandArgumentEntry arg;
1116 CommandArgumentData line_num_arg;
1117
1118 // Define the first (and only) variant of this arg.
1119 line_num_arg.arg_type = eArgTypeLineNum;
1120 line_num_arg.arg_repetition = eArgRepeatPlain;
1121
1122 // There is only one variant this argument could be; put it into the argument entry.
1123 arg.push_back (line_num_arg);
1124
1125 // Push the data for the first argument into the m_arguments vector.
1126 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127 }
1128
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001129 ~CommandObjectThreadUntil() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001130
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001132 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 {
1134 return &m_options;
1135 }
1136
Jim Ingham5a988412012-06-08 21:56:10 +00001137protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001138 bool
1139 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140 {
Greg Claytona7015092010-09-18 01:14:36 +00001141 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001142
Greg Claytona7015092010-09-18 01:14:36 +00001143 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001144 if (target == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001146 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147 result.SetStatus (eReturnStatusFailed);
1148 return false;
1149 }
1150
Greg Claytonf9fc6092013-01-09 19:44:40 +00001151 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001152 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153 {
1154 result.AppendError ("need a valid process to step");
1155 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001156 }
1157 else
1158 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001159 Thread *thread = nullptr;
Jim Ingham9bdea542015-02-06 02:10:56 +00001160 std::vector<uint32_t> line_numbers;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161
Jim Ingham9bdea542015-02-06 02:10:56 +00001162 if (command.GetArgumentCount() >= 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001164 size_t num_args = command.GetArgumentCount();
1165 for (size_t i = 0; i < num_args; i++)
1166 {
1167 uint32_t line_number;
1168 line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1169 if (line_number == UINT32_MAX)
1170 {
1171 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1172 result.SetStatus (eReturnStatusFailed);
1173 return false;
1174 }
1175 else
1176 line_numbers.push_back(line_number);
1177 }
1178 }
1179 else if (m_options.m_until_addrs.empty())
1180 {
1181 result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182 result.SetStatus (eReturnStatusFailed);
1183 return false;
1184 }
1185
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1187 {
Jim Ingham8d94ba02016-03-12 02:45:34 +00001188 thread = GetDefaultThread();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001189 }
1190 else
1191 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001192 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001193 }
1194
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001195 if (thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001196 {
1197 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001198 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1199 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001200 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201 result.SetStatus (eReturnStatusFailed);
1202 return false;
1203 }
1204
Jim Ingham7ba6e992012-05-11 23:47:32 +00001205 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001206
Jason Molendab57e4a12013-11-04 09:33:30 +00001207 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001208 if (frame == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001210 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1211 m_options.m_frame_idx,
1212 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213 result.SetStatus (eReturnStatusFailed);
1214 return false;
1215 }
1216
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001217 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001218
1219 if (frame->HasDebugInformation ())
1220 {
1221 // Finally we got here... Translate the given line number to a bunch of addresses:
1222 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001223 LineTable *line_table = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001224 if (sc.comp_unit)
1225 line_table = sc.comp_unit->GetLineTable();
1226
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001227 if (line_table == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001228 {
1229 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1230 m_options.m_frame_idx, m_options.m_thread_idx);
1231 result.SetStatus (eReturnStatusFailed);
1232 return false;
1233 }
1234
1235 LineEntry function_start;
1236 uint32_t index_ptr = 0, end_ptr;
1237 std::vector<addr_t> address_list;
1238
1239 // Find the beginning & end index of the
1240 AddressRange fun_addr_range = sc.function->GetAddressRange();
1241 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1242 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1243
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001244 Address fun_end_addr(fun_start_addr.GetSection(),
1245 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001246
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001247 bool all_in_function = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001248
Jim Ingham9bdea542015-02-06 02:10:56 +00001249 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1250
1251 for (uint32_t line_number : line_numbers)
1252 {
1253 uint32_t start_idx_ptr = index_ptr;
1254 while (start_idx_ptr <= end_ptr)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001255 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001256 LineEntry line_entry;
1257 const bool exact = false;
1258 start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
1259 if (start_idx_ptr == UINT32_MAX)
1260 break;
1261
1262 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1263 if (address != LLDB_INVALID_ADDRESS)
1264 {
1265 if (fun_addr_range.ContainsLoadAddress (address, target))
1266 address_list.push_back (address);
1267 else
1268 all_in_function = false;
1269 }
1270 start_idx_ptr++;
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001271 }
Jim Ingham9bdea542015-02-06 02:10:56 +00001272 }
1273
1274 for (lldb::addr_t address : m_options.m_until_addrs)
1275 {
1276 if (fun_addr_range.ContainsLoadAddress (address, target))
1277 address_list.push_back (address);
1278 else
1279 all_in_function = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001280 }
1281
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001282 if (address_list.empty())
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001283 {
1284 if (all_in_function)
1285 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1286 else
1287 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1288
1289 result.SetStatus (eReturnStatusFailed);
1290 return false;
1291 }
1292
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001293 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001294 &address_list.front(),
1295 address_list.size(),
1296 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001297 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001298 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1299 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1300 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001301 new_plan_sp->SetIsMasterPlan (true);
1302 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001303 }
1304 else
1305 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001306 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1307 m_options.m_frame_idx,
1308 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309 result.SetStatus (eReturnStatusFailed);
1310 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001311 }
1312
Jim Ingham2976d002010-08-26 21:32:51 +00001313 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Greg Claytondc6224e2014-10-21 01:00:42 +00001314
1315 StreamString stream;
1316 Error error;
1317 if (synchronous_execution)
1318 error = process->ResumeSynchronous (&stream);
1319 else
1320 error = process->Resume ();
1321
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001322 if (error.Success())
1323 {
Daniel Malead01b2952012-11-29 21:49:15 +00001324 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001325 if (synchronous_execution)
1326 {
Greg Claytondc6224e2014-10-21 01:00:42 +00001327 // If any state changed events had anything to say, add that to the result
1328 if (stream.GetData())
1329 result.AppendMessage(stream.GetData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001330
1331 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1333 }
1334 else
1335 {
1336 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1337 }
1338 }
1339 else
1340 {
1341 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1342 result.SetStatus (eReturnStatusFailed);
1343 }
1344
1345 }
1346 return result.Succeeded();
1347 }
Jim Ingham5a988412012-06-08 21:56:10 +00001348
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001349 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350};
1351
Greg Claytone0d378b2011-03-24 21:19:54 +00001352OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001353CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1354{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001355{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1356{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1357{ 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"},
1358{ 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."},
1359{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001360};
1361
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001362//-------------------------------------------------------------------------
1363// CommandObjectThreadSelect
1364//-------------------------------------------------------------------------
1365
Jim Ingham5a988412012-06-08 21:56:10 +00001366class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001367{
1368public:
Greg Claytona7015092010-09-18 01:14:36 +00001369 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001370 CommandObjectParsed(interpreter,
1371 "thread select",
1372 "Select a thread as the currently active thread.",
1373 nullptr,
1374 eCommandRequiresProcess |
1375 eCommandTryTargetAPILock |
1376 eCommandProcessMustBeLaunched |
1377 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001378 {
Caroline Tice405fe672010-10-04 22:28:36 +00001379 CommandArgumentEntry arg;
1380 CommandArgumentData thread_idx_arg;
1381
1382 // Define the first (and only) variant of this arg.
1383 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1384 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1385
1386 // There is only one variant this argument could be; put it into the argument entry.
1387 arg.push_back (thread_idx_arg);
1388
1389 // Push the data for the first argument into the m_arguments vector.
1390 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001391 }
1392
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001393 ~CommandObjectThreadSelect() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001394
Jim Ingham5a988412012-06-08 21:56:10 +00001395protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001396 bool
1397 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001398 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001399 Process *process = m_exe_ctx.GetProcessPtr();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001400 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001401 {
1402 result.AppendError ("no process");
1403 result.SetStatus (eReturnStatusFailed);
1404 return false;
1405 }
1406 else if (command.GetArgumentCount() != 1)
1407 {
Jason Molendafd54b362011-09-20 21:44:10 +00001408 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 +00001409 result.SetStatus (eReturnStatusFailed);
1410 return false;
1411 }
1412
Vince Harron5275aaa2015-01-15 20:08:35 +00001413 uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001414
1415 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001416 if (new_thread == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001418 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001419 result.SetStatus (eReturnStatusFailed);
1420 return false;
1421 }
1422
Jim Inghamc3faa192012-12-11 02:31:48 +00001423 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001424 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001425
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001426 return result.Succeeded();
1427 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001428};
1429
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001430//-------------------------------------------------------------------------
1431// CommandObjectThreadList
1432//-------------------------------------------------------------------------
1433
Jim Ingham5a988412012-06-08 21:56:10 +00001434class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001435{
Greg Clayton66111032010-06-23 01:19:29 +00001436public:
Greg Claytona7015092010-09-18 01:14:36 +00001437 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001438 CommandObjectParsed (interpreter,
1439 "thread list",
1440 "Show a summary of all current threads in a process.",
1441 "thread list",
Enrico Granatae87764f2015-05-27 05:04:35 +00001442 eCommandRequiresProcess |
1443 eCommandTryTargetAPILock |
1444 eCommandProcessMustBeLaunched |
1445 eCommandProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001446 {
Greg Clayton66111032010-06-23 01:19:29 +00001447 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001448
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001449 ~CommandObjectThreadList() override = default;
Greg Clayton66111032010-06-23 01:19:29 +00001450
Jim Ingham5a988412012-06-08 21:56:10 +00001451protected:
Greg Clayton66111032010-06-23 01:19:29 +00001452 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001453 DoExecute (Args& command, CommandReturnObject &result) override
Greg Clayton66111032010-06-23 01:19:29 +00001454 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001455 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001456 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001457 Process *process = m_exe_ctx.GetProcessPtr();
1458 const bool only_threads_with_stop_reason = false;
1459 const uint32_t start_frame = 0;
1460 const uint32_t num_frames = 0;
1461 const uint32_t num_frames_with_source = 0;
1462 process->GetStatus(strm);
1463 process->GetThreadStatus (strm,
1464 only_threads_with_stop_reason,
1465 start_frame,
1466 num_frames,
1467 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001468 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001469 }
Greg Clayton66111032010-06-23 01:19:29 +00001470};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001471
Jim Ingham93208b82013-01-31 21:46:01 +00001472//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001473// CommandObjectThreadInfo
1474//-------------------------------------------------------------------------
1475
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001476class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001477{
1478public:
Jason Molenda705b1802014-06-13 02:37:02 +00001479 class CommandOptions : public Options
1480 {
1481 public:
Jason Molenda705b1802014-06-13 02:37:02 +00001482 CommandOptions (CommandInterpreter &interpreter) :
1483 Options (interpreter)
1484 {
1485 OptionParsingStarting ();
1486 }
1487
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001488 ~CommandOptions() override = default;
1489
Jason Molenda705b1802014-06-13 02:37:02 +00001490 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001491 OptionParsingStarting () override
Jason Molenda705b1802014-06-13 02:37:02 +00001492 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001493 m_json_thread = false;
1494 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001495 }
1496
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001497 Error
1498 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jason Molenda705b1802014-06-13 02:37:02 +00001499 {
1500 const int short_option = m_getopt_table[option_idx].val;
1501 Error error;
1502
1503 switch (short_option)
1504 {
1505 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001506 m_json_thread = true;
1507 break;
1508
1509 case 's':
1510 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001511 break;
1512
Kuba Breckaafdf8422014-10-10 23:43:03 +00001513 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001514 return Error("invalid short option character '%c'", short_option);
Jason Molenda705b1802014-06-13 02:37:02 +00001515 }
1516 return error;
1517 }
1518
1519 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001520 GetDefinitions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001521 {
1522 return g_option_table;
1523 }
1524
Kuba Breckaafdf8422014-10-10 23:43:03 +00001525 bool m_json_thread;
1526 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001527
1528 static OptionDefinition g_option_table[];
1529 };
1530
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001531 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
1532 CommandObjectIterateOverThreads (interpreter,
1533 "thread info",
1534 "Show an extended summary of information about thread(s) in a process.",
1535 "thread info",
1536 eCommandRequiresProcess |
1537 eCommandTryTargetAPILock |
1538 eCommandProcessMustBeLaunched |
1539 eCommandProcessMustBePaused),
1540 m_options (interpreter)
1541 {
1542 m_add_return = false;
1543 }
1544
1545 ~CommandObjectThreadInfo() override = default;
1546
Jason Molenda705b1802014-06-13 02:37:02 +00001547 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001548 GetOptions () override
Jason Molenda705b1802014-06-13 02:37:02 +00001549 {
1550 return &m_options;
1551 }
1552
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001553 bool
Stephane Sezerf8104912016-03-17 18:52:41 +00001554 HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
Jason Molenda705b1802014-06-13 02:37:02 +00001555 {
Stephane Sezerf8104912016-03-17 18:52:41 +00001556 ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1557 if (!thread_sp)
Jason Molenda705b1802014-06-13 02:37:02 +00001558 {
Stephane Sezerf8104912016-03-17 18:52:41 +00001559 result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid);
1560 result.SetStatus (eReturnStatusFailed);
1561 return false;
1562 }
1563
1564 Thread *thread = thread_sp.get();
1565
1566 Stream &strm = result.GetOutputStream();
1567 if (!thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
1568 {
1569 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread->GetIndexID());
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001570 result.SetStatus (eReturnStatusFailed);
1571 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001572 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001573 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001574 }
1575
1576 CommandOptions m_options;
Jason Molenda705b1802014-06-13 02:37:02 +00001577};
1578
1579OptionDefinition
1580CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1581{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001582 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format."},
1583 { 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 +00001584
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001585 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jason Molenda705b1802014-06-13 02:37:02 +00001586};
1587
Jason Molenda705b1802014-06-13 02:37:02 +00001588//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001589// CommandObjectThreadReturn
1590//-------------------------------------------------------------------------
1591
Jim Inghamcb640dd2012-09-14 02:14:15 +00001592class CommandObjectThreadReturn : public CommandObjectRaw
1593{
1594public:
Jim Ingham93208b82013-01-31 21:46:01 +00001595 class CommandOptions : public Options
1596 {
1597 public:
Jim Ingham93208b82013-01-31 21:46:01 +00001598 CommandOptions (CommandInterpreter &interpreter) :
1599 Options (interpreter),
1600 m_from_expression (false)
1601 {
1602 // Keep default values of all options in one place: OptionParsingStarting ()
1603 OptionParsingStarting ();
1604 }
1605
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001606 ~CommandOptions() override = default;
Jim Ingham93208b82013-01-31 21:46:01 +00001607
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001608 Error
1609 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham93208b82013-01-31 21:46:01 +00001610 {
1611 Error error;
1612 const int short_option = m_getopt_table[option_idx].val;
1613
1614 switch (short_option)
1615 {
1616 case 'x':
1617 {
1618 bool success;
1619 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1620 if (success)
1621 m_from_expression = tmp_value;
1622 else
1623 {
1624 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1625 }
1626 }
1627 break;
1628 default:
1629 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1630 break;
Jim Ingham93208b82013-01-31 21:46:01 +00001631 }
1632 return error;
1633 }
1634
1635 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001636 OptionParsingStarting () override
Jim Ingham93208b82013-01-31 21:46:01 +00001637 {
1638 m_from_expression = false;
1639 }
1640
1641 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001642 GetDefinitions () override
Jim Ingham93208b82013-01-31 21:46:01 +00001643 {
1644 return g_option_table;
1645 }
1646
1647 bool m_from_expression;
1648
1649 // Options table: Required for subclasses of Options.
1650
1651 static OptionDefinition g_option_table[];
1652
1653 // Instance variables to hold the values for command options.
1654 };
1655
Jim Inghamcb640dd2012-09-14 02:14:15 +00001656 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1657 CommandObjectRaw (interpreter,
1658 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001659 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1660 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001661 "thread return",
Enrico Granatae87764f2015-05-27 05:04:35 +00001662 eCommandRequiresFrame |
1663 eCommandTryTargetAPILock |
1664 eCommandProcessMustBeLaunched |
1665 eCommandProcessMustBePaused ),
Jim Ingham93208b82013-01-31 21:46:01 +00001666 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001667 {
1668 CommandArgumentEntry arg;
1669 CommandArgumentData expression_arg;
1670
1671 // Define the first (and only) variant of this arg.
1672 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001673 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001674
1675 // There is only one variant this argument could be; put it into the argument entry.
1676 arg.push_back (expression_arg);
1677
1678 // Push the data for the first argument into the m_arguments vector.
1679 m_arguments.push_back (arg);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001680 }
Jim Inghamcb640dd2012-09-14 02:14:15 +00001681
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001682 ~CommandObjectThreadReturn() override = default;
1683
1684 Options *
1685 GetOptions() override
1686 {
1687 return &m_options;
1688 }
1689
1690protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001691 bool
1692 DoExecute (const char *command, CommandReturnObject &result) override
Jim Inghamcb640dd2012-09-14 02:14:15 +00001693 {
Jim Ingham93208b82013-01-31 21:46:01 +00001694 // I am going to handle this by hand, because I don't want you to have to say:
1695 // "thread return -- -5".
1696 if (command[0] == '-' && command[1] == 'x')
1697 {
1698 if (command && command[2] != '\0')
1699 result.AppendWarning("Return values ignored when returning from user called expressions");
1700
1701 Thread *thread = m_exe_ctx.GetThreadPtr();
1702 Error error;
1703 error = thread->UnwindInnermostExpression();
1704 if (!error.Success())
1705 {
1706 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1707 result.SetStatus (eReturnStatusFailed);
1708 }
1709 else
1710 {
1711 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1712 if (success)
1713 {
1714 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1715 result.SetStatus (eReturnStatusSuccessFinishResult);
1716 }
1717 else
1718 {
1719 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1720 result.SetStatus (eReturnStatusFailed);
1721 }
1722 }
1723 return result.Succeeded();
1724 }
1725
Jim Inghamcb640dd2012-09-14 02:14:15 +00001726 ValueObjectSP return_valobj_sp;
1727
Jason Molendab57e4a12013-11-04 09:33:30 +00001728 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001729 uint32_t frame_idx = frame_sp->GetFrameIndex();
1730
1731 if (frame_sp->IsInlined())
1732 {
1733 result.AppendError("Don't know how to return from inlined frames.");
1734 result.SetStatus (eReturnStatusFailed);
1735 return false;
1736 }
1737
1738 if (command && command[0] != '\0')
1739 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001740 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001741 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001742
1743 options.SetUnwindOnError(true);
1744 options.SetUseDynamic(eNoDynamicValues);
1745
Jim Ingham8646d3c2014-05-05 02:47:44 +00001746 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001747 exe_results = target->EvaluateExpression (command,
1748 frame_sp.get(),
1749 return_valobj_sp,
1750 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001751 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001752 {
1753 if (return_valobj_sp)
1754 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1755 else
1756 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1757 result.SetStatus (eReturnStatusFailed);
1758 return false;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001759 }
1760 }
1761
1762 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001763 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001764 const bool broadcast = true;
1765 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001766 if (!error.Success())
1767 {
1768 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1769 result.SetStatus (eReturnStatusFailed);
1770 return false;
1771 }
1772
Jim Inghamcb640dd2012-09-14 02:14:15 +00001773 result.SetStatus (eReturnStatusSuccessFinishResult);
1774 return true;
1775 }
Jim Ingham93208b82013-01-31 21:46:01 +00001776
1777 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001778};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001779
Jim Ingham93208b82013-01-31 21:46:01 +00001780OptionDefinition
1781CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1782{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001783{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1784{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham93208b82013-01-31 21:46:01 +00001785};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001786
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001787//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001788// CommandObjectThreadJump
1789//-------------------------------------------------------------------------
1790
1791class CommandObjectThreadJump : public CommandObjectParsed
1792{
1793public:
1794 class CommandOptions : public Options
1795 {
1796 public:
Richard Mittonf86248d2013-09-12 02:20:34 +00001797 CommandOptions (CommandInterpreter &interpreter) :
1798 Options (interpreter)
1799 {
1800 OptionParsingStarting ();
1801 }
1802
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001803 ~CommandOptions() override = default;
1804
Richard Mittonf86248d2013-09-12 02:20:34 +00001805 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001806 OptionParsingStarting () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001807 {
1808 m_filenames.Clear();
1809 m_line_num = 0;
1810 m_line_offset = 0;
1811 m_load_addr = LLDB_INVALID_ADDRESS;
1812 m_force = false;
1813 }
1814
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001815 Error
1816 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001817 {
1818 bool success;
1819 const int short_option = m_getopt_table[option_idx].val;
1820 Error error;
1821
1822 switch (short_option)
1823 {
1824 case 'f':
1825 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1826 if (m_filenames.GetSize() > 1)
1827 return Error("only one source file expected.");
1828 break;
1829 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001830 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001831 if (!success || m_line_num == 0)
1832 return Error("invalid line number: '%s'.", option_arg);
1833 break;
1834 case 'b':
Vince Harron5275aaa2015-01-15 20:08:35 +00001835 m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001836 if (!success)
1837 return Error("invalid line offset: '%s'.", option_arg);
1838 break;
1839 case 'a':
1840 {
1841 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1842 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1843 }
1844 break;
1845 case 'r':
1846 m_force = true;
1847 break;
Richard Mittonf86248d2013-09-12 02:20:34 +00001848 default:
1849 return Error("invalid short option character '%c'", short_option);
Richard Mittonf86248d2013-09-12 02:20:34 +00001850 }
1851 return error;
1852 }
1853
1854 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001855 GetDefinitions () override
Richard Mittonf86248d2013-09-12 02:20:34 +00001856 {
1857 return g_option_table;
1858 }
1859
1860 FileSpecList m_filenames;
1861 uint32_t m_line_num;
1862 int32_t m_line_offset;
1863 lldb::addr_t m_load_addr;
1864 bool m_force;
1865
1866 static OptionDefinition g_option_table[];
1867 };
1868
Richard Mittonf86248d2013-09-12 02:20:34 +00001869 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1870 CommandObjectParsed (interpreter,
1871 "thread jump",
1872 "Sets the program counter to a new address.",
1873 "thread jump",
Enrico Granatae87764f2015-05-27 05:04:35 +00001874 eCommandRequiresFrame |
1875 eCommandTryTargetAPILock |
1876 eCommandProcessMustBeLaunched |
1877 eCommandProcessMustBePaused ),
Richard Mittonf86248d2013-09-12 02:20:34 +00001878 m_options (interpreter)
1879 {
1880 }
1881
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001882 ~CommandObjectThreadJump() override = default;
1883
1884 Options *
1885 GetOptions() override
Richard Mittonf86248d2013-09-12 02:20:34 +00001886 {
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001887 return &m_options;
Richard Mittonf86248d2013-09-12 02:20:34 +00001888 }
1889
1890protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001891 bool DoExecute (Args& args, CommandReturnObject &result) override
Richard Mittonf86248d2013-09-12 02:20:34 +00001892 {
1893 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001894 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001895 Thread *thread = m_exe_ctx.GetThreadPtr();
1896 Target *target = m_exe_ctx.GetTargetPtr();
1897 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1898
1899 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1900 {
1901 // Use this address directly.
1902 Address dest = Address(m_options.m_load_addr);
1903
1904 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1905 if (callAddr == LLDB_INVALID_ADDRESS)
1906 {
1907 result.AppendErrorWithFormat ("Invalid destination address.");
1908 result.SetStatus (eReturnStatusFailed);
1909 return false;
1910 }
1911
1912 if (!reg_ctx->SetPC (callAddr))
1913 {
1914 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1915 result.SetStatus (eReturnStatusFailed);
1916 return false;
1917 }
1918 }
1919 else
1920 {
1921 // Pick either the absolute line, or work out a relative one.
1922 int32_t line = (int32_t)m_options.m_line_num;
1923 if (line == 0)
1924 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1925
1926 // Try the current file, but override if asked.
1927 FileSpec file = sym_ctx.line_entry.file;
1928 if (m_options.m_filenames.GetSize() == 1)
1929 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1930
1931 if (!file)
1932 {
1933 result.AppendErrorWithFormat ("No source file available for the current location.");
1934 result.SetStatus (eReturnStatusFailed);
1935 return false;
1936 }
1937
1938 std::string warnings;
1939 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1940
1941 if (err.Fail())
1942 {
1943 result.SetError (err);
1944 return false;
1945 }
1946
1947 if (!warnings.empty())
1948 result.AppendWarning (warnings.c_str());
1949 }
1950
1951 result.SetStatus (eReturnStatusSuccessFinishResult);
1952 return true;
1953 }
1954
1955 CommandOptions m_options;
1956};
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001957
Richard Mittonf86248d2013-09-12 02:20:34 +00001958OptionDefinition
1959CommandObjectThreadJump::CommandOptions::g_option_table[] =
1960{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001961 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001962 "Specifies the source file to jump to."},
1963
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001964 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001965 "Specifies the line number to jump to."},
1966
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001967 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001968 "Jumps by a relative line offset from the current line."},
1969
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001970 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001971 "Jumps to a specific address."},
1972
1973 { LLDB_OPT_SET_1|
1974 LLDB_OPT_SET_2|
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001975 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 +00001976
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001977 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Richard Mittonf86248d2013-09-12 02:20:34 +00001978};
1979
1980//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001981// Next are the subcommands of CommandObjectMultiwordThreadPlan
1982//-------------------------------------------------------------------------
1983
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001984//-------------------------------------------------------------------------
1985// CommandObjectThreadPlanList
1986//-------------------------------------------------------------------------
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00001987
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001988class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
1989{
1990public:
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001991 class CommandOptions : public Options
1992 {
1993 public:
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001994 CommandOptions (CommandInterpreter &interpreter) :
1995 Options(interpreter)
1996 {
1997 // Keep default values of all options in one place: OptionParsingStarting ()
1998 OptionParsingStarting ();
1999 }
2000
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002001 ~CommandOptions() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002002
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002003 Error
2004 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002005 {
2006 Error error;
2007 const int short_option = m_getopt_table[option_idx].val;
2008
2009 switch (short_option)
2010 {
2011 case 'i':
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002012 m_internal = true;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002013 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002014 case 'v':
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002015 m_verbose = true;
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002016 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002017 default:
2018 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2019 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002020 }
2021 return error;
2022 }
2023
2024 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002025 OptionParsingStarting () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002026 {
2027 m_verbose = false;
2028 m_internal = false;
2029 }
2030
2031 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002032 GetDefinitions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002033 {
2034 return g_option_table;
2035 }
2036
2037 // Options table: Required for subclasses of Options.
2038
2039 static OptionDefinition g_option_table[];
2040
2041 // Instance variables to hold the values for command options.
2042 bool m_verbose;
2043 bool m_internal;
2044 };
2045
2046 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002047 CommandObjectIterateOverThreads(interpreter,
2048 "thread plan list",
2049 "Show thread plans for one or more threads. If no threads are specified, show the "
2050 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2051 nullptr,
2052 eCommandRequiresProcess |
2053 eCommandRequiresThread |
2054 eCommandTryTargetAPILock |
2055 eCommandProcessMustBeLaunched |
2056 eCommandProcessMustBePaused ),
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002057 m_options(interpreter)
2058 {
2059 }
2060
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002061 ~CommandObjectThreadPlanList() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002062
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002063 Options *
2064 GetOptions () override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002065 {
2066 return &m_options;
2067 }
2068
2069protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002070 bool
Stephane Sezerf8104912016-03-17 18:52:41 +00002071 HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002072 {
Stephane Sezerf8104912016-03-17 18:52:41 +00002073 ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
2074 if (!thread_sp)
2075 {
2076 result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid);
2077 result.SetStatus (eReturnStatusFailed);
2078 return false;
2079 }
2080
2081 Thread *thread = thread_sp.get();
2082
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002083 Stream &strm = result.GetOutputStream();
2084 DescriptionLevel desc_level = eDescriptionLevelFull;
2085 if (m_options.m_verbose)
2086 desc_level = eDescriptionLevelVerbose;
2087
Stephane Sezerf8104912016-03-17 18:52:41 +00002088 thread->DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002089 return true;
2090 }
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002091
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002092 CommandOptions m_options;
2093};
2094
2095OptionDefinition
2096CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2097{
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002098{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans"},
2099{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2100{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002101};
2102
2103class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2104{
2105public:
2106 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002107 CommandObjectParsed(interpreter,
2108 "thread plan discard",
2109 "Discards thread plans up to and including the plan passed as the command argument."
2110 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2111 " without the \"-i\" argument.",
2112 nullptr,
2113 eCommandRequiresProcess |
2114 eCommandRequiresThread |
2115 eCommandTryTargetAPILock |
2116 eCommandProcessMustBeLaunched |
2117 eCommandProcessMustBePaused )
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002118 {
2119 CommandArgumentEntry arg;
2120 CommandArgumentData plan_index_arg;
2121
2122 // Define the first (and only) variant of this arg.
2123 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2124 plan_index_arg.arg_repetition = eArgRepeatPlain;
2125
2126 // There is only one variant this argument could be; put it into the argument entry.
2127 arg.push_back (plan_index_arg);
2128
2129 // Push the data for the first argument into the m_arguments vector.
2130 m_arguments.push_back (arg);
2131 }
2132
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002133 ~CommandObjectThreadPlanDiscard() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002134
2135 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002136 DoExecute (Args& args, CommandReturnObject &result) override
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002137 {
2138 Thread *thread = m_exe_ctx.GetThreadPtr();
2139 if (args.GetArgumentCount() != 1)
2140 {
2141 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2142 args.GetArgumentCount());
2143 result.SetStatus (eReturnStatusFailed);
2144 return false;
2145 }
2146
2147 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00002148 uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002149 if (!success)
2150 {
2151 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2152 args.GetArgumentAtIndex(0));
2153 result.SetStatus (eReturnStatusFailed);
2154 return false;
2155 }
2156
2157 if (thread_plan_idx == 0)
2158 {
2159 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2160 result.SetStatus (eReturnStatusFailed);
2161 return false;
2162 }
2163
2164 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2165 {
2166 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2167 return true;
2168 }
2169 else
2170 {
2171 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2172 args.GetArgumentAtIndex(0));
2173 result.SetStatus (eReturnStatusFailed);
2174 return false;
2175 }
2176 }
2177};
2178
2179//-------------------------------------------------------------------------
2180// CommandObjectMultiwordThreadPlan
2181//-------------------------------------------------------------------------
2182
2183class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2184{
2185public:
2186 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2187 CommandObjectMultiword (interpreter,
2188 "plan",
2189 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2190 "thread plan <subcommand> [<subcommand objects]")
2191 {
2192 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2193 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2194 }
2195
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002196 ~CommandObjectMultiwordThreadPlan() override = default;
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002197};
2198
2199//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002200// CommandObjectMultiwordThread
2201//-------------------------------------------------------------------------
2202
Greg Clayton66111032010-06-23 01:19:29 +00002203CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002204 CommandObjectMultiword (interpreter,
2205 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002206 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002207 "thread <subcommand> [<subcommand-options>]")
2208{
Greg Claytona7015092010-09-18 01:14:36 +00002209 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2210 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2211 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002212 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002213 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002214 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2215 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002216 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002217 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2218 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002219 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002220 "Source level single step in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002221 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002222 eStepTypeInto,
2223 eStepScopeSource)));
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002224
Greg Claytona7015092010-09-18 01:14:36 +00002225 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2226 interpreter,
2227 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002228 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002229 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002230 eStepTypeOut,
2231 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002232
Greg Claytona7015092010-09-18 01:14:36 +00002233 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2234 interpreter,
2235 "thread step-over",
2236 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002237 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002238 eStepTypeOver,
2239 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002240
Greg Claytona7015092010-09-18 01:14:36 +00002241 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2242 interpreter,
2243 "thread step-inst",
2244 "Single step one instruction in specified thread (current thread, if none specified).",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002245 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002246 eStepTypeTrace,
2247 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002248
Greg Claytona7015092010-09-18 01:14:36 +00002249 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2250 interpreter,
2251 "thread step-inst-over",
2252 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002253 nullptr,
Greg Claytona7015092010-09-18 01:14:36 +00002254 eStepTypeTraceOver,
2255 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002256
2257 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2258 interpreter,
2259 "thread step-scripted",
2260 "Step as instructed by the script class passed in the -C option.",
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002261 nullptr,
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002262 eStepTypeScripted,
2263 eStepScopeSource)));
2264
2265 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002266}
2267
Eugene Zelenko50ff9fe2016-02-25 23:46:36 +00002268CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;