blob: d0c82b44f55d704864167f3667fb1cd5d822be07 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectThread.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Inghamcb640dd2012-09-14 02:14:15 +000018#include "lldb/lldb-private.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/State.h"
20#include "lldb/Core/SourceManager.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000021#include "lldb/Core/ValueObject.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000022#include "lldb/Host/Host.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000023#include "lldb/Host/StringConvert.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Interpreter/CommandInterpreter.h"
25#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton1f746072012-08-29 21:13:06 +000026#include "lldb/Interpreter/Options.h"
27#include "lldb/Symbol/CompileUnit.h"
28#include "lldb/Symbol/Function.h"
29#include "lldb/Symbol/LineTable.h"
30#include "lldb/Symbol/LineEntry.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/Process.h"
32#include "lldb/Target/RegisterContext.h"
Jason Molenda750ea692013-11-12 07:02:07 +000033#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Target/Target.h"
35#include "lldb/Target/Thread.h"
36#include "lldb/Target/ThreadPlan.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037#include "lldb/Target/ThreadPlanStepInstruction.h"
38#include "lldb/Target/ThreadPlanStepOut.h"
39#include "lldb/Target/ThreadPlanStepRange.h"
40#include "lldb/Target/ThreadPlanStepInRange.h"
Greg Clayton1f746072012-08-29 21:13:06 +000041
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
43using namespace lldb;
44using namespace lldb_private;
45
46
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047//-------------------------------------------------------------------------
48// CommandObjectThreadBacktrace
49//-------------------------------------------------------------------------
50
Jim Ingham2bdbfd52014-09-29 23:17:18 +000051class CommandObjectIterateOverThreads : public CommandObjectParsed
52{
53public:
54 CommandObjectIterateOverThreads (CommandInterpreter &interpreter,
55 const char *name,
56 const char *help,
57 const char *syntax,
58 uint32_t flags) :
59 CommandObjectParsed (interpreter, name, help, syntax, flags)
60 {
61 }
62
63 virtual ~CommandObjectIterateOverThreads() {}
64 virtual bool
65 DoExecute (Args& command, CommandReturnObject &result)
66 {
67 result.SetStatus (m_success_return);
68
69 if (command.GetArgumentCount() == 0)
70 {
71 Thread *thread = m_exe_ctx.GetThreadPtr();
72 if (!HandleOneThread (*thread, result))
73 return false;
74 }
75 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
76 {
77 Process *process = m_exe_ctx.GetProcessPtr();
78 uint32_t idx = 0;
79 for (ThreadSP thread_sp : process->Threads())
80 {
81 if (idx != 0 && m_add_return)
82 result.AppendMessage("");
83
84 if (!HandleOneThread(*(thread_sp.get()), result))
85 return false;
86 ++idx;
87 }
88 }
89 else
90 {
91 const size_t num_args = command.GetArgumentCount();
92 Process *process = m_exe_ctx.GetProcessPtr();
93 Mutex::Locker locker (process->GetThreadList().GetMutex());
94 std::vector<ThreadSP> thread_sps;
95
96 for (size_t i = 0; i < num_args; i++)
97 {
98 bool success;
99
Vince Harron5275aaa2015-01-15 20:08:35 +0000100 uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000101 if (!success)
102 {
103 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
104 result.SetStatus (eReturnStatusFailed);
105 return false;
106 }
107
108 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
109
110 if (!thread_sps[i])
111 {
112 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
113 result.SetStatus (eReturnStatusFailed);
114 return false;
115 }
116
117 }
118
119 for (uint32_t i = 0; i < num_args; i++)
120 {
121 if (!HandleOneThread (*(thread_sps[i].get()), result))
122 return false;
123
124 if (i < num_args - 1 && m_add_return)
125 result.AppendMessage("");
126 }
127 }
128 return result.Succeeded();
129 }
130
131protected:
132
133 // Override this to do whatever you need to do for one thread.
134 //
135 // If you return false, the iteration will stop, otherwise it will proceed.
136 // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
137 // so you only need to set the return status in HandleOneThread if you want to indicate an error.
138 // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
139
140 virtual bool
141 HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
142
143 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
144 bool m_add_return = true;
145
146};
147
148//-------------------------------------------------------------------------
149// CommandObjectThreadBacktrace
150//-------------------------------------------------------------------------
151
152class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153{
154public:
155
Jim Inghame2e0b452010-08-26 23:36:03 +0000156 class CommandOptions : public Options
157 {
158 public:
159
Greg Claytoneb0103f2011-04-07 22:46:35 +0000160 CommandOptions (CommandInterpreter &interpreter) :
161 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +0000162 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000163 // Keep default values of all options in one place: OptionParsingStarting ()
164 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +0000165 }
166
167 virtual
168 ~CommandOptions ()
169 {
170 }
171
172 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000173 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame2e0b452010-08-26 23:36:03 +0000174 {
175 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000176 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame2e0b452010-08-26 23:36:03 +0000177
178 switch (short_option)
179 {
180 case 'c':
181 {
182 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +0000183 int32_t input_count = StringConvert::ToSInt32 (option_arg, -1, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000184 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000185 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000186 if (input_count < -1)
187 m_count = UINT32_MAX;
188 else
189 m_count = input_count;
190 }
191 break;
192 case 's':
193 {
194 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +0000195 m_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Jim Inghame2e0b452010-08-26 23:36:03 +0000196 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000197 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000198 }
Jason Molenda750ea692013-11-12 07:02:07 +0000199 case 'e':
200 {
201 bool success;
202 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
203 if (!success)
204 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
205 }
Jim Inghame2e0b452010-08-26 23:36:03 +0000206 break;
207 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000208 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000209 break;
210
211 }
212 return error;
213 }
214
215 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000216 OptionParsingStarting ()
Jim Inghame2e0b452010-08-26 23:36:03 +0000217 {
Greg Clayton7260f622011-04-18 08:33:37 +0000218 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000219 m_start = 0;
Jason Molenda750ea692013-11-12 07:02:07 +0000220 m_extended_backtrace = false;
Jim Inghame2e0b452010-08-26 23:36:03 +0000221 }
222
Greg Claytone0d378b2011-03-24 21:19:54 +0000223 const OptionDefinition*
Jim Inghame2e0b452010-08-26 23:36:03 +0000224 GetDefinitions ()
225 {
226 return g_option_table;
227 }
228
229 // Options table: Required for subclasses of Options.
230
Greg Claytone0d378b2011-03-24 21:19:54 +0000231 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000232
233 // Instance variables to hold the values for command options.
234 uint32_t m_count;
235 uint32_t m_start;
Jason Molenda750ea692013-11-12 07:02:07 +0000236 bool m_extended_backtrace;
Jim Inghame2e0b452010-08-26 23:36:03 +0000237 };
238
Greg Claytona7015092010-09-18 01:14:36 +0000239 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000240 CommandObjectIterateOverThreads (interpreter,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000241 "thread backtrace",
242 "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.",
243 NULL,
244 eFlagRequiresProcess |
245 eFlagRequiresThread |
246 eFlagTryTargetAPILock |
247 eFlagProcessMustBeLaunched |
248 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000249 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250 {
251 }
252
253 ~CommandObjectThreadBacktrace()
254 {
255 }
256
Jim Inghame2e0b452010-08-26 23:36:03 +0000257 virtual Options *
258 GetOptions ()
259 {
260 return &m_options;
261 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262
Jim Ingham5a988412012-06-08 21:56:10 +0000263protected:
Jason Molenda750ea692013-11-12 07:02:07 +0000264 void
265 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
266 {
267 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
268 if (runtime)
269 {
270 Stream &strm = result.GetOutputStream();
271 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
272 for (auto type : types)
273 {
Jason Molenda008c45f2013-11-12 23:33:32 +0000274 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
Jason Molenda750ea692013-11-12 07:02:07 +0000275 if (ext_thread_sp && ext_thread_sp->IsValid ())
276 {
277 const uint32_t num_frames_with_source = 0;
278 if (ext_thread_sp->GetStatus (strm,
279 m_options.m_start,
280 m_options.m_count,
281 num_frames_with_source))
282 {
283 DoExtendedBacktrace (ext_thread_sp.get(), result);
284 }
285 }
286 }
287 }
288 }
289
Greg Clayton66111032010-06-23 01:19:29 +0000290 virtual bool
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000291 HandleOneThread (Thread &thread, CommandReturnObject &result)
292 {
Greg Clayton7260f622011-04-18 08:33:37 +0000293 Stream &strm = result.GetOutputStream();
294
295 // Don't show source context when doing backtraces.
296 const uint32_t num_frames_with_source = 0;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000297
298 if (!thread.GetStatus (strm,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000299 m_options.m_start,
300 m_options.m_count,
301 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000302 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000303 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID());
304 result.SetStatus (eReturnStatusFailed);
305 return false;
Jim Ingham09b263e2010-08-27 00:58:05 +0000306 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000307 if (m_options.m_extended_backtrace)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000309 DoExtendedBacktrace (&thread, result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000311
312 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 }
Jim Ingham5a988412012-06-08 21:56:10 +0000314
Jim Inghame2e0b452010-08-26 23:36:03 +0000315 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316};
317
Greg Claytone0d378b2011-03-24 21:19:54 +0000318OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000319CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
320{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000321{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
322{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
323{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
324{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghame2e0b452010-08-26 23:36:03 +0000325};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326
Greg Clayton69b518f2010-07-07 17:07:17 +0000327enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328{
329 eStepScopeSource,
330 eStepScopeInstruction
331};
332
Jim Ingham5a988412012-06-08 21:56:10 +0000333class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334{
335public:
336
337 class CommandOptions : public Options
338 {
339 public:
340
Greg Claytoneb0103f2011-04-07 22:46:35 +0000341 CommandOptions (CommandInterpreter &interpreter) :
342 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000344 // Keep default values of all options in one place: OptionParsingStarting ()
345 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346 }
347
348 virtual
349 ~CommandOptions ()
350 {
351 }
352
353 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000354 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355 {
356 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000357 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358
359 switch (short_option)
360 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000361 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362 {
363 bool success;
Jim Ingham4b4b2472014-03-13 02:47:14 +0000364 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000366 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Jim Ingham4b4b2472014-03-13 02:47:14 +0000367 else
368 {
369 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
370 }
371 }
372 break;
373
374 case 'A':
375 {
376 bool success;
377 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
378 if (!success)
379 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
380 else
381 {
382 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 }
385 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000386
Jim Ingham7a88ec92014-07-08 19:28:57 +0000387 case 'c':
388 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000389 m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000390 if (m_step_count == UINT32_MAX)
391 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
392 break;
393 }
394 break;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000395 case 'C':
396 {
397 m_class_name.clear();
398 m_class_name.assign(option_arg);
399 }
400 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000401 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000404 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405 }
406 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000407
408 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000409 {
410 m_avoid_regexp.clear();
411 m_avoid_regexp.assign(option_arg);
412 }
413 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000414
Jim Inghamc6276822012-12-12 19:58:40 +0000415 case 't':
416 {
417 m_step_in_target.clear();
418 m_step_in_target.assign(option_arg);
419
420 }
421 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000422 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000423 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000424 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425
426 }
427 return error;
428 }
429
430 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000431 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432 {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000433 m_step_in_avoid_no_debug = eLazyBoolCalculate;
434 m_step_out_avoid_no_debug = eLazyBoolCalculate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 m_run_mode = eOnlyDuringStepping;
Ewan Crawford78baa192015-05-13 09:18:18 +0000436
437 // Check if we are in Non-Stop mode
438 lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
439 if (target_sp.get() != nullptr && target_sp->GetNonStopModeEnabled())
440 m_run_mode = eOnlyThisThread;
441
Jim Inghama56c8002010-07-10 02:27:39 +0000442 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000443 m_step_in_target.clear();
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000444 m_class_name.clear();
Jim Ingham7a88ec92014-07-08 19:28:57 +0000445 m_step_count = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446 }
447
Greg Claytone0d378b2011-03-24 21:19:54 +0000448 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449 GetDefinitions ()
450 {
451 return g_option_table;
452 }
453
454 // Options table: Required for subclasses of Options.
455
Greg Claytone0d378b2011-03-24 21:19:54 +0000456 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457
458 // Instance variables to hold the values for command options.
Jim Ingham4b4b2472014-03-13 02:47:14 +0000459 LazyBool m_step_in_avoid_no_debug;
460 LazyBool m_step_out_avoid_no_debug;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000462 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000463 std::string m_step_in_target;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000464 std::string m_class_name;
Zachary Turner898e10e2015-01-09 20:15:21 +0000465 uint32_t m_step_count;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466 };
467
Greg Claytona7015092010-09-18 01:14:36 +0000468 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
469 const char *name,
470 const char *help,
471 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000472 StepType step_type,
473 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000474 CommandObjectParsed (interpreter, name, help, syntax,
475 eFlagRequiresProcess |
476 eFlagRequiresThread |
477 eFlagTryTargetAPILock |
478 eFlagProcessMustBeLaunched |
479 eFlagProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480 m_step_type (step_type),
481 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000482 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483 {
Caroline Tice405fe672010-10-04 22:28:36 +0000484 CommandArgumentEntry arg;
485 CommandArgumentData thread_id_arg;
486
487 // Define the first (and only) variant of this arg.
488 thread_id_arg.arg_type = eArgTypeThreadID;
489 thread_id_arg.arg_repetition = eArgRepeatOptional;
490
491 // There is only one variant this argument could be; put it into the argument entry.
492 arg.push_back (thread_id_arg);
493
494 // Push the data for the first argument into the m_arguments vector.
495 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 }
497
498 virtual
499 ~CommandObjectThreadStepWithTypeAndScope ()
500 {
501 }
502
503 virtual
504 Options *
505 GetOptions ()
506 {
507 return &m_options;
508 }
509
Jim Ingham5a988412012-06-08 21:56:10 +0000510protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000512 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000514 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000515 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516
Greg Claytonf9fc6092013-01-09 19:44:40 +0000517 const uint32_t num_threads = process->GetThreadList().GetSize();
518 Thread *thread = NULL;
519
520 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000522 thread = process->GetThreadList().GetSelectedThread().get();
523 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000525 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000527 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000529 }
530 else
531 {
532 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
Vince Harron5275aaa2015-01-15 20:08:35 +0000533 uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000534 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000535 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000536 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
537 result.SetStatus (eReturnStatusFailed);
538 return false;
539 }
540 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
541 if (thread == NULL)
542 {
543 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
544 step_thread_idx, num_threads);
545 result.SetStatus (eReturnStatusFailed);
546 return false;
547 }
548 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000549
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000550 if (m_step_type == eStepTypeScripted)
551 {
552 if (m_options.m_class_name.empty())
553 {
554 result.AppendErrorWithFormat ("empty class name for scripted step.");
555 result.SetStatus(eReturnStatusFailed);
556 return false;
557 }
558 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
559 {
560 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
561 result.SetStatus(eReturnStatusFailed);
562 return false;
563 }
564 }
565
Greg Claytonf9fc6092013-01-09 19:44:40 +0000566 const bool abort_other_plans = false;
567 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
568
569 // This is a bit unfortunate, but not all the commands in this command object support
570 // only while stepping, so I use the bool for them.
571 bool bool_stop_other_threads;
572 if (m_options.m_run_mode == eAllThreads)
573 bool_stop_other_threads = false;
574 else if (m_options.m_run_mode == eOnlyDuringStepping)
575 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000576 if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000577 bool_stop_other_threads = false;
578 else
579 bool_stop_other_threads = true;
580 }
581 else
582 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000583
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000584 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000585
586 if (m_step_type == eStepTypeInto)
587 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000588 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Stephane Sezerca05ae22015-03-26 17:47:34 +0000589 assert(frame != nullptr);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000590
Stephane Sezerca05ae22015-03-26 17:47:34 +0000591 if (frame->HasDebugInformation ())
Greg Claytonf9fc6092013-01-09 19:44:40 +0000592 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000593 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000594 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
595 frame->GetSymbolContext(eSymbolContextEverything),
596 m_options.m_step_in_target.c_str(),
597 stop_other_threads,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000598 m_options.m_step_in_avoid_no_debug,
599 m_options.m_step_out_avoid_no_debug);
600
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000601 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000602 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000603 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000604 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000605 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000606 }
607 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000608 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000609
610 }
611 else if (m_step_type == eStepTypeOver)
612 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000613 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000614
615 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000616 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000617 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
618 frame->GetSymbolContext(eSymbolContextEverything),
Jim Ingham4b4b2472014-03-13 02:47:14 +0000619 stop_other_threads,
620 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000621 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000622 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000623 abort_other_plans,
624 bool_stop_other_threads);
625
626 }
627 else if (m_step_type == eStepTypeTrace)
628 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000629 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000630 }
631 else if (m_step_type == eStepTypeTraceOver)
632 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000633 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000634 }
635 else if (m_step_type == eStepTypeOut)
636 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000637 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000638 NULL,
639 false,
640 bool_stop_other_threads,
641 eVoteYes,
642 eVoteNoOpinion,
Jim Ingham4b4b2472014-03-13 02:47:14 +0000643 thread->GetSelectedFrameIndex(),
644 m_options.m_step_out_avoid_no_debug);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000645 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000646 else if (m_step_type == eStepTypeScripted)
647 {
648 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
649 m_options.m_class_name.c_str(),
650 bool_stop_other_threads);
651 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000652 else
653 {
654 result.AppendError ("step type is not supported");
655 result.SetStatus (eReturnStatusFailed);
656 return false;
657 }
658
659 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
660 // so that they can be interruptible). Then resume the process.
661
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000662 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000663 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000664 new_plan_sp->SetIsMasterPlan (true);
665 new_plan_sp->SetOkayToDiscard (false);
Jim Ingham7a88ec92014-07-08 19:28:57 +0000666
667 if (m_options.m_step_count > 1)
668 {
Zachary Turner40411162014-07-16 20:28:24 +0000669 if (new_plan_sp->SetIterationCount(m_options.m_step_count))
Jim Ingham7a88ec92014-07-08 19:28:57 +0000670 {
671 result.AppendWarning ("step operation does not support iteration count.");
672 }
673 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000674
Greg Claytondc6224e2014-10-21 01:00:42 +0000675
Greg Claytonf9fc6092013-01-09 19:44:40 +0000676 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000677
678 StreamString stream;
679 Error error;
680 if (synchronous_execution)
681 error = process->ResumeSynchronous (&stream);
682 else
683 error = process->Resume ();
Todd Fialaa3b89e22014-08-12 14:33:19 +0000684
685 // There is a race condition where this thread will return up the call stack to the main command handler
686 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
687 // a chance to call PushProcessIOHandler().
688 process->SyncIOHandler(2000);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000689
690 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000691 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000692 // If any state changed events had anything to say, add that to the result
693 if (stream.GetData())
694 result.AppendMessage(stream.GetData());
695
Greg Claytonf9fc6092013-01-09 19:44:40 +0000696 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
697 result.SetDidChangeProcessState (true);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000698 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000699 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000700 else
701 {
702 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
703 }
704 }
705 else
706 {
707 result.AppendError ("Couldn't find thread plan to implement step type.");
708 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709 }
710 return result.Succeeded();
711 }
712
713protected:
714 StepType m_step_type;
715 StepScope m_step_scope;
716 CommandOptions m_options;
717};
718
Greg Claytone0d378b2011-03-24 21:19:54 +0000719static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720g_tri_running_mode[] =
721{
Greg Claytoned8a7052010-09-18 03:37:20 +0000722{ eOnlyThisThread, "this-thread", "Run only this thread"},
723{ eAllThreads, "all-threads", "Run all threads"},
724{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725{ 0, NULL, NULL }
726};
727
Greg Claytone0d378b2011-03-24 21:19:54 +0000728static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000729g_duo_running_mode[] =
730{
Greg Claytoned8a7052010-09-18 03:37:20 +0000731{ eOnlyThisThread, "this-thread", "Run only this thread"},
732{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733{ 0, NULL, NULL }
734};
735
Greg Claytone0d378b2011-03-24 21:19:54 +0000736OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
738{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000739{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
740{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000741{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
742{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
743{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
744{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
745{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
Zachary Turnerd37221d2014-07-09 16:31:49 +0000746{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000747};
748
749
750//-------------------------------------------------------------------------
751// CommandObjectThreadContinue
752//-------------------------------------------------------------------------
753
Jim Ingham5a988412012-06-08 21:56:10 +0000754class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000755{
756public:
757
Greg Claytona7015092010-09-18 01:14:36 +0000758 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000759 CommandObjectParsed (interpreter,
760 "thread continue",
761 "Continue execution of one or more threads in an active process.",
762 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000763 eFlagRequiresThread |
764 eFlagTryTargetAPILock |
765 eFlagProcessMustBeLaunched |
766 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767 {
Caroline Tice405fe672010-10-04 22:28:36 +0000768 CommandArgumentEntry arg;
769 CommandArgumentData thread_idx_arg;
770
771 // Define the first (and only) variant of this arg.
772 thread_idx_arg.arg_type = eArgTypeThreadIndex;
773 thread_idx_arg.arg_repetition = eArgRepeatPlus;
774
775 // There is only one variant this argument could be; put it into the argument entry.
776 arg.push_back (thread_idx_arg);
777
778 // Push the data for the first argument into the m_arguments vector.
779 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000780 }
781
782
783 virtual
784 ~CommandObjectThreadContinue ()
785 {
786 }
787
788 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000789 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000790 {
Greg Claytona7015092010-09-18 01:14:36 +0000791 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000792
Greg Claytona7015092010-09-18 01:14:36 +0000793 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000794 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000795 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000796 result.SetStatus (eReturnStatusFailed);
797 return false;
798 }
799
Greg Claytonf9fc6092013-01-09 19:44:40 +0000800 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801 if (process == NULL)
802 {
803 result.AppendError ("no process exists. Cannot continue");
804 result.SetStatus (eReturnStatusFailed);
805 return false;
806 }
807
808 StateType state = process->GetState();
809 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
810 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000811 const size_t argc = command.GetArgumentCount();
812 if (argc > 0)
813 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000814 // These two lines appear at the beginning of both blocks in
815 // this if..else, but that is because we need to release the
816 // lock before calling process->Resume below.
817 Mutex::Locker locker (process->GetThreadList().GetMutex());
818 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000819 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000820 for (uint32_t i=0; i<argc; ++i)
821 {
Jim Inghamce76c622012-05-31 20:48:41 +0000822 bool success;
823 const int base = 0;
Vince Harron5275aaa2015-01-15 20:08:35 +0000824 uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000825 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000826 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000827 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000828
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000829 if (thread)
830 {
831 resume_threads.push_back(thread);
832 }
833 else
834 {
835 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
836 result.SetStatus (eReturnStatusFailed);
837 return false;
838 }
Jim Inghamce76c622012-05-31 20:48:41 +0000839 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840 else
Jim Inghamce76c622012-05-31 20:48:41 +0000841 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000842 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000843 result.SetStatus (eReturnStatusFailed);
844 return false;
845 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000847
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000848 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000849 {
850 result.AppendError ("no valid thread indexes were specified");
851 result.SetStatus (eReturnStatusFailed);
852 return false;
853 }
854 else
855 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000856 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000857 result.AppendMessageWithFormat ("Resuming thread: ");
858 else
859 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000860
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000861 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000862 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000863 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
864 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000865
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000866 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000868 resume_threads.erase(this_thread_pos);
869 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000870 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
871 else
872 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000873
874 const bool override_suspend = true;
875 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876 }
877 else
878 {
879 thread->SetResumeState (eStateSuspended);
880 }
881 }
Daniel Malead01b2952012-11-29 21:49:15 +0000882 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000883 }
884 }
885 else
886 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000887 // These two lines appear at the beginning of both blocks in
888 // this if..else, but that is because we need to release the
889 // lock before calling process->Resume below.
890 Mutex::Locker locker (process->GetThreadList().GetMutex());
891 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000892 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000893 if (current_thread == NULL)
894 {
895 result.AppendError ("the process doesn't have a current thread");
896 result.SetStatus (eReturnStatusFailed);
897 return false;
898 }
899 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000900 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000902 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000903 if (thread == current_thread)
904 {
Daniel Malead01b2952012-11-29 21:49:15 +0000905 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Jim Ingham6c9ed912014-04-03 01:26:14 +0000906 const bool override_suspend = true;
907 thread->SetResumeState (eStateRunning, override_suspend);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908 }
909 else
910 {
911 thread->SetResumeState (eStateSuspended);
912 }
913 }
914 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000915
Greg Claytondc6224e2014-10-21 01:00:42 +0000916
917 StreamString stream;
918 Error error;
919 if (synchronous_execution)
920 error = process->ResumeSynchronous (&stream);
921 else
922 error = process->Resume ();
923
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000924 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 if (error.Success())
926 {
Daniel Malead01b2952012-11-29 21:49:15 +0000927 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928 if (synchronous_execution)
929 {
Greg Claytondc6224e2014-10-21 01:00:42 +0000930 // If any state changed events had anything to say, add that to the result
931 if (stream.GetData())
932 result.AppendMessage(stream.GetData());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000933
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000935 result.SetStatus (eReturnStatusSuccessFinishNoResult);
936 }
937 else
938 {
939 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
940 }
941 }
942 else
943 {
944 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
945 result.SetStatus (eReturnStatusFailed);
946 }
947 }
948 else
949 {
950 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
951 StateAsCString(state));
952 result.SetStatus (eReturnStatusFailed);
953 }
954
955 return result.Succeeded();
956 }
957
958};
959
960//-------------------------------------------------------------------------
961// CommandObjectThreadUntil
962//-------------------------------------------------------------------------
963
Jim Ingham5a988412012-06-08 21:56:10 +0000964class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000965{
966public:
967
968 class CommandOptions : public Options
969 {
970 public:
971 uint32_t m_thread_idx;
972 uint32_t m_frame_idx;
973
Greg Claytoneb0103f2011-04-07 22:46:35 +0000974 CommandOptions (CommandInterpreter &interpreter) :
975 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000976 m_thread_idx(LLDB_INVALID_THREAD_ID),
977 m_frame_idx(LLDB_INVALID_FRAME_ID)
978 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000979 // Keep default values of all options in one place: OptionParsingStarting ()
980 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981 }
982
983 virtual
984 ~CommandOptions ()
985 {
986 }
987
988 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000989 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990 {
991 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000992 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993
994 switch (short_option)
995 {
Jim Ingham9bdea542015-02-06 02:10:56 +0000996 case 'a':
997 {
998 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
999 lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1000 if (error.Success())
1001 m_until_addrs.push_back(tmp_addr);
1002 }
1003 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001004 case 't':
1005 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001006 m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007 if (m_thread_idx == LLDB_INVALID_INDEX32)
1008 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001009 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010 }
1011 }
1012 break;
1013 case 'f':
1014 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001015 m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001016 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
1017 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001018 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019 }
1020 }
1021 break;
1022 case 'm':
1023 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001024 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001025 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026
Greg Claytoncf0e4f02011-10-07 18:58:12 +00001027 if (error.Success())
1028 {
1029 if (run_mode == eAllThreads)
1030 m_stop_others = false;
1031 else
1032 m_stop_others = true;
1033 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034 }
1035 break;
1036 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001037 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038 break;
1039
1040 }
1041 return error;
1042 }
1043
1044 void
Greg Claytonf6b8b582011-04-13 00:18:08 +00001045 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047 m_thread_idx = LLDB_INVALID_THREAD_ID;
1048 m_frame_idx = 0;
1049 m_stop_others = false;
Jim Ingham9bdea542015-02-06 02:10:56 +00001050 m_until_addrs.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051 }
1052
Greg Claytone0d378b2011-03-24 21:19:54 +00001053 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 GetDefinitions ()
1055 {
1056 return g_option_table;
1057 }
1058
1059 uint32_t m_step_thread_idx;
1060 bool m_stop_others;
Jim Ingham9bdea542015-02-06 02:10:56 +00001061 std::vector<lldb::addr_t> m_until_addrs;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062
1063 // Options table: Required for subclasses of Options.
1064
Greg Claytone0d378b2011-03-24 21:19:54 +00001065 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066
1067 // Instance variables to hold the values for command options.
1068 };
1069
Greg Claytona7015092010-09-18 01:14:36 +00001070 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001071 CommandObjectParsed (interpreter,
1072 "thread until",
Jim Ingham9bdea542015-02-06 02:10:56 +00001073 "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
Jim Ingham5a988412012-06-08 21:56:10 +00001074 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001075 eFlagRequiresThread |
1076 eFlagTryTargetAPILock |
1077 eFlagProcessMustBeLaunched |
1078 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001079 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001080 {
Caroline Tice405fe672010-10-04 22:28:36 +00001081 CommandArgumentEntry arg;
1082 CommandArgumentData line_num_arg;
1083
1084 // Define the first (and only) variant of this arg.
1085 line_num_arg.arg_type = eArgTypeLineNum;
1086 line_num_arg.arg_repetition = eArgRepeatPlain;
1087
1088 // There is only one variant this argument could be; put it into the argument entry.
1089 arg.push_back (line_num_arg);
1090
1091 // Push the data for the first argument into the m_arguments vector.
1092 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093 }
1094
1095
1096 virtual
1097 ~CommandObjectThreadUntil ()
1098 {
1099 }
1100
1101 virtual
1102 Options *
1103 GetOptions ()
1104 {
1105 return &m_options;
1106 }
1107
Jim Ingham5a988412012-06-08 21:56:10 +00001108protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001109 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001110 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111 {
Greg Claytona7015092010-09-18 01:14:36 +00001112 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113
Greg Claytona7015092010-09-18 01:14:36 +00001114 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +00001115 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116 {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001117 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001118 result.SetStatus (eReturnStatusFailed);
1119 return false;
1120 }
1121
Greg Claytonf9fc6092013-01-09 19:44:40 +00001122 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001123 if (process == NULL)
1124 {
1125 result.AppendError ("need a valid process to step");
1126 result.SetStatus (eReturnStatusFailed);
1127
1128 }
1129 else
1130 {
1131 Thread *thread = NULL;
Jim Ingham9bdea542015-02-06 02:10:56 +00001132 std::vector<uint32_t> line_numbers;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133
Jim Ingham9bdea542015-02-06 02:10:56 +00001134 if (command.GetArgumentCount() >= 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001136 size_t num_args = command.GetArgumentCount();
1137 for (size_t i = 0; i < num_args; i++)
1138 {
1139 uint32_t line_number;
1140 line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1141 if (line_number == UINT32_MAX)
1142 {
1143 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1144 result.SetStatus (eReturnStatusFailed);
1145 return false;
1146 }
1147 else
1148 line_numbers.push_back(line_number);
1149 }
1150 }
1151 else if (m_options.m_until_addrs.empty())
1152 {
1153 result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154 result.SetStatus (eReturnStatusFailed);
1155 return false;
1156 }
1157
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001158
1159 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1160 {
Jim Ingham2976d002010-08-26 21:32:51 +00001161 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162 }
1163 else
1164 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001165 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 }
1167
1168 if (thread == NULL)
1169 {
1170 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001171 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1172 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001173 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 result.SetStatus (eReturnStatusFailed);
1175 return false;
1176 }
1177
Jim Ingham7ba6e992012-05-11 23:47:32 +00001178 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179
Jason Molendab57e4a12013-11-04 09:33:30 +00001180 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181 if (frame == NULL)
1182 {
1183
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001184 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1185 m_options.m_frame_idx,
1186 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187 result.SetStatus (eReturnStatusFailed);
1188 return false;
1189 }
1190
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001191 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192
1193 if (frame->HasDebugInformation ())
1194 {
1195 // Finally we got here... Translate the given line number to a bunch of addresses:
1196 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1197 LineTable *line_table = NULL;
1198 if (sc.comp_unit)
1199 line_table = sc.comp_unit->GetLineTable();
1200
1201 if (line_table == NULL)
1202 {
1203 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1204 m_options.m_frame_idx, m_options.m_thread_idx);
1205 result.SetStatus (eReturnStatusFailed);
1206 return false;
1207 }
1208
1209 LineEntry function_start;
1210 uint32_t index_ptr = 0, end_ptr;
1211 std::vector<addr_t> address_list;
1212
1213 // Find the beginning & end index of the
1214 AddressRange fun_addr_range = sc.function->GetAddressRange();
1215 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1216 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1217
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001218 Address fun_end_addr(fun_start_addr.GetSection(),
1219 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001220
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001221 bool all_in_function = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001222
Jim Ingham9bdea542015-02-06 02:10:56 +00001223 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1224
1225 for (uint32_t line_number : line_numbers)
1226 {
1227 uint32_t start_idx_ptr = index_ptr;
1228 while (start_idx_ptr <= end_ptr)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001229 {
Jim Ingham9bdea542015-02-06 02:10:56 +00001230 LineEntry line_entry;
1231 const bool exact = false;
1232 start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
1233 if (start_idx_ptr == UINT32_MAX)
1234 break;
1235
1236 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1237 if (address != LLDB_INVALID_ADDRESS)
1238 {
1239 if (fun_addr_range.ContainsLoadAddress (address, target))
1240 address_list.push_back (address);
1241 else
1242 all_in_function = false;
1243 }
1244 start_idx_ptr++;
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001245 }
Jim Ingham9bdea542015-02-06 02:10:56 +00001246 }
1247
1248 for (lldb::addr_t address : m_options.m_until_addrs)
1249 {
1250 if (fun_addr_range.ContainsLoadAddress (address, target))
1251 address_list.push_back (address);
1252 else
1253 all_in_function = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001254 }
1255
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001256 if (address_list.size() == 0)
1257 {
1258 if (all_in_function)
1259 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1260 else
1261 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1262
1263 result.SetStatus (eReturnStatusFailed);
1264 return false;
1265 }
1266
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001267 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001268 &address_list.front(),
1269 address_list.size(),
1270 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001271 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001272 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1273 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1274 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001275 new_plan_sp->SetIsMasterPlan (true);
1276 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001277 }
1278 else
1279 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001280 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1281 m_options.m_frame_idx,
1282 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001283 result.SetStatus (eReturnStatusFailed);
1284 return false;
1285
1286 }
1287
Greg Claytondc6224e2014-10-21 01:00:42 +00001288
1289
Jim Ingham2976d002010-08-26 21:32:51 +00001290 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Greg Claytondc6224e2014-10-21 01:00:42 +00001291
1292 StreamString stream;
1293 Error error;
1294 if (synchronous_execution)
1295 error = process->ResumeSynchronous (&stream);
1296 else
1297 error = process->Resume ();
1298
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001299 if (error.Success())
1300 {
Daniel Malead01b2952012-11-29 21:49:15 +00001301 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 if (synchronous_execution)
1303 {
Greg Claytondc6224e2014-10-21 01:00:42 +00001304 // If any state changed events had anything to say, add that to the result
1305 if (stream.GetData())
1306 result.AppendMessage(stream.GetData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001307
1308 result.SetDidChangeProcessState (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1310 }
1311 else
1312 {
1313 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1314 }
1315 }
1316 else
1317 {
1318 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1319 result.SetStatus (eReturnStatusFailed);
1320 }
1321
1322 }
1323 return result.Succeeded();
1324 }
Jim Ingham5a988412012-06-08 21:56:10 +00001325
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001326 CommandOptions m_options;
1327
1328};
1329
Greg Claytone0d378b2011-03-24 21:19:54 +00001330OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001331CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1332{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001333{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1334{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
Jim Ingham9bdea542015-02-06 02:10:56 +00001335{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"},
1336{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."},
Zachary Turnerd37221d2014-07-09 16:31:49 +00001337{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001338};
1339
1340
1341//-------------------------------------------------------------------------
1342// CommandObjectThreadSelect
1343//-------------------------------------------------------------------------
1344
Jim Ingham5a988412012-06-08 21:56:10 +00001345class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001346{
1347public:
1348
Greg Claytona7015092010-09-18 01:14:36 +00001349 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001350 CommandObjectParsed (interpreter,
1351 "thread select",
1352 "Select a thread as the currently active thread.",
1353 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001354 eFlagRequiresProcess |
1355 eFlagTryTargetAPILock |
1356 eFlagProcessMustBeLaunched |
1357 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001358 {
Caroline Tice405fe672010-10-04 22:28:36 +00001359 CommandArgumentEntry arg;
1360 CommandArgumentData thread_idx_arg;
1361
1362 // Define the first (and only) variant of this arg.
1363 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1364 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1365
1366 // There is only one variant this argument could be; put it into the argument entry.
1367 arg.push_back (thread_idx_arg);
1368
1369 // Push the data for the first argument into the m_arguments vector.
1370 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001371 }
1372
1373
1374 virtual
1375 ~CommandObjectThreadSelect ()
1376 {
1377 }
1378
Jim Ingham5a988412012-06-08 21:56:10 +00001379protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001381 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001382 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001383 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001384 if (process == NULL)
1385 {
1386 result.AppendError ("no process");
1387 result.SetStatus (eReturnStatusFailed);
1388 return false;
1389 }
1390 else if (command.GetArgumentCount() != 1)
1391 {
Jason Molendafd54b362011-09-20 21:44:10 +00001392 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 +00001393 result.SetStatus (eReturnStatusFailed);
1394 return false;
1395 }
1396
Vince Harron5275aaa2015-01-15 20:08:35 +00001397 uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001398
1399 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1400 if (new_thread == NULL)
1401 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001402 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403 result.SetStatus (eReturnStatusFailed);
1404 return false;
1405 }
1406
Jim Inghamc3faa192012-12-11 02:31:48 +00001407 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001408 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001409
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001410 return result.Succeeded();
1411 }
1412
1413};
1414
1415
1416//-------------------------------------------------------------------------
1417// CommandObjectThreadList
1418//-------------------------------------------------------------------------
1419
Jim Ingham5a988412012-06-08 21:56:10 +00001420class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001421{
Greg Clayton66111032010-06-23 01:19:29 +00001422public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001423
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001424
Greg Claytona7015092010-09-18 01:14:36 +00001425 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001426 CommandObjectParsed (interpreter,
1427 "thread list",
1428 "Show a summary of all current threads in a process.",
1429 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001430 eFlagRequiresProcess |
1431 eFlagTryTargetAPILock |
1432 eFlagProcessMustBeLaunched |
1433 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434 {
Greg Clayton66111032010-06-23 01:19:29 +00001435 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001436
Greg Clayton66111032010-06-23 01:19:29 +00001437 ~CommandObjectThreadList()
1438 {
1439 }
1440
Jim Ingham5a988412012-06-08 21:56:10 +00001441protected:
Greg Clayton66111032010-06-23 01:19:29 +00001442 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001443 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001444 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001445 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001446 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001447 Process *process = m_exe_ctx.GetProcessPtr();
1448 const bool only_threads_with_stop_reason = false;
1449 const uint32_t start_frame = 0;
1450 const uint32_t num_frames = 0;
1451 const uint32_t num_frames_with_source = 0;
1452 process->GetStatus(strm);
1453 process->GetThreadStatus (strm,
1454 only_threads_with_stop_reason,
1455 start_frame,
1456 num_frames,
1457 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001458 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001459 }
Greg Clayton66111032010-06-23 01:19:29 +00001460};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001461
Jim Ingham93208b82013-01-31 21:46:01 +00001462//-------------------------------------------------------------------------
Jason Molenda705b1802014-06-13 02:37:02 +00001463// CommandObjectThreadInfo
1464//-------------------------------------------------------------------------
1465
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001466class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
Jason Molenda705b1802014-06-13 02:37:02 +00001467{
1468public:
1469
1470 CommandObjectThreadInfo (CommandInterpreter &interpreter) :
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001471 CommandObjectIterateOverThreads (interpreter,
1472 "thread info",
1473 "Show an extended summary of information about thread(s) in a process.",
1474 "thread info",
1475 eFlagRequiresProcess |
1476 eFlagTryTargetAPILock |
1477 eFlagProcessMustBeLaunched |
1478 eFlagProcessMustBePaused),
Jason Molenda705b1802014-06-13 02:37:02 +00001479 m_options (interpreter)
1480 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001481 m_add_return = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001482 }
1483
1484 class CommandOptions : public Options
1485 {
1486 public:
1487
1488 CommandOptions (CommandInterpreter &interpreter) :
1489 Options (interpreter)
1490 {
1491 OptionParsingStarting ();
1492 }
1493
1494 void
1495 OptionParsingStarting ()
1496 {
Kuba Breckaafdf8422014-10-10 23:43:03 +00001497 m_json_thread = false;
1498 m_json_stopinfo = false;
Jason Molenda705b1802014-06-13 02:37:02 +00001499 }
1500
1501 virtual
1502 ~CommandOptions ()
1503 {
1504 }
1505
1506 virtual Error
1507 SetOptionValue (uint32_t option_idx, const char *option_arg)
1508 {
1509 const int short_option = m_getopt_table[option_idx].val;
1510 Error error;
1511
1512 switch (short_option)
1513 {
1514 case 'j':
Kuba Breckaafdf8422014-10-10 23:43:03 +00001515 m_json_thread = true;
1516 break;
1517
1518 case 's':
1519 m_json_stopinfo = true;
Jason Molenda705b1802014-06-13 02:37:02 +00001520 break;
1521
Kuba Breckaafdf8422014-10-10 23:43:03 +00001522 default:
Jason Molenda705b1802014-06-13 02:37:02 +00001523 return Error("invalid short option character '%c'", short_option);
1524
1525 }
1526 return error;
1527 }
1528
1529 const OptionDefinition*
1530 GetDefinitions ()
1531 {
1532 return g_option_table;
1533 }
1534
Kuba Breckaafdf8422014-10-10 23:43:03 +00001535 bool m_json_thread;
1536 bool m_json_stopinfo;
Jason Molenda705b1802014-06-13 02:37:02 +00001537
1538 static OptionDefinition g_option_table[];
1539 };
1540
1541 virtual
1542 Options *
1543 GetOptions ()
1544 {
1545 return &m_options;
1546 }
1547
1548
1549 virtual
1550 ~CommandObjectThreadInfo ()
1551 {
1552 }
1553
1554 virtual bool
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001555 HandleOneThread (Thread &thread, CommandReturnObject &result)
Jason Molenda705b1802014-06-13 02:37:02 +00001556 {
Jason Molenda705b1802014-06-13 02:37:02 +00001557 Stream &strm = result.GetOutputStream();
Kuba Breckaafdf8422014-10-10 23:43:03 +00001558 if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
Jason Molenda705b1802014-06-13 02:37:02 +00001559 {
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001560 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
1561 result.SetStatus (eReturnStatusFailed);
1562 return false;
Jason Molenda705b1802014-06-13 02:37:02 +00001563 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001564 return true;
Jason Molenda705b1802014-06-13 02:37:02 +00001565 }
1566
1567 CommandOptions m_options;
1568
1569};
1570
1571OptionDefinition
1572CommandObjectThreadInfo::CommandOptions::g_option_table[] =
1573{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001574 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."},
Kuba Breckaafdf8422014-10-10 23:43:03 +00001575 { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
Jason Molenda705b1802014-06-13 02:37:02 +00001576
Zachary Turnerd37221d2014-07-09 16:31:49 +00001577 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jason Molenda705b1802014-06-13 02:37:02 +00001578};
1579
1580
1581//-------------------------------------------------------------------------
Jim Ingham93208b82013-01-31 21:46:01 +00001582// CommandObjectThreadReturn
1583//-------------------------------------------------------------------------
1584
Jim Inghamcb640dd2012-09-14 02:14:15 +00001585class CommandObjectThreadReturn : public CommandObjectRaw
1586{
1587public:
Jim Ingham93208b82013-01-31 21:46:01 +00001588 class CommandOptions : public Options
1589 {
1590 public:
1591
1592 CommandOptions (CommandInterpreter &interpreter) :
1593 Options (interpreter),
1594 m_from_expression (false)
1595 {
1596 // Keep default values of all options in one place: OptionParsingStarting ()
1597 OptionParsingStarting ();
1598 }
1599
1600 virtual
1601 ~CommandOptions ()
1602 {
1603 }
1604
1605 virtual Error
1606 SetOptionValue (uint32_t option_idx, const char *option_arg)
1607 {
1608 Error error;
1609 const int short_option = m_getopt_table[option_idx].val;
1610
1611 switch (short_option)
1612 {
1613 case 'x':
1614 {
1615 bool success;
1616 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1617 if (success)
1618 m_from_expression = tmp_value;
1619 else
1620 {
1621 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1622 }
1623 }
1624 break;
1625 default:
1626 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1627 break;
1628
1629 }
1630 return error;
1631 }
1632
1633 void
1634 OptionParsingStarting ()
1635 {
1636 m_from_expression = false;
1637 }
1638
1639 const OptionDefinition*
1640 GetDefinitions ()
1641 {
1642 return g_option_table;
1643 }
1644
1645 bool m_from_expression;
1646
1647 // Options table: Required for subclasses of Options.
1648
1649 static OptionDefinition g_option_table[];
1650
1651 // Instance variables to hold the values for command options.
1652 };
1653
1654 virtual
1655 Options *
1656 GetOptions ()
1657 {
1658 return &m_options;
1659 }
1660
Jim Inghamcb640dd2012-09-14 02:14:15 +00001661 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1662 CommandObjectRaw (interpreter,
1663 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001664 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1665 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001666 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001667 eFlagRequiresFrame |
1668 eFlagTryTargetAPILock |
1669 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001670 eFlagProcessMustBePaused ),
1671 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001672 {
1673 CommandArgumentEntry arg;
1674 CommandArgumentData expression_arg;
1675
1676 // Define the first (and only) variant of this arg.
1677 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001678 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001679
1680 // There is only one variant this argument could be; put it into the argument entry.
1681 arg.push_back (expression_arg);
1682
1683 // Push the data for the first argument into the m_arguments vector.
1684 m_arguments.push_back (arg);
1685
1686
1687 }
1688
1689 ~CommandObjectThreadReturn()
1690 {
1691 }
1692
1693protected:
1694
1695 bool DoExecute
1696 (
1697 const char *command,
1698 CommandReturnObject &result
1699 )
1700 {
Jim Ingham93208b82013-01-31 21:46:01 +00001701 // I am going to handle this by hand, because I don't want you to have to say:
1702 // "thread return -- -5".
1703 if (command[0] == '-' && command[1] == 'x')
1704 {
1705 if (command && command[2] != '\0')
1706 result.AppendWarning("Return values ignored when returning from user called expressions");
1707
1708 Thread *thread = m_exe_ctx.GetThreadPtr();
1709 Error error;
1710 error = thread->UnwindInnermostExpression();
1711 if (!error.Success())
1712 {
1713 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1714 result.SetStatus (eReturnStatusFailed);
1715 }
1716 else
1717 {
1718 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1719 if (success)
1720 {
1721 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1722 result.SetStatus (eReturnStatusSuccessFinishResult);
1723 }
1724 else
1725 {
1726 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1727 result.SetStatus (eReturnStatusFailed);
1728 }
1729 }
1730 return result.Succeeded();
1731 }
1732
Jim Inghamcb640dd2012-09-14 02:14:15 +00001733 ValueObjectSP return_valobj_sp;
1734
Jason Molendab57e4a12013-11-04 09:33:30 +00001735 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001736 uint32_t frame_idx = frame_sp->GetFrameIndex();
1737
1738 if (frame_sp->IsInlined())
1739 {
1740 result.AppendError("Don't know how to return from inlined frames.");
1741 result.SetStatus (eReturnStatusFailed);
1742 return false;
1743 }
1744
1745 if (command && command[0] != '\0')
1746 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001747 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001748 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001749
1750 options.SetUnwindOnError(true);
1751 options.SetUseDynamic(eNoDynamicValues);
1752
Jim Ingham8646d3c2014-05-05 02:47:44 +00001753 ExpressionResults exe_results = eExpressionSetupError;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001754 exe_results = target->EvaluateExpression (command,
1755 frame_sp.get(),
1756 return_valobj_sp,
1757 options);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001758 if (exe_results != eExpressionCompleted)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001759 {
1760 if (return_valobj_sp)
1761 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1762 else
1763 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1764 result.SetStatus (eReturnStatusFailed);
1765 return false;
1766
1767 }
1768 }
1769
1770 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001771 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001772 const bool broadcast = true;
1773 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001774 if (!error.Success())
1775 {
1776 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1777 result.SetStatus (eReturnStatusFailed);
1778 return false;
1779 }
1780
Jim Inghamcb640dd2012-09-14 02:14:15 +00001781 result.SetStatus (eReturnStatusSuccessFinishResult);
1782 return true;
1783 }
Jim Ingham93208b82013-01-31 21:46:01 +00001784
1785 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001786
1787};
Jim Ingham93208b82013-01-31 21:46:01 +00001788OptionDefinition
1789CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1790{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001791{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1792{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham93208b82013-01-31 21:46:01 +00001793};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001794
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001795//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001796// CommandObjectThreadJump
1797//-------------------------------------------------------------------------
1798
1799class CommandObjectThreadJump : public CommandObjectParsed
1800{
1801public:
1802 class CommandOptions : public Options
1803 {
1804 public:
1805
1806 CommandOptions (CommandInterpreter &interpreter) :
1807 Options (interpreter)
1808 {
1809 OptionParsingStarting ();
1810 }
1811
1812 void
1813 OptionParsingStarting ()
1814 {
1815 m_filenames.Clear();
1816 m_line_num = 0;
1817 m_line_offset = 0;
1818 m_load_addr = LLDB_INVALID_ADDRESS;
1819 m_force = false;
1820 }
1821
1822 virtual
1823 ~CommandOptions ()
1824 {
1825 }
1826
1827 virtual Error
1828 SetOptionValue (uint32_t option_idx, const char *option_arg)
1829 {
1830 bool success;
1831 const int short_option = m_getopt_table[option_idx].val;
1832 Error error;
1833
1834 switch (short_option)
1835 {
1836 case 'f':
1837 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1838 if (m_filenames.GetSize() > 1)
1839 return Error("only one source file expected.");
1840 break;
1841 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001842 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001843 if (!success || m_line_num == 0)
1844 return Error("invalid line number: '%s'.", option_arg);
1845 break;
1846 case 'b':
Vince Harron5275aaa2015-01-15 20:08:35 +00001847 m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
Richard Mittonf86248d2013-09-12 02:20:34 +00001848 if (!success)
1849 return Error("invalid line offset: '%s'.", option_arg);
1850 break;
1851 case 'a':
1852 {
1853 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1854 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1855 }
1856 break;
1857 case 'r':
1858 m_force = true;
1859 break;
1860
1861 default:
1862 return Error("invalid short option character '%c'", short_option);
1863
1864 }
1865 return error;
1866 }
1867
1868 const OptionDefinition*
1869 GetDefinitions ()
1870 {
1871 return g_option_table;
1872 }
1873
1874 FileSpecList m_filenames;
1875 uint32_t m_line_num;
1876 int32_t m_line_offset;
1877 lldb::addr_t m_load_addr;
1878 bool m_force;
1879
1880 static OptionDefinition g_option_table[];
1881 };
1882
1883 virtual
1884 Options *
1885 GetOptions ()
1886 {
1887 return &m_options;
1888 }
1889
1890 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1891 CommandObjectParsed (interpreter,
1892 "thread jump",
1893 "Sets the program counter to a new address.",
1894 "thread jump",
1895 eFlagRequiresFrame |
1896 eFlagTryTargetAPILock |
1897 eFlagProcessMustBeLaunched |
1898 eFlagProcessMustBePaused ),
1899 m_options (interpreter)
1900 {
1901 }
1902
1903 ~CommandObjectThreadJump()
1904 {
1905 }
1906
1907protected:
1908
1909 bool DoExecute (Args& args, CommandReturnObject &result)
1910 {
1911 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001912 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001913 Thread *thread = m_exe_ctx.GetThreadPtr();
1914 Target *target = m_exe_ctx.GetTargetPtr();
1915 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1916
1917 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1918 {
1919 // Use this address directly.
1920 Address dest = Address(m_options.m_load_addr);
1921
1922 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1923 if (callAddr == LLDB_INVALID_ADDRESS)
1924 {
1925 result.AppendErrorWithFormat ("Invalid destination address.");
1926 result.SetStatus (eReturnStatusFailed);
1927 return false;
1928 }
1929
1930 if (!reg_ctx->SetPC (callAddr))
1931 {
1932 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1933 result.SetStatus (eReturnStatusFailed);
1934 return false;
1935 }
1936 }
1937 else
1938 {
1939 // Pick either the absolute line, or work out a relative one.
1940 int32_t line = (int32_t)m_options.m_line_num;
1941 if (line == 0)
1942 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1943
1944 // Try the current file, but override if asked.
1945 FileSpec file = sym_ctx.line_entry.file;
1946 if (m_options.m_filenames.GetSize() == 1)
1947 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1948
1949 if (!file)
1950 {
1951 result.AppendErrorWithFormat ("No source file available for the current location.");
1952 result.SetStatus (eReturnStatusFailed);
1953 return false;
1954 }
1955
1956 std::string warnings;
1957 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1958
1959 if (err.Fail())
1960 {
1961 result.SetError (err);
1962 return false;
1963 }
1964
1965 if (!warnings.empty())
1966 result.AppendWarning (warnings.c_str());
1967 }
1968
1969 result.SetStatus (eReturnStatusSuccessFinishResult);
1970 return true;
1971 }
1972
1973 CommandOptions m_options;
1974};
1975OptionDefinition
1976CommandObjectThreadJump::CommandOptions::g_option_table[] =
1977{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001978 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Richard Mittonf86248d2013-09-12 02:20:34 +00001979 "Specifies the source file to jump to."},
1980
Zachary Turnerd37221d2014-07-09 16:31:49 +00001981 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Richard Mittonf86248d2013-09-12 02:20:34 +00001982 "Specifies the line number to jump to."},
1983
Zachary Turnerd37221d2014-07-09 16:31:49 +00001984 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,
Richard Mittonf86248d2013-09-12 02:20:34 +00001985 "Jumps by a relative line offset from the current line."},
1986
Zachary Turnerd37221d2014-07-09 16:31:49 +00001987 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Richard Mittonf86248d2013-09-12 02:20:34 +00001988 "Jumps to a specific address."},
1989
1990 { LLDB_OPT_SET_1|
1991 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +00001992 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
Richard Mittonf86248d2013-09-12 02:20:34 +00001993
Zachary Turnerd37221d2014-07-09 16:31:49 +00001994 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Richard Mittonf86248d2013-09-12 02:20:34 +00001995};
1996
1997//-------------------------------------------------------------------------
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001998// Next are the subcommands of CommandObjectMultiwordThreadPlan
1999//-------------------------------------------------------------------------
2000
2001
2002//-------------------------------------------------------------------------
2003// CommandObjectThreadPlanList
2004//-------------------------------------------------------------------------
2005class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
2006{
2007public:
2008
2009 class CommandOptions : public Options
2010 {
2011 public:
2012
2013 CommandOptions (CommandInterpreter &interpreter) :
2014 Options(interpreter)
2015 {
2016 // Keep default values of all options in one place: OptionParsingStarting ()
2017 OptionParsingStarting ();
2018 }
2019
2020 virtual
2021 ~CommandOptions ()
2022 {
2023 }
2024
2025 virtual Error
2026 SetOptionValue (uint32_t option_idx, const char *option_arg)
2027 {
2028 Error error;
2029 const int short_option = m_getopt_table[option_idx].val;
2030
2031 switch (short_option)
2032 {
2033 case 'i':
2034 {
2035 m_internal = true;
2036 }
2037 break;
2038 case 'v':
2039 {
2040 m_verbose = true;
2041 }
2042 break;
2043 default:
2044 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2045 break;
2046
2047 }
2048 return error;
2049 }
2050
2051 void
2052 OptionParsingStarting ()
2053 {
2054 m_verbose = false;
2055 m_internal = false;
2056 }
2057
2058 const OptionDefinition*
2059 GetDefinitions ()
2060 {
2061 return g_option_table;
2062 }
2063
2064 // Options table: Required for subclasses of Options.
2065
2066 static OptionDefinition g_option_table[];
2067
2068 // Instance variables to hold the values for command options.
2069 bool m_verbose;
2070 bool m_internal;
2071 };
2072
2073 CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
2074 CommandObjectIterateOverThreads (interpreter,
2075 "thread plan list",
2076 "Show thread plans for one or more threads. If no threads are specified, show the "
2077 "currently selected thread. Use the thread-index \"all\" to see all threads.",
2078 NULL,
2079 eFlagRequiresProcess |
2080 eFlagRequiresThread |
2081 eFlagTryTargetAPILock |
2082 eFlagProcessMustBeLaunched |
2083 eFlagProcessMustBePaused ),
2084 m_options(interpreter)
2085 {
2086 }
2087
2088 ~CommandObjectThreadPlanList ()
2089 {
2090 }
2091
2092 virtual Options *
2093 GetOptions ()
2094 {
2095 return &m_options;
2096 }
2097
2098protected:
2099 virtual bool
2100 HandleOneThread (Thread &thread, CommandReturnObject &result)
2101 {
2102 Stream &strm = result.GetOutputStream();
2103 DescriptionLevel desc_level = eDescriptionLevelFull;
2104 if (m_options.m_verbose)
2105 desc_level = eDescriptionLevelVerbose;
2106
2107 thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
2108 return true;
2109 }
2110 CommandOptions m_options;
2111};
2112
2113OptionDefinition
2114CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
2115{
2116{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
2117{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
2118{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2119};
2120
2121class CommandObjectThreadPlanDiscard : public CommandObjectParsed
2122{
2123public:
2124 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
2125 CommandObjectParsed (interpreter,
2126 "thread plan discard",
2127 "Discards thread plans up to and including the plan passed as the command argument."
2128 "Only user visible plans can be discarded, use the index from \"thread plan list\""
2129 " without the \"-i\" argument.",
2130 NULL,
2131 eFlagRequiresProcess |
2132 eFlagRequiresThread |
2133 eFlagTryTargetAPILock |
2134 eFlagProcessMustBeLaunched |
2135 eFlagProcessMustBePaused )
2136 {
2137 CommandArgumentEntry arg;
2138 CommandArgumentData plan_index_arg;
2139
2140 // Define the first (and only) variant of this arg.
2141 plan_index_arg.arg_type = eArgTypeUnsignedInteger;
2142 plan_index_arg.arg_repetition = eArgRepeatPlain;
2143
2144 // There is only one variant this argument could be; put it into the argument entry.
2145 arg.push_back (plan_index_arg);
2146
2147 // Push the data for the first argument into the m_arguments vector.
2148 m_arguments.push_back (arg);
2149 }
2150
2151 virtual ~CommandObjectThreadPlanDiscard () {}
2152
2153 bool
2154 DoExecute (Args& args, CommandReturnObject &result)
2155 {
2156 Thread *thread = m_exe_ctx.GetThreadPtr();
2157 if (args.GetArgumentCount() != 1)
2158 {
2159 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
2160 args.GetArgumentCount());
2161 result.SetStatus (eReturnStatusFailed);
2162 return false;
2163 }
2164
2165 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00002166 uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002167 if (!success)
2168 {
2169 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
2170 args.GetArgumentAtIndex(0));
2171 result.SetStatus (eReturnStatusFailed);
2172 return false;
2173 }
2174
2175 if (thread_plan_idx == 0)
2176 {
2177 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
2178 result.SetStatus (eReturnStatusFailed);
2179 return false;
2180 }
2181
2182 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
2183 {
2184 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2185 return true;
2186 }
2187 else
2188 {
2189 result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
2190 args.GetArgumentAtIndex(0));
2191 result.SetStatus (eReturnStatusFailed);
2192 return false;
2193 }
2194 }
2195};
2196
2197//-------------------------------------------------------------------------
2198// CommandObjectMultiwordThreadPlan
2199//-------------------------------------------------------------------------
2200
2201class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
2202{
2203public:
2204 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
2205 CommandObjectMultiword (interpreter,
2206 "plan",
2207 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
2208 "thread plan <subcommand> [<subcommand objects]")
2209 {
2210 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
2211 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
2212 }
2213
2214 virtual ~CommandObjectMultiwordThreadPlan () {}
2215
2216
2217};
2218
2219//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002220// CommandObjectMultiwordThread
2221//-------------------------------------------------------------------------
2222
Greg Clayton66111032010-06-23 01:19:29 +00002223CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002224 CommandObjectMultiword (interpreter,
2225 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002226 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002227 "thread <subcommand> [<subcommand-options>]")
2228{
Greg Claytona7015092010-09-18 01:14:36 +00002229 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
2230 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
2231 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00002232 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00002233 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002234 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
2235 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
Jason Molenda705b1802014-06-13 02:37:02 +00002236 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00002237 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2238 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00002239 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00002240 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002241 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002242 eStepTypeInto,
2243 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00002244
Greg Claytona7015092010-09-18 01:14:36 +00002245 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2246 interpreter,
2247 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00002248 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002249 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002250 eStepTypeOut,
2251 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002252
Greg Claytona7015092010-09-18 01:14:36 +00002253 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2254 interpreter,
2255 "thread step-over",
2256 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002257 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002258 eStepTypeOver,
2259 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002260
Greg Claytona7015092010-09-18 01:14:36 +00002261 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2262 interpreter,
2263 "thread step-inst",
2264 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00002265 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002266 eStepTypeTrace,
2267 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00002268
Greg Claytona7015092010-09-18 01:14:36 +00002269 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2270 interpreter,
2271 "thread step-inst-over",
2272 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00002273 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00002274 eStepTypeTraceOver,
2275 eStepScopeInstruction)));
Jim Ingham2bdbfd52014-09-29 23:17:18 +00002276
2277 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
2278 interpreter,
2279 "thread step-scripted",
2280 "Step as instructed by the script class passed in the -C option.",
2281 NULL,
2282 eStepTypeScripted,
2283 eStepScopeSource)));
2284
2285 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002286}
2287
2288CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
2289{
2290}
2291
2292