blob: bfe9541154a3f67dc4787a982899fd9d12035b3b [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"
Greg Clayton7fb56d02011-02-01 01:31:41 +000021#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#include "lldb/Interpreter/Options.h"
25#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/LineTable.h"
28#include "lldb/Symbol/LineEntry.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Process.h"
30#include "lldb/Target/RegisterContext.h"
Jason Molenda750ea692013-11-12 07:02:07 +000031#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
34#include "lldb/Target/ThreadPlan.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Target/ThreadPlanStepInstruction.h"
36#include "lldb/Target/ThreadPlanStepOut.h"
37#include "lldb/Target/ThreadPlanStepRange.h"
38#include "lldb/Target/ThreadPlanStepInRange.h"
Greg Clayton1f746072012-08-29 21:13:06 +000039
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040
41using namespace lldb;
42using namespace lldb_private;
43
44
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045//-------------------------------------------------------------------------
46// CommandObjectThreadBacktrace
47//-------------------------------------------------------------------------
48
Jim Ingham5a988412012-06-08 21:56:10 +000049class CommandObjectThreadBacktrace : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050{
51public:
52
Jim Inghame2e0b452010-08-26 23:36:03 +000053 class CommandOptions : public Options
54 {
55 public:
56
Greg Claytoneb0103f2011-04-07 22:46:35 +000057 CommandOptions (CommandInterpreter &interpreter) :
58 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +000059 {
Greg Claytonf6b8b582011-04-13 00:18:08 +000060 // Keep default values of all options in one place: OptionParsingStarting ()
61 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +000062 }
63
64 virtual
65 ~CommandOptions ()
66 {
67 }
68
69 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +000070 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame2e0b452010-08-26 23:36:03 +000071 {
72 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000073 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame2e0b452010-08-26 23:36:03 +000074
75 switch (short_option)
76 {
77 case 'c':
78 {
79 bool success;
80 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
81 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000082 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +000083 if (input_count < -1)
84 m_count = UINT32_MAX;
85 else
86 m_count = input_count;
87 }
88 break;
89 case 's':
90 {
91 bool success;
92 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
93 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000094 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +000095 }
Jason Molenda750ea692013-11-12 07:02:07 +000096 case 'e':
97 {
98 bool success;
99 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
100 if (!success)
101 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
102 }
Jim Inghame2e0b452010-08-26 23:36:03 +0000103 break;
104 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000105 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +0000106 break;
107
108 }
109 return error;
110 }
111
112 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000113 OptionParsingStarting ()
Jim Inghame2e0b452010-08-26 23:36:03 +0000114 {
Greg Clayton7260f622011-04-18 08:33:37 +0000115 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000116 m_start = 0;
Jason Molenda750ea692013-11-12 07:02:07 +0000117 m_extended_backtrace = false;
Jim Inghame2e0b452010-08-26 23:36:03 +0000118 }
119
Greg Claytone0d378b2011-03-24 21:19:54 +0000120 const OptionDefinition*
Jim Inghame2e0b452010-08-26 23:36:03 +0000121 GetDefinitions ()
122 {
123 return g_option_table;
124 }
125
126 // Options table: Required for subclasses of Options.
127
Greg Claytone0d378b2011-03-24 21:19:54 +0000128 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000129
130 // Instance variables to hold the values for command options.
131 uint32_t m_count;
132 uint32_t m_start;
Jason Molenda750ea692013-11-12 07:02:07 +0000133 bool m_extended_backtrace;
Jim Inghame2e0b452010-08-26 23:36:03 +0000134 };
135
Greg Claytona7015092010-09-18 01:14:36 +0000136 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000137 CommandObjectParsed (interpreter,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000138 "thread backtrace",
139 "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.",
140 NULL,
141 eFlagRequiresProcess |
142 eFlagRequiresThread |
143 eFlagTryTargetAPILock |
144 eFlagProcessMustBeLaunched |
145 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000146 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 {
Caroline Tice405fe672010-10-04 22:28:36 +0000148 CommandArgumentEntry arg;
149 CommandArgumentData thread_idx_arg;
150
151 // Define the first (and only) variant of this arg.
152 thread_idx_arg.arg_type = eArgTypeThreadIndex;
153 thread_idx_arg.arg_repetition = eArgRepeatStar;
154
155 // There is only one variant this argument could be; put it into the argument entry.
156 arg.push_back (thread_idx_arg);
157
158 // Push the data for the first argument into the m_arguments vector.
159 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 }
161
162 ~CommandObjectThreadBacktrace()
163 {
164 }
165
Jim Inghame2e0b452010-08-26 23:36:03 +0000166 virtual Options *
167 GetOptions ()
168 {
169 return &m_options;
170 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171
Jim Ingham5a988412012-06-08 21:56:10 +0000172protected:
Jason Molenda750ea692013-11-12 07:02:07 +0000173 void
174 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
175 {
176 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
177 if (runtime)
178 {
179 Stream &strm = result.GetOutputStream();
180 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
181 for (auto type : types)
182 {
183 ThreadSP ext_thread_sp = runtime->GetExtendedBacktrace (thread->shared_from_this(), type);
184 if (ext_thread_sp && ext_thread_sp->IsValid ())
185 {
186 const uint32_t num_frames_with_source = 0;
187 if (ext_thread_sp->GetStatus (strm,
188 m_options.m_start,
189 m_options.m_count,
190 num_frames_with_source))
191 {
192 DoExtendedBacktrace (ext_thread_sp.get(), result);
193 }
194 }
195 }
196 }
197 }
198
Greg Clayton66111032010-06-23 01:19:29 +0000199 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000200 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton7260f622011-04-18 08:33:37 +0000201 {
Jim Ingham09b263e2010-08-27 00:58:05 +0000202 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton7260f622011-04-18 08:33:37 +0000203 Stream &strm = result.GetOutputStream();
204
205 // Don't show source context when doing backtraces.
206 const uint32_t num_frames_with_source = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207 if (command.GetArgumentCount() == 0)
208 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000209 Thread *thread = m_exe_ctx.GetThreadPtr();
210 // Thread::GetStatus() returns the number of frames shown.
211 if (thread->GetStatus (strm,
212 m_options.m_start,
213 m_options.m_count,
214 num_frames_with_source))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000216 result.SetStatus (eReturnStatusSuccessFinishResult);
Jason Molenda750ea692013-11-12 07:02:07 +0000217 if (m_options.m_extended_backtrace)
218 {
219 DoExtendedBacktrace (thread, result);
220 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221 }
222 }
Jim Ingham09b263e2010-08-27 00:58:05 +0000223 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
224 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000225 Process *process = m_exe_ctx.GetProcessPtr();
Sean Callanan5c19eac2013-11-06 19:28:40 +0000226 uint32_t idx = 0;
227 for (ThreadSP thread_sp : process->Threads())
Jim Ingham09b263e2010-08-27 00:58:05 +0000228 {
Sean Callanan5c19eac2013-11-06 19:28:40 +0000229 if (idx != 0)
230 result.AppendMessage("");
231
Johnny Chenf2ddc712011-06-01 23:19:52 +0000232 if (!thread_sp->GetStatus (strm,
233 m_options.m_start,
234 m_options.m_count,
235 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000236 {
Sean Callanan5c19eac2013-11-06 19:28:40 +0000237 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", idx);
Jim Ingham09b263e2010-08-27 00:58:05 +0000238 result.SetStatus (eReturnStatusFailed);
239 return false;
240 }
Jason Molenda750ea692013-11-12 07:02:07 +0000241 if (m_options.m_extended_backtrace)
242 {
243 DoExtendedBacktrace (thread_sp.get(), result);
244 }
Jim Ingham5c4df7a2011-07-26 02:39:59 +0000245
Sean Callanan5c19eac2013-11-06 19:28:40 +0000246 ++idx;
Jim Ingham09b263e2010-08-27 00:58:05 +0000247 }
248 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 else
250 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000251 const size_t num_args = command.GetArgumentCount();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000252 Process *process = m_exe_ctx.GetProcessPtr();
Jim Ingham41f2b942012-09-10 20:50:15 +0000253 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Ingham09b263e2010-08-27 00:58:05 +0000254 std::vector<ThreadSP> thread_sps;
255
Greg Claytonc7bece562013-01-25 18:06:21 +0000256 for (size_t i = 0; i < num_args; i++)
Jim Ingham09b263e2010-08-27 00:58:05 +0000257 {
258 bool success;
259
260 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
261 if (!success)
262 {
263 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
264 result.SetStatus (eReturnStatusFailed);
265 return false;
266 }
267
268 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
269
270 if (!thread_sps[i])
271 {
272 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
273 result.SetStatus (eReturnStatusFailed);
274 return false;
275 }
276
277 }
278
279 for (uint32_t i = 0; i < num_args; i++)
280 {
Greg Clayton7260f622011-04-18 08:33:37 +0000281 if (!thread_sps[i]->GetStatus (strm,
282 m_options.m_start,
283 m_options.m_count,
284 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000285 {
286 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
287 result.SetStatus (eReturnStatusFailed);
288 return false;
289 }
Jason Molenda750ea692013-11-12 07:02:07 +0000290 if (m_options.m_extended_backtrace)
291 {
292 DoExtendedBacktrace (thread_sps[i].get(), result);
293 }
Jim Ingham09b263e2010-08-27 00:58:05 +0000294
295 if (i < num_args - 1)
296 result.AppendMessage("");
297 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298 }
299 return result.Succeeded();
300 }
Jim Ingham5a988412012-06-08 21:56:10 +0000301
Jim Inghame2e0b452010-08-26 23:36:03 +0000302 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303};
304
Greg Claytone0d378b2011-03-24 21:19:54 +0000305OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000306CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
307{
Virgile Belloe2607b52013-09-05 16:42:23 +0000308{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
309{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
Jason Molenda750ea692013-11-12 07:02:07 +0000310{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
Caroline Ticedeaab222010-10-01 19:59:14 +0000311{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Inghame2e0b452010-08-26 23:36:03 +0000312};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313
Greg Clayton69b518f2010-07-07 17:07:17 +0000314enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315{
316 eStepScopeSource,
317 eStepScopeInstruction
318};
319
Jim Ingham5a988412012-06-08 21:56:10 +0000320class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321{
322public:
323
324 class CommandOptions : public Options
325 {
326 public:
327
Greg Claytoneb0103f2011-04-07 22:46:35 +0000328 CommandOptions (CommandInterpreter &interpreter) :
329 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000331 // Keep default values of all options in one place: OptionParsingStarting ()
332 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 }
334
335 virtual
336 ~CommandOptions ()
337 {
338 }
339
340 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000341 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 {
343 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000344 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345
346 switch (short_option)
347 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000348 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 {
350 bool success;
351 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
352 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000353 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354 }
355 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000356
357 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000360 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 }
362 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000363
364 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000365 {
366 m_avoid_regexp.clear();
367 m_avoid_regexp.assign(option_arg);
368 }
369 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000370
Jim Inghamc6276822012-12-12 19:58:40 +0000371 case 't':
372 {
373 m_step_in_target.clear();
374 m_step_in_target.assign(option_arg);
375
376 }
377 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000378 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000379 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000380 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381
382 }
383 return error;
384 }
385
386 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000387 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389 m_avoid_no_debug = true;
390 m_run_mode = eOnlyDuringStepping;
Jim Inghama56c8002010-07-10 02:27:39 +0000391 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000392 m_step_in_target.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000393 }
394
Greg Claytone0d378b2011-03-24 21:19:54 +0000395 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 GetDefinitions ()
397 {
398 return g_option_table;
399 }
400
401 // Options table: Required for subclasses of Options.
402
Greg Claytone0d378b2011-03-24 21:19:54 +0000403 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404
405 // Instance variables to hold the values for command options.
406 bool m_avoid_no_debug;
407 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000408 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000409 std::string m_step_in_target;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410 };
411
Greg Claytona7015092010-09-18 01:14:36 +0000412 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
413 const char *name,
414 const char *help,
415 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000416 StepType step_type,
417 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000418 CommandObjectParsed (interpreter, name, help, syntax,
419 eFlagRequiresProcess |
420 eFlagRequiresThread |
421 eFlagTryTargetAPILock |
422 eFlagProcessMustBeLaunched |
423 eFlagProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424 m_step_type (step_type),
425 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000426 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 {
Caroline Tice405fe672010-10-04 22:28:36 +0000428 CommandArgumentEntry arg;
429 CommandArgumentData thread_id_arg;
430
431 // Define the first (and only) variant of this arg.
432 thread_id_arg.arg_type = eArgTypeThreadID;
433 thread_id_arg.arg_repetition = eArgRepeatOptional;
434
435 // There is only one variant this argument could be; put it into the argument entry.
436 arg.push_back (thread_id_arg);
437
438 // Push the data for the first argument into the m_arguments vector.
439 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440 }
441
442 virtual
443 ~CommandObjectThreadStepWithTypeAndScope ()
444 {
445 }
446
447 virtual
448 Options *
449 GetOptions ()
450 {
451 return &m_options;
452 }
453
Jim Ingham5a988412012-06-08 21:56:10 +0000454protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000456 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000458 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000459 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000460
Greg Claytonf9fc6092013-01-09 19:44:40 +0000461 const uint32_t num_threads = process->GetThreadList().GetSize();
462 Thread *thread = NULL;
463
464 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000466 thread = process->GetThreadList().GetSelectedThread().get();
467 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000468 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000469 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000470 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000471 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000473 }
474 else
475 {
476 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
477 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
478 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000479 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000480 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
481 result.SetStatus (eReturnStatusFailed);
482 return false;
483 }
484 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
485 if (thread == NULL)
486 {
487 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
488 step_thread_idx, num_threads);
489 result.SetStatus (eReturnStatusFailed);
490 return false;
491 }
492 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000493
Greg Claytonf9fc6092013-01-09 19:44:40 +0000494 const bool abort_other_plans = false;
495 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
496
497 // This is a bit unfortunate, but not all the commands in this command object support
498 // only while stepping, so I use the bool for them.
499 bool bool_stop_other_threads;
500 if (m_options.m_run_mode == eAllThreads)
501 bool_stop_other_threads = false;
502 else if (m_options.m_run_mode == eOnlyDuringStepping)
503 {
504 if (m_step_type == eStepTypeOut)
505 bool_stop_other_threads = false;
506 else
507 bool_stop_other_threads = true;
508 }
509 else
510 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000511
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000512 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000513
514 if (m_step_type == eStepTypeInto)
515 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000516 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000517
518 if (frame->HasDebugInformation ())
519 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000520 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000521 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
522 frame->GetSymbolContext(eSymbolContextEverything),
523 m_options.m_step_in_target.c_str(),
524 stop_other_threads,
525 m_options.m_avoid_no_debug);
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000526 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000527 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000528 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000529 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000530 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000531 }
532 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000533 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000534
535 }
536 else if (m_step_type == eStepTypeOver)
537 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000538 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000539
540 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000541 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000542 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
543 frame->GetSymbolContext(eSymbolContextEverything),
544 stop_other_threads);
545 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000546 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000547 abort_other_plans,
548 bool_stop_other_threads);
549
550 }
551 else if (m_step_type == eStepTypeTrace)
552 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000553 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000554 }
555 else if (m_step_type == eStepTypeTraceOver)
556 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000557 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000558 }
559 else if (m_step_type == eStepTypeOut)
560 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000561 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000562 NULL,
563 false,
564 bool_stop_other_threads,
565 eVoteYes,
566 eVoteNoOpinion,
567 thread->GetSelectedFrameIndex());
568 }
569 else
570 {
571 result.AppendError ("step type is not supported");
572 result.SetStatus (eReturnStatusFailed);
573 return false;
574 }
575
576 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
577 // so that they can be interruptible). Then resume the process.
578
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000579 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000580 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000581 new_plan_sp->SetIsMasterPlan (true);
582 new_plan_sp->SetOkayToDiscard (false);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000583
584 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
585 process->Resume ();
586
587
588 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000589 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000590 StateType state = process->WaitForProcessToStop (NULL);
591
592 //EventSP event_sp;
593 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
594 //while (! StateIsStoppedState (state))
595 // {
596 // state = process->WaitForStateChangedEvents (NULL, event_sp);
597 // }
598 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
599 result.SetDidChangeProcessState (true);
600 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
601 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000603 else
604 {
605 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
606 }
607 }
608 else
609 {
610 result.AppendError ("Couldn't find thread plan to implement step type.");
611 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612 }
613 return result.Succeeded();
614 }
615
616protected:
617 StepType m_step_type;
618 StepScope m_step_scope;
619 CommandOptions m_options;
620};
621
Greg Claytone0d378b2011-03-24 21:19:54 +0000622static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623g_tri_running_mode[] =
624{
Greg Claytoned8a7052010-09-18 03:37:20 +0000625{ eOnlyThisThread, "this-thread", "Run only this thread"},
626{ eAllThreads, "all-threads", "Run all threads"},
627{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628{ 0, NULL, NULL }
629};
630
Greg Claytone0d378b2011-03-24 21:19:54 +0000631static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632g_duo_running_mode[] =
633{
Greg Claytoned8a7052010-09-18 03:37:20 +0000634{ eOnlyThisThread, "this-thread", "Run only this thread"},
635{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636{ 0, NULL, NULL }
637};
638
Greg Claytone0d378b2011-03-24 21:19:54 +0000639OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
641{
Virgile Belloe2607b52013-09-05 16:42:23 +0000642{ LLDB_OPT_SET_1, false, "avoid-no-debug", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether step-in will step over functions with no debug information."},
643{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
644{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
645{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
Caroline Ticedeaab222010-10-01 19:59:14 +0000646{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647};
648
649
650//-------------------------------------------------------------------------
651// CommandObjectThreadContinue
652//-------------------------------------------------------------------------
653
Jim Ingham5a988412012-06-08 21:56:10 +0000654class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655{
656public:
657
Greg Claytona7015092010-09-18 01:14:36 +0000658 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000659 CommandObjectParsed (interpreter,
660 "thread continue",
661 "Continue execution of one or more threads in an active process.",
662 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000663 eFlagRequiresThread |
664 eFlagTryTargetAPILock |
665 eFlagProcessMustBeLaunched |
666 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667 {
Caroline Tice405fe672010-10-04 22:28:36 +0000668 CommandArgumentEntry arg;
669 CommandArgumentData thread_idx_arg;
670
671 // Define the first (and only) variant of this arg.
672 thread_idx_arg.arg_type = eArgTypeThreadIndex;
673 thread_idx_arg.arg_repetition = eArgRepeatPlus;
674
675 // There is only one variant this argument could be; put it into the argument entry.
676 arg.push_back (thread_idx_arg);
677
678 // Push the data for the first argument into the m_arguments vector.
679 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000680 }
681
682
683 virtual
684 ~CommandObjectThreadContinue ()
685 {
686 }
687
688 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000689 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000690 {
Greg Claytona7015092010-09-18 01:14:36 +0000691 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000692
Greg Claytona7015092010-09-18 01:14:36 +0000693 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000695 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 result.SetStatus (eReturnStatusFailed);
697 return false;
698 }
699
Greg Claytonf9fc6092013-01-09 19:44:40 +0000700 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701 if (process == NULL)
702 {
703 result.AppendError ("no process exists. Cannot continue");
704 result.SetStatus (eReturnStatusFailed);
705 return false;
706 }
707
708 StateType state = process->GetState();
709 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
710 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711 const size_t argc = command.GetArgumentCount();
712 if (argc > 0)
713 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000714 // These two lines appear at the beginning of both blocks in
715 // this if..else, but that is because we need to release the
716 // lock before calling process->Resume below.
717 Mutex::Locker locker (process->GetThreadList().GetMutex());
718 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000719 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720 for (uint32_t i=0; i<argc; ++i)
721 {
Jim Inghamce76c622012-05-31 20:48:41 +0000722 bool success;
723 const int base = 0;
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000724 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
725 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000726 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000727 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000728
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000729 if (thread)
730 {
731 resume_threads.push_back(thread);
732 }
733 else
734 {
735 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
736 result.SetStatus (eReturnStatusFailed);
737 return false;
738 }
Jim Inghamce76c622012-05-31 20:48:41 +0000739 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000740 else
Jim Inghamce76c622012-05-31 20:48:41 +0000741 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000742 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000743 result.SetStatus (eReturnStatusFailed);
744 return false;
745 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000746 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000747
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000748 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749 {
750 result.AppendError ("no valid thread indexes were specified");
751 result.SetStatus (eReturnStatusFailed);
752 return false;
753 }
754 else
755 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000756 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000757 result.AppendMessageWithFormat ("Resuming thread: ");
758 else
759 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000760
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000761 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000763 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
764 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000765
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000766 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000768 resume_threads.erase(this_thread_pos);
769 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000770 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
771 else
772 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000773
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774 thread->SetResumeState (eStateRunning);
775 }
776 else
777 {
778 thread->SetResumeState (eStateSuspended);
779 }
780 }
Daniel Malead01b2952012-11-29 21:49:15 +0000781 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 }
783 }
784 else
785 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000786 // These two lines appear at the beginning of both blocks in
787 // this if..else, but that is because we need to release the
788 // lock before calling process->Resume below.
789 Mutex::Locker locker (process->GetThreadList().GetMutex());
790 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000791 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000792 if (current_thread == NULL)
793 {
794 result.AppendError ("the process doesn't have a current thread");
795 result.SetStatus (eReturnStatusFailed);
796 return false;
797 }
798 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000799 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000801 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000802 if (thread == current_thread)
803 {
Daniel Malead01b2952012-11-29 21:49:15 +0000804 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000805 thread->SetResumeState (eStateRunning);
806 }
807 else
808 {
809 thread->SetResumeState (eStateSuspended);
810 }
811 }
812 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000813
814 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000815 Error error (process->Resume());
816 if (error.Success())
817 {
Daniel Malead01b2952012-11-29 21:49:15 +0000818 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000819 if (synchronous_execution)
820 {
Greg Claytonb1320972010-07-14 00:18:15 +0000821 state = process->WaitForProcessToStop (NULL);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000822
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +0000824 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825 result.SetStatus (eReturnStatusSuccessFinishNoResult);
826 }
827 else
828 {
829 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
830 }
831 }
832 else
833 {
834 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
835 result.SetStatus (eReturnStatusFailed);
836 }
837 }
838 else
839 {
840 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
841 StateAsCString(state));
842 result.SetStatus (eReturnStatusFailed);
843 }
844
845 return result.Succeeded();
846 }
847
848};
849
850//-------------------------------------------------------------------------
851// CommandObjectThreadUntil
852//-------------------------------------------------------------------------
853
Jim Ingham5a988412012-06-08 21:56:10 +0000854class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000855{
856public:
857
858 class CommandOptions : public Options
859 {
860 public:
861 uint32_t m_thread_idx;
862 uint32_t m_frame_idx;
863
Greg Claytoneb0103f2011-04-07 22:46:35 +0000864 CommandOptions (CommandInterpreter &interpreter) :
865 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866 m_thread_idx(LLDB_INVALID_THREAD_ID),
867 m_frame_idx(LLDB_INVALID_FRAME_ID)
868 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000869 // Keep default values of all options in one place: OptionParsingStarting ()
870 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871 }
872
873 virtual
874 ~CommandOptions ()
875 {
876 }
877
878 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000879 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880 {
881 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000882 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000883
884 switch (short_option)
885 {
886 case 't':
887 {
Greg Claytonb1320972010-07-14 00:18:15 +0000888 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000889 if (m_thread_idx == LLDB_INVALID_INDEX32)
890 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000891 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 }
893 }
894 break;
895 case 'f':
896 {
897 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
898 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
899 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000900 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901 }
902 }
903 break;
904 case 'm':
905 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000907 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000909 if (error.Success())
910 {
911 if (run_mode == eAllThreads)
912 m_stop_others = false;
913 else
914 m_stop_others = true;
915 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916 }
917 break;
918 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000919 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920 break;
921
922 }
923 return error;
924 }
925
926 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000927 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000929 m_thread_idx = LLDB_INVALID_THREAD_ID;
930 m_frame_idx = 0;
931 m_stop_others = false;
932 }
933
Greg Claytone0d378b2011-03-24 21:19:54 +0000934 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000935 GetDefinitions ()
936 {
937 return g_option_table;
938 }
939
940 uint32_t m_step_thread_idx;
941 bool m_stop_others;
942
943 // Options table: Required for subclasses of Options.
944
Greg Claytone0d378b2011-03-24 21:19:54 +0000945 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946
947 // Instance variables to hold the values for command options.
948 };
949
Greg Claytona7015092010-09-18 01:14:36 +0000950 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000951 CommandObjectParsed (interpreter,
952 "thread until",
953 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
954 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000955 eFlagRequiresThread |
956 eFlagTryTargetAPILock |
957 eFlagProcessMustBeLaunched |
958 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000959 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960 {
Caroline Tice405fe672010-10-04 22:28:36 +0000961 CommandArgumentEntry arg;
962 CommandArgumentData line_num_arg;
963
964 // Define the first (and only) variant of this arg.
965 line_num_arg.arg_type = eArgTypeLineNum;
966 line_num_arg.arg_repetition = eArgRepeatPlain;
967
968 // There is only one variant this argument could be; put it into the argument entry.
969 arg.push_back (line_num_arg);
970
971 // Push the data for the first argument into the m_arguments vector.
972 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973 }
974
975
976 virtual
977 ~CommandObjectThreadUntil ()
978 {
979 }
980
981 virtual
982 Options *
983 GetOptions ()
984 {
985 return &m_options;
986 }
987
Jim Ingham5a988412012-06-08 21:56:10 +0000988protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000989 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000990 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991 {
Greg Claytona7015092010-09-18 01:14:36 +0000992 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993
Greg Claytona7015092010-09-18 01:14:36 +0000994 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +0000995 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000997 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000998 result.SetStatus (eReturnStatusFailed);
999 return false;
1000 }
1001
Greg Claytonf9fc6092013-01-09 19:44:40 +00001002 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001003 if (process == NULL)
1004 {
1005 result.AppendError ("need a valid process to step");
1006 result.SetStatus (eReturnStatusFailed);
1007
1008 }
1009 else
1010 {
1011 Thread *thread = NULL;
1012 uint32_t line_number;
1013
1014 if (command.GetArgumentCount() != 1)
1015 {
1016 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1017 result.SetStatus (eReturnStatusFailed);
1018 return false;
1019 }
1020
1021 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1022 if (line_number == UINT32_MAX)
1023 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001024 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001025 result.SetStatus (eReturnStatusFailed);
1026 return false;
1027 }
1028
1029 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1030 {
Jim Ingham2976d002010-08-26 21:32:51 +00001031 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 }
1033 else
1034 {
Greg Clayton76927ee2012-05-31 00:29:20 +00001035 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036 }
1037
1038 if (thread == NULL)
1039 {
1040 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001041 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1042 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001043 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044 result.SetStatus (eReturnStatusFailed);
1045 return false;
1046 }
1047
Jim Ingham7ba6e992012-05-11 23:47:32 +00001048 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049
Jason Molendab57e4a12013-11-04 09:33:30 +00001050 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051 if (frame == NULL)
1052 {
1053
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001054 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1055 m_options.m_frame_idx,
1056 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057 result.SetStatus (eReturnStatusFailed);
1058 return false;
1059 }
1060
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001061 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062
1063 if (frame->HasDebugInformation ())
1064 {
1065 // Finally we got here... Translate the given line number to a bunch of addresses:
1066 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1067 LineTable *line_table = NULL;
1068 if (sc.comp_unit)
1069 line_table = sc.comp_unit->GetLineTable();
1070
1071 if (line_table == NULL)
1072 {
1073 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1074 m_options.m_frame_idx, m_options.m_thread_idx);
1075 result.SetStatus (eReturnStatusFailed);
1076 return false;
1077 }
1078
1079 LineEntry function_start;
1080 uint32_t index_ptr = 0, end_ptr;
1081 std::vector<addr_t> address_list;
1082
1083 // Find the beginning & end index of the
1084 AddressRange fun_addr_range = sc.function->GetAddressRange();
1085 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1086 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1087
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001088 Address fun_end_addr(fun_start_addr.GetSection(),
1089 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1091
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001092 bool all_in_function = true;
1093
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094 while (index_ptr <= end_ptr)
1095 {
1096 LineEntry line_entry;
Jim Ingham87df91b2011-09-23 00:54:11 +00001097 const bool exact = false;
1098 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 if (index_ptr == UINT32_MAX)
1100 break;
1101
Greg Claytonf5e56de2010-09-14 23:36:40 +00001102 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001103 if (address != LLDB_INVALID_ADDRESS)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001104 {
1105 if (fun_addr_range.ContainsLoadAddress (address, target))
1106 address_list.push_back (address);
1107 else
1108 all_in_function = false;
1109 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110 index_ptr++;
1111 }
1112
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001113 if (address_list.size() == 0)
1114 {
1115 if (all_in_function)
1116 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1117 else
1118 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1119
1120 result.SetStatus (eReturnStatusFailed);
1121 return false;
1122 }
1123
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001124 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001125 &address_list.front(),
1126 address_list.size(),
1127 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001128 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001129 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1130 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1131 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001132 new_plan_sp->SetIsMasterPlan (true);
1133 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134 }
1135 else
1136 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001137 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1138 m_options.m_frame_idx,
1139 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140 result.SetStatus (eReturnStatusFailed);
1141 return false;
1142
1143 }
1144
Jim Ingham2976d002010-08-26 21:32:51 +00001145 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001146 Error error (process->Resume ());
1147 if (error.Success())
1148 {
Daniel Malead01b2952012-11-29 21:49:15 +00001149 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 if (synchronous_execution)
1151 {
1152 StateType state = process->WaitForProcessToStop (NULL);
1153
1154 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +00001155 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001156 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1157 }
1158 else
1159 {
1160 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1161 }
1162 }
1163 else
1164 {
1165 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1166 result.SetStatus (eReturnStatusFailed);
1167 }
1168
1169 }
1170 return result.Succeeded();
1171 }
Jim Ingham5a988412012-06-08 21:56:10 +00001172
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001173 CommandOptions m_options;
1174
1175};
1176
Greg Claytone0d378b2011-03-24 21:19:54 +00001177OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001178CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1179{
Virgile Belloe2607b52013-09-05 16:42:23 +00001180{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1181{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1182{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
Caroline Ticedeaab222010-10-01 19:59:14 +00001183{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001184};
1185
1186
1187//-------------------------------------------------------------------------
1188// CommandObjectThreadSelect
1189//-------------------------------------------------------------------------
1190
Jim Ingham5a988412012-06-08 21:56:10 +00001191class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192{
1193public:
1194
Greg Claytona7015092010-09-18 01:14:36 +00001195 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001196 CommandObjectParsed (interpreter,
1197 "thread select",
1198 "Select a thread as the currently active thread.",
1199 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001200 eFlagRequiresProcess |
1201 eFlagTryTargetAPILock |
1202 eFlagProcessMustBeLaunched |
1203 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001204 {
Caroline Tice405fe672010-10-04 22:28:36 +00001205 CommandArgumentEntry arg;
1206 CommandArgumentData thread_idx_arg;
1207
1208 // Define the first (and only) variant of this arg.
1209 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1210 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1211
1212 // There is only one variant this argument could be; put it into the argument entry.
1213 arg.push_back (thread_idx_arg);
1214
1215 // Push the data for the first argument into the m_arguments vector.
1216 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001217 }
1218
1219
1220 virtual
1221 ~CommandObjectThreadSelect ()
1222 {
1223 }
1224
Jim Ingham5a988412012-06-08 21:56:10 +00001225protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001226 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001227 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001228 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001229 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230 if (process == NULL)
1231 {
1232 result.AppendError ("no process");
1233 result.SetStatus (eReturnStatusFailed);
1234 return false;
1235 }
1236 else if (command.GetArgumentCount() != 1)
1237 {
Jason Molendafd54b362011-09-20 21:44:10 +00001238 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 +00001239 result.SetStatus (eReturnStatusFailed);
1240 return false;
1241 }
1242
1243 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1244
1245 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1246 if (new_thread == NULL)
1247 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001248 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001249 result.SetStatus (eReturnStatusFailed);
1250 return false;
1251 }
1252
Jim Inghamc3faa192012-12-11 02:31:48 +00001253 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001254 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001256 return result.Succeeded();
1257 }
1258
1259};
1260
1261
1262//-------------------------------------------------------------------------
1263// CommandObjectThreadList
1264//-------------------------------------------------------------------------
1265
Jim Ingham5a988412012-06-08 21:56:10 +00001266class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267{
Greg Clayton66111032010-06-23 01:19:29 +00001268public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001270
Greg Claytona7015092010-09-18 01:14:36 +00001271 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001272 CommandObjectParsed (interpreter,
1273 "thread list",
1274 "Show a summary of all current threads in a process.",
1275 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001276 eFlagRequiresProcess |
1277 eFlagTryTargetAPILock |
1278 eFlagProcessMustBeLaunched |
1279 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001280 {
Greg Clayton66111032010-06-23 01:19:29 +00001281 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001282
Greg Clayton66111032010-06-23 01:19:29 +00001283 ~CommandObjectThreadList()
1284 {
1285 }
1286
Jim Ingham5a988412012-06-08 21:56:10 +00001287protected:
Greg Clayton66111032010-06-23 01:19:29 +00001288 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001289 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001290 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001291 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001292 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001293 Process *process = m_exe_ctx.GetProcessPtr();
1294 const bool only_threads_with_stop_reason = false;
1295 const uint32_t start_frame = 0;
1296 const uint32_t num_frames = 0;
1297 const uint32_t num_frames_with_source = 0;
1298 process->GetStatus(strm);
1299 process->GetThreadStatus (strm,
1300 only_threads_with_stop_reason,
1301 start_frame,
1302 num_frames,
1303 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001304 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001305 }
Greg Clayton66111032010-06-23 01:19:29 +00001306};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001307
Jim Ingham93208b82013-01-31 21:46:01 +00001308//-------------------------------------------------------------------------
1309// CommandObjectThreadReturn
1310//-------------------------------------------------------------------------
1311
Jim Inghamcb640dd2012-09-14 02:14:15 +00001312class CommandObjectThreadReturn : public CommandObjectRaw
1313{
1314public:
Jim Ingham93208b82013-01-31 21:46:01 +00001315 class CommandOptions : public Options
1316 {
1317 public:
1318
1319 CommandOptions (CommandInterpreter &interpreter) :
1320 Options (interpreter),
1321 m_from_expression (false)
1322 {
1323 // Keep default values of all options in one place: OptionParsingStarting ()
1324 OptionParsingStarting ();
1325 }
1326
1327 virtual
1328 ~CommandOptions ()
1329 {
1330 }
1331
1332 virtual Error
1333 SetOptionValue (uint32_t option_idx, const char *option_arg)
1334 {
1335 Error error;
1336 const int short_option = m_getopt_table[option_idx].val;
1337
1338 switch (short_option)
1339 {
1340 case 'x':
1341 {
1342 bool success;
1343 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1344 if (success)
1345 m_from_expression = tmp_value;
1346 else
1347 {
1348 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1349 }
1350 }
1351 break;
1352 default:
1353 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1354 break;
1355
1356 }
1357 return error;
1358 }
1359
1360 void
1361 OptionParsingStarting ()
1362 {
1363 m_from_expression = false;
1364 }
1365
1366 const OptionDefinition*
1367 GetDefinitions ()
1368 {
1369 return g_option_table;
1370 }
1371
1372 bool m_from_expression;
1373
1374 // Options table: Required for subclasses of Options.
1375
1376 static OptionDefinition g_option_table[];
1377
1378 // Instance variables to hold the values for command options.
1379 };
1380
1381 virtual
1382 Options *
1383 GetOptions ()
1384 {
1385 return &m_options;
1386 }
1387
Jim Inghamcb640dd2012-09-14 02:14:15 +00001388 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1389 CommandObjectRaw (interpreter,
1390 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001391 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1392 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001393 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001394 eFlagRequiresFrame |
1395 eFlagTryTargetAPILock |
1396 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001397 eFlagProcessMustBePaused ),
1398 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001399 {
1400 CommandArgumentEntry arg;
1401 CommandArgumentData expression_arg;
1402
1403 // Define the first (and only) variant of this arg.
1404 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001405 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001406
1407 // There is only one variant this argument could be; put it into the argument entry.
1408 arg.push_back (expression_arg);
1409
1410 // Push the data for the first argument into the m_arguments vector.
1411 m_arguments.push_back (arg);
1412
1413
1414 }
1415
1416 ~CommandObjectThreadReturn()
1417 {
1418 }
1419
1420protected:
1421
1422 bool DoExecute
1423 (
1424 const char *command,
1425 CommandReturnObject &result
1426 )
1427 {
Jim Ingham93208b82013-01-31 21:46:01 +00001428 // I am going to handle this by hand, because I don't want you to have to say:
1429 // "thread return -- -5".
1430 if (command[0] == '-' && command[1] == 'x')
1431 {
1432 if (command && command[2] != '\0')
1433 result.AppendWarning("Return values ignored when returning from user called expressions");
1434
1435 Thread *thread = m_exe_ctx.GetThreadPtr();
1436 Error error;
1437 error = thread->UnwindInnermostExpression();
1438 if (!error.Success())
1439 {
1440 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1441 result.SetStatus (eReturnStatusFailed);
1442 }
1443 else
1444 {
1445 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1446 if (success)
1447 {
1448 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1449 result.SetStatus (eReturnStatusSuccessFinishResult);
1450 }
1451 else
1452 {
1453 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1454 result.SetStatus (eReturnStatusFailed);
1455 }
1456 }
1457 return result.Succeeded();
1458 }
1459
Jim Inghamcb640dd2012-09-14 02:14:15 +00001460 ValueObjectSP return_valobj_sp;
1461
Jason Molendab57e4a12013-11-04 09:33:30 +00001462 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001463 uint32_t frame_idx = frame_sp->GetFrameIndex();
1464
1465 if (frame_sp->IsInlined())
1466 {
1467 result.AppendError("Don't know how to return from inlined frames.");
1468 result.SetStatus (eReturnStatusFailed);
1469 return false;
1470 }
1471
1472 if (command && command[0] != '\0')
1473 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001474 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001475 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001476
1477 options.SetUnwindOnError(true);
1478 options.SetUseDynamic(eNoDynamicValues);
1479
1480 ExecutionResults exe_results = eExecutionSetupError;
1481 exe_results = target->EvaluateExpression (command,
1482 frame_sp.get(),
1483 return_valobj_sp,
1484 options);
1485 if (exe_results != eExecutionCompleted)
1486 {
1487 if (return_valobj_sp)
1488 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1489 else
1490 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1491 result.SetStatus (eReturnStatusFailed);
1492 return false;
1493
1494 }
1495 }
1496
1497 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001498 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001499 const bool broadcast = true;
1500 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001501 if (!error.Success())
1502 {
1503 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1504 result.SetStatus (eReturnStatusFailed);
1505 return false;
1506 }
1507
Jim Inghamcb640dd2012-09-14 02:14:15 +00001508 result.SetStatus (eReturnStatusSuccessFinishResult);
1509 return true;
1510 }
Jim Ingham93208b82013-01-31 21:46:01 +00001511
1512 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001513
1514};
Jim Ingham93208b82013-01-31 21:46:01 +00001515OptionDefinition
1516CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1517{
Virgile Belloe2607b52013-09-05 16:42:23 +00001518{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
Jim Ingham93208b82013-01-31 21:46:01 +00001519{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1520};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001521
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001522//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001523// CommandObjectThreadJump
1524//-------------------------------------------------------------------------
1525
1526class CommandObjectThreadJump : public CommandObjectParsed
1527{
1528public:
1529 class CommandOptions : public Options
1530 {
1531 public:
1532
1533 CommandOptions (CommandInterpreter &interpreter) :
1534 Options (interpreter)
1535 {
1536 OptionParsingStarting ();
1537 }
1538
1539 void
1540 OptionParsingStarting ()
1541 {
1542 m_filenames.Clear();
1543 m_line_num = 0;
1544 m_line_offset = 0;
1545 m_load_addr = LLDB_INVALID_ADDRESS;
1546 m_force = false;
1547 }
1548
1549 virtual
1550 ~CommandOptions ()
1551 {
1552 }
1553
1554 virtual Error
1555 SetOptionValue (uint32_t option_idx, const char *option_arg)
1556 {
1557 bool success;
1558 const int short_option = m_getopt_table[option_idx].val;
1559 Error error;
1560
1561 switch (short_option)
1562 {
1563 case 'f':
1564 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1565 if (m_filenames.GetSize() > 1)
1566 return Error("only one source file expected.");
1567 break;
1568 case 'l':
1569 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1570 if (!success || m_line_num == 0)
1571 return Error("invalid line number: '%s'.", option_arg);
1572 break;
1573 case 'b':
1574 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1575 if (!success)
1576 return Error("invalid line offset: '%s'.", option_arg);
1577 break;
1578 case 'a':
1579 {
1580 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1581 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1582 }
1583 break;
1584 case 'r':
1585 m_force = true;
1586 break;
1587
1588 default:
1589 return Error("invalid short option character '%c'", short_option);
1590
1591 }
1592 return error;
1593 }
1594
1595 const OptionDefinition*
1596 GetDefinitions ()
1597 {
1598 return g_option_table;
1599 }
1600
1601 FileSpecList m_filenames;
1602 uint32_t m_line_num;
1603 int32_t m_line_offset;
1604 lldb::addr_t m_load_addr;
1605 bool m_force;
1606
1607 static OptionDefinition g_option_table[];
1608 };
1609
1610 virtual
1611 Options *
1612 GetOptions ()
1613 {
1614 return &m_options;
1615 }
1616
1617 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1618 CommandObjectParsed (interpreter,
1619 "thread jump",
1620 "Sets the program counter to a new address.",
1621 "thread jump",
1622 eFlagRequiresFrame |
1623 eFlagTryTargetAPILock |
1624 eFlagProcessMustBeLaunched |
1625 eFlagProcessMustBePaused ),
1626 m_options (interpreter)
1627 {
1628 }
1629
1630 ~CommandObjectThreadJump()
1631 {
1632 }
1633
1634protected:
1635
1636 bool DoExecute (Args& args, CommandReturnObject &result)
1637 {
1638 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001639 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001640 Thread *thread = m_exe_ctx.GetThreadPtr();
1641 Target *target = m_exe_ctx.GetTargetPtr();
1642 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1643
1644 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1645 {
1646 // Use this address directly.
1647 Address dest = Address(m_options.m_load_addr);
1648
1649 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1650 if (callAddr == LLDB_INVALID_ADDRESS)
1651 {
1652 result.AppendErrorWithFormat ("Invalid destination address.");
1653 result.SetStatus (eReturnStatusFailed);
1654 return false;
1655 }
1656
1657 if (!reg_ctx->SetPC (callAddr))
1658 {
1659 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1660 result.SetStatus (eReturnStatusFailed);
1661 return false;
1662 }
1663 }
1664 else
1665 {
1666 // Pick either the absolute line, or work out a relative one.
1667 int32_t line = (int32_t)m_options.m_line_num;
1668 if (line == 0)
1669 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1670
1671 // Try the current file, but override if asked.
1672 FileSpec file = sym_ctx.line_entry.file;
1673 if (m_options.m_filenames.GetSize() == 1)
1674 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1675
1676 if (!file)
1677 {
1678 result.AppendErrorWithFormat ("No source file available for the current location.");
1679 result.SetStatus (eReturnStatusFailed);
1680 return false;
1681 }
1682
1683 std::string warnings;
1684 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1685
1686 if (err.Fail())
1687 {
1688 result.SetError (err);
1689 return false;
1690 }
1691
1692 if (!warnings.empty())
1693 result.AppendWarning (warnings.c_str());
1694 }
1695
1696 result.SetStatus (eReturnStatusSuccessFinishResult);
1697 return true;
1698 }
1699
1700 CommandOptions m_options;
1701};
1702OptionDefinition
1703CommandObjectThreadJump::CommandOptions::g_option_table[] =
1704{
1705 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1706 "Specifies the source file to jump to."},
1707
1708 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
1709 "Specifies the line number to jump to."},
1710
1711 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset,
1712 "Jumps by a relative line offset from the current line."},
1713
1714 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression,
1715 "Jumps to a specific address."},
1716
1717 { LLDB_OPT_SET_1|
1718 LLDB_OPT_SET_2|
1719 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
1720
1721 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1722};
1723
1724//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001725// CommandObjectMultiwordThread
1726//-------------------------------------------------------------------------
1727
Greg Clayton66111032010-06-23 01:19:29 +00001728CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001729 CommandObjectMultiword (interpreter,
1730 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001731 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001732 "thread <subcommand> [<subcommand-options>]")
1733{
Greg Claytona7015092010-09-18 01:14:36 +00001734 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1735 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1736 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00001737 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00001738 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001739 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1740 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1741 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1742 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00001743 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00001744 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001745 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001746 eStepTypeInto,
1747 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00001748
Greg Claytona7015092010-09-18 01:14:36 +00001749 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1750 interpreter,
1751 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00001752 "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 +00001753 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001754 eStepTypeOut,
1755 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001756
Greg Claytona7015092010-09-18 01:14:36 +00001757 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1758 interpreter,
1759 "thread step-over",
1760 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001761 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001762 eStepTypeOver,
1763 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001764
Greg Claytona7015092010-09-18 01:14:36 +00001765 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1766 interpreter,
1767 "thread step-inst",
1768 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001769 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001770 eStepTypeTrace,
1771 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00001772
Greg Claytona7015092010-09-18 01:14:36 +00001773 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1774 interpreter,
1775 "thread step-inst-over",
1776 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001777 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001778 eStepTypeTraceOver,
1779 eStepScopeInstruction)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001780}
1781
1782CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1783{
1784}
1785
1786