blob: 3dce83c48d034d5ce82e726844a55b4f33b961d9 [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"
31#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
33#include "lldb/Target/ThreadPlan.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Target/ThreadPlanStepInstruction.h"
35#include "lldb/Target/ThreadPlanStepOut.h"
36#include "lldb/Target/ThreadPlanStepRange.h"
37#include "lldb/Target/ThreadPlanStepInRange.h"
Greg Clayton1f746072012-08-29 21:13:06 +000038
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
40using namespace lldb;
41using namespace lldb_private;
42
43
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044//-------------------------------------------------------------------------
45// CommandObjectThreadBacktrace
46//-------------------------------------------------------------------------
47
Jim Ingham5a988412012-06-08 21:56:10 +000048class CommandObjectThreadBacktrace : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049{
50public:
51
Jim Inghame2e0b452010-08-26 23:36:03 +000052 class CommandOptions : public Options
53 {
54 public:
55
Greg Claytoneb0103f2011-04-07 22:46:35 +000056 CommandOptions (CommandInterpreter &interpreter) :
57 Options(interpreter)
Jim Inghame2e0b452010-08-26 23:36:03 +000058 {
Greg Claytonf6b8b582011-04-13 00:18:08 +000059 // Keep default values of all options in one place: OptionParsingStarting ()
60 OptionParsingStarting ();
Jim Inghame2e0b452010-08-26 23:36:03 +000061 }
62
63 virtual
64 ~CommandOptions ()
65 {
66 }
67
68 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +000069 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame2e0b452010-08-26 23:36:03 +000070 {
71 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000072 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame2e0b452010-08-26 23:36:03 +000073
74 switch (short_option)
75 {
76 case 'c':
77 {
78 bool success;
79 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
80 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000081 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +000082 if (input_count < -1)
83 m_count = UINT32_MAX;
84 else
85 m_count = input_count;
86 }
87 break;
88 case 's':
89 {
90 bool success;
91 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
92 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000093 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +000094 }
95 break;
96 default:
Greg Clayton86edbf42011-10-26 00:56:27 +000097 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Jim Inghame2e0b452010-08-26 23:36:03 +000098 break;
99
100 }
101 return error;
102 }
103
104 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000105 OptionParsingStarting ()
Jim Inghame2e0b452010-08-26 23:36:03 +0000106 {
Greg Clayton7260f622011-04-18 08:33:37 +0000107 m_count = UINT32_MAX;
Jim Inghame2e0b452010-08-26 23:36:03 +0000108 m_start = 0;
109 }
110
Greg Claytone0d378b2011-03-24 21:19:54 +0000111 const OptionDefinition*
Jim Inghame2e0b452010-08-26 23:36:03 +0000112 GetDefinitions ()
113 {
114 return g_option_table;
115 }
116
117 // Options table: Required for subclasses of Options.
118
Greg Claytone0d378b2011-03-24 21:19:54 +0000119 static OptionDefinition g_option_table[];
Jim Inghame2e0b452010-08-26 23:36:03 +0000120
121 // Instance variables to hold the values for command options.
122 uint32_t m_count;
123 uint32_t m_start;
124 };
125
Greg Claytona7015092010-09-18 01:14:36 +0000126 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000127 CommandObjectParsed (interpreter,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000128 "thread backtrace",
129 "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.",
130 NULL,
131 eFlagRequiresProcess |
132 eFlagRequiresThread |
133 eFlagTryTargetAPILock |
134 eFlagProcessMustBeLaunched |
135 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000136 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137 {
Caroline Tice405fe672010-10-04 22:28:36 +0000138 CommandArgumentEntry arg;
139 CommandArgumentData thread_idx_arg;
140
141 // Define the first (and only) variant of this arg.
142 thread_idx_arg.arg_type = eArgTypeThreadIndex;
143 thread_idx_arg.arg_repetition = eArgRepeatStar;
144
145 // There is only one variant this argument could be; put it into the argument entry.
146 arg.push_back (thread_idx_arg);
147
148 // Push the data for the first argument into the m_arguments vector.
149 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 }
151
152 ~CommandObjectThreadBacktrace()
153 {
154 }
155
Jim Inghame2e0b452010-08-26 23:36:03 +0000156 virtual Options *
157 GetOptions ()
158 {
159 return &m_options;
160 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161
Jim Ingham5a988412012-06-08 21:56:10 +0000162protected:
Greg Clayton66111032010-06-23 01:19:29 +0000163 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000164 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton7260f622011-04-18 08:33:37 +0000165 {
Jim Ingham09b263e2010-08-27 00:58:05 +0000166 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton7260f622011-04-18 08:33:37 +0000167 Stream &strm = result.GetOutputStream();
168
169 // Don't show source context when doing backtraces.
170 const uint32_t num_frames_with_source = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171 if (command.GetArgumentCount() == 0)
172 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000173 Thread *thread = m_exe_ctx.GetThreadPtr();
174 // Thread::GetStatus() returns the number of frames shown.
175 if (thread->GetStatus (strm,
176 m_options.m_start,
177 m_options.m_count,
178 num_frames_with_source))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000180 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 }
182 }
Jim Ingham09b263e2010-08-27 00:58:05 +0000183 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
184 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000185 Process *process = m_exe_ctx.GetProcessPtr();
Sean Callanan5c19eac2013-11-06 19:28:40 +0000186 uint32_t idx = 0;
187 for (ThreadSP thread_sp : process->Threads())
Jim Ingham09b263e2010-08-27 00:58:05 +0000188 {
Sean Callanan5c19eac2013-11-06 19:28:40 +0000189 if (idx != 0)
190 result.AppendMessage("");
191
Johnny Chenf2ddc712011-06-01 23:19:52 +0000192 if (!thread_sp->GetStatus (strm,
193 m_options.m_start,
194 m_options.m_count,
195 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000196 {
Sean Callanan5c19eac2013-11-06 19:28:40 +0000197 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", idx);
Jim Ingham09b263e2010-08-27 00:58:05 +0000198 result.SetStatus (eReturnStatusFailed);
199 return false;
200 }
Jim Ingham5c4df7a2011-07-26 02:39:59 +0000201
Sean Callanan5c19eac2013-11-06 19:28:40 +0000202 ++idx;
Jim Ingham09b263e2010-08-27 00:58:05 +0000203 }
204 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 else
206 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000207 const size_t num_args = command.GetArgumentCount();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000208 Process *process = m_exe_ctx.GetProcessPtr();
Jim Ingham41f2b942012-09-10 20:50:15 +0000209 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Ingham09b263e2010-08-27 00:58:05 +0000210 std::vector<ThreadSP> thread_sps;
211
Greg Claytonc7bece562013-01-25 18:06:21 +0000212 for (size_t i = 0; i < num_args; i++)
Jim Ingham09b263e2010-08-27 00:58:05 +0000213 {
214 bool success;
215
216 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
217 if (!success)
218 {
219 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
220 result.SetStatus (eReturnStatusFailed);
221 return false;
222 }
223
224 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
225
226 if (!thread_sps[i])
227 {
228 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
229 result.SetStatus (eReturnStatusFailed);
230 return false;
231 }
232
233 }
234
235 for (uint32_t i = 0; i < num_args; i++)
236 {
Greg Clayton7260f622011-04-18 08:33:37 +0000237 if (!thread_sps[i]->GetStatus (strm,
238 m_options.m_start,
239 m_options.m_count,
240 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000241 {
242 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
243 result.SetStatus (eReturnStatusFailed);
244 return false;
245 }
246
247 if (i < num_args - 1)
248 result.AppendMessage("");
249 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250 }
251 return result.Succeeded();
252 }
Jim Ingham5a988412012-06-08 21:56:10 +0000253
Jim Inghame2e0b452010-08-26 23:36:03 +0000254 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255};
256
Greg Claytone0d378b2011-03-24 21:19:54 +0000257OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000258CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
259{
Virgile Belloe2607b52013-09-05 16:42:23 +0000260{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
261{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
Caroline Ticedeaab222010-10-01 19:59:14 +0000262{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Inghame2e0b452010-08-26 23:36:03 +0000263};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264
Greg Clayton69b518f2010-07-07 17:07:17 +0000265enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266{
267 eStepScopeSource,
268 eStepScopeInstruction
269};
270
Jim Ingham5a988412012-06-08 21:56:10 +0000271class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272{
273public:
274
275 class CommandOptions : public Options
276 {
277 public:
278
Greg Claytoneb0103f2011-04-07 22:46:35 +0000279 CommandOptions (CommandInterpreter &interpreter) :
280 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000282 // Keep default values of all options in one place: OptionParsingStarting ()
283 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284 }
285
286 virtual
287 ~CommandOptions ()
288 {
289 }
290
291 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000292 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 {
294 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000295 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296
297 switch (short_option)
298 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000299 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 {
301 bool success;
302 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
303 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000304 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000305 }
306 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000307
308 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000311 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312 }
313 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000314
315 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000316 {
317 m_avoid_regexp.clear();
318 m_avoid_regexp.assign(option_arg);
319 }
320 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000321
Jim Inghamc6276822012-12-12 19:58:40 +0000322 case 't':
323 {
324 m_step_in_target.clear();
325 m_step_in_target.assign(option_arg);
326
327 }
328 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000329 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000330 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000331 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332
333 }
334 return error;
335 }
336
337 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000338 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 m_avoid_no_debug = true;
341 m_run_mode = eOnlyDuringStepping;
Jim Inghama56c8002010-07-10 02:27:39 +0000342 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000343 m_step_in_target.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 }
345
Greg Claytone0d378b2011-03-24 21:19:54 +0000346 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347 GetDefinitions ()
348 {
349 return g_option_table;
350 }
351
352 // Options table: Required for subclasses of Options.
353
Greg Claytone0d378b2011-03-24 21:19:54 +0000354 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355
356 // Instance variables to hold the values for command options.
357 bool m_avoid_no_debug;
358 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000359 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000360 std::string m_step_in_target;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 };
362
Greg Claytona7015092010-09-18 01:14:36 +0000363 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
364 const char *name,
365 const char *help,
366 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000367 StepType step_type,
368 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000369 CommandObjectParsed (interpreter, name, help, syntax,
370 eFlagRequiresProcess |
371 eFlagRequiresThread |
372 eFlagTryTargetAPILock |
373 eFlagProcessMustBeLaunched |
374 eFlagProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375 m_step_type (step_type),
376 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000377 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 {
Caroline Tice405fe672010-10-04 22:28:36 +0000379 CommandArgumentEntry arg;
380 CommandArgumentData thread_id_arg;
381
382 // Define the first (and only) variant of this arg.
383 thread_id_arg.arg_type = eArgTypeThreadID;
384 thread_id_arg.arg_repetition = eArgRepeatOptional;
385
386 // There is only one variant this argument could be; put it into the argument entry.
387 arg.push_back (thread_id_arg);
388
389 // Push the data for the first argument into the m_arguments vector.
390 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 }
392
393 virtual
394 ~CommandObjectThreadStepWithTypeAndScope ()
395 {
396 }
397
398 virtual
399 Options *
400 GetOptions ()
401 {
402 return &m_options;
403 }
404
Jim Ingham5a988412012-06-08 21:56:10 +0000405protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000407 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000409 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000410 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411
Greg Claytonf9fc6092013-01-09 19:44:40 +0000412 const uint32_t num_threads = process->GetThreadList().GetSize();
413 Thread *thread = NULL;
414
415 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000417 thread = process->GetThreadList().GetSelectedThread().get();
418 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000420 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000422 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000424 }
425 else
426 {
427 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
428 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
429 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000431 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
432 result.SetStatus (eReturnStatusFailed);
433 return false;
434 }
435 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
436 if (thread == NULL)
437 {
438 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
439 step_thread_idx, num_threads);
440 result.SetStatus (eReturnStatusFailed);
441 return false;
442 }
443 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000444
Greg Claytonf9fc6092013-01-09 19:44:40 +0000445 const bool abort_other_plans = false;
446 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
447
448 // This is a bit unfortunate, but not all the commands in this command object support
449 // only while stepping, so I use the bool for them.
450 bool bool_stop_other_threads;
451 if (m_options.m_run_mode == eAllThreads)
452 bool_stop_other_threads = false;
453 else if (m_options.m_run_mode == eOnlyDuringStepping)
454 {
455 if (m_step_type == eStepTypeOut)
456 bool_stop_other_threads = false;
457 else
458 bool_stop_other_threads = true;
459 }
460 else
461 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000462
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000463 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000464
465 if (m_step_type == eStepTypeInto)
466 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000467 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000468
469 if (frame->HasDebugInformation ())
470 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000471 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000472 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
473 frame->GetSymbolContext(eSymbolContextEverything),
474 m_options.m_step_in_target.c_str(),
475 stop_other_threads,
476 m_options.m_avoid_no_debug);
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000477 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000478 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000479 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000480 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000481 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000482 }
483 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000484 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000485
486 }
487 else if (m_step_type == eStepTypeOver)
488 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000489 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000490
491 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000492 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000493 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
494 frame->GetSymbolContext(eSymbolContextEverything),
495 stop_other_threads);
496 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000497 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000498 abort_other_plans,
499 bool_stop_other_threads);
500
501 }
502 else if (m_step_type == eStepTypeTrace)
503 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000504 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000505 }
506 else if (m_step_type == eStepTypeTraceOver)
507 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000508 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000509 }
510 else if (m_step_type == eStepTypeOut)
511 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000512 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000513 NULL,
514 false,
515 bool_stop_other_threads,
516 eVoteYes,
517 eVoteNoOpinion,
518 thread->GetSelectedFrameIndex());
519 }
520 else
521 {
522 result.AppendError ("step type is not supported");
523 result.SetStatus (eReturnStatusFailed);
524 return false;
525 }
526
527 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
528 // so that they can be interruptible). Then resume the process.
529
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000530 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000531 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000532 new_plan_sp->SetIsMasterPlan (true);
533 new_plan_sp->SetOkayToDiscard (false);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000534
535 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
536 process->Resume ();
537
538
539 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000540 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000541 StateType state = process->WaitForProcessToStop (NULL);
542
543 //EventSP event_sp;
544 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
545 //while (! StateIsStoppedState (state))
546 // {
547 // state = process->WaitForStateChangedEvents (NULL, event_sp);
548 // }
549 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
550 result.SetDidChangeProcessState (true);
551 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
552 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000554 else
555 {
556 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
557 }
558 }
559 else
560 {
561 result.AppendError ("Couldn't find thread plan to implement step type.");
562 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000563 }
564 return result.Succeeded();
565 }
566
567protected:
568 StepType m_step_type;
569 StepScope m_step_scope;
570 CommandOptions m_options;
571};
572
Greg Claytone0d378b2011-03-24 21:19:54 +0000573static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574g_tri_running_mode[] =
575{
Greg Claytoned8a7052010-09-18 03:37:20 +0000576{ eOnlyThisThread, "this-thread", "Run only this thread"},
577{ eAllThreads, "all-threads", "Run all threads"},
578{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579{ 0, NULL, NULL }
580};
581
Greg Claytone0d378b2011-03-24 21:19:54 +0000582static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000583g_duo_running_mode[] =
584{
Greg Claytoned8a7052010-09-18 03:37:20 +0000585{ eOnlyThisThread, "this-thread", "Run only this thread"},
586{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000587{ 0, NULL, NULL }
588};
589
Greg Claytone0d378b2011-03-24 21:19:54 +0000590OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
592{
Virgile Belloe2607b52013-09-05 16:42:23 +0000593{ 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."},
594{ 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."},
595{ 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."},
596{ 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 +0000597{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000598};
599
600
601//-------------------------------------------------------------------------
602// CommandObjectThreadContinue
603//-------------------------------------------------------------------------
604
Jim Ingham5a988412012-06-08 21:56:10 +0000605class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606{
607public:
608
Greg Claytona7015092010-09-18 01:14:36 +0000609 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000610 CommandObjectParsed (interpreter,
611 "thread continue",
612 "Continue execution of one or more threads in an active process.",
613 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000614 eFlagRequiresThread |
615 eFlagTryTargetAPILock |
616 eFlagProcessMustBeLaunched |
617 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 {
Caroline Tice405fe672010-10-04 22:28:36 +0000619 CommandArgumentEntry arg;
620 CommandArgumentData thread_idx_arg;
621
622 // Define the first (and only) variant of this arg.
623 thread_idx_arg.arg_type = eArgTypeThreadIndex;
624 thread_idx_arg.arg_repetition = eArgRepeatPlus;
625
626 // There is only one variant this argument could be; put it into the argument entry.
627 arg.push_back (thread_idx_arg);
628
629 // Push the data for the first argument into the m_arguments vector.
630 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631 }
632
633
634 virtual
635 ~CommandObjectThreadContinue ()
636 {
637 }
638
639 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000640 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 {
Greg Claytona7015092010-09-18 01:14:36 +0000642 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000643
Greg Claytona7015092010-09-18 01:14:36 +0000644 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000646 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647 result.SetStatus (eReturnStatusFailed);
648 return false;
649 }
650
Greg Claytonf9fc6092013-01-09 19:44:40 +0000651 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 if (process == NULL)
653 {
654 result.AppendError ("no process exists. Cannot continue");
655 result.SetStatus (eReturnStatusFailed);
656 return false;
657 }
658
659 StateType state = process->GetState();
660 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
661 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662 const size_t argc = command.GetArgumentCount();
663 if (argc > 0)
664 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000665 // These two lines appear at the beginning of both blocks in
666 // this if..else, but that is because we need to release the
667 // lock before calling process->Resume below.
668 Mutex::Locker locker (process->GetThreadList().GetMutex());
669 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000670 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671 for (uint32_t i=0; i<argc; ++i)
672 {
Jim Inghamce76c622012-05-31 20:48:41 +0000673 bool success;
674 const int base = 0;
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000675 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
676 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000677 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000678 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000679
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000680 if (thread)
681 {
682 resume_threads.push_back(thread);
683 }
684 else
685 {
686 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
687 result.SetStatus (eReturnStatusFailed);
688 return false;
689 }
Jim Inghamce76c622012-05-31 20:48:41 +0000690 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000691 else
Jim Inghamce76c622012-05-31 20:48:41 +0000692 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000693 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000694 result.SetStatus (eReturnStatusFailed);
695 return false;
696 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000698
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000699 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700 {
701 result.AppendError ("no valid thread indexes were specified");
702 result.SetStatus (eReturnStatusFailed);
703 return false;
704 }
705 else
706 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000707 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000708 result.AppendMessageWithFormat ("Resuming thread: ");
709 else
710 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000711
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000712 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000713 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000714 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
715 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000716
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000717 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000719 resume_threads.erase(this_thread_pos);
720 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000721 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
722 else
723 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000724
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725 thread->SetResumeState (eStateRunning);
726 }
727 else
728 {
729 thread->SetResumeState (eStateSuspended);
730 }
731 }
Daniel Malead01b2952012-11-29 21:49:15 +0000732 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 }
734 }
735 else
736 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000737 // These two lines appear at the beginning of both blocks in
738 // this if..else, but that is because we need to release the
739 // lock before calling process->Resume below.
740 Mutex::Locker locker (process->GetThreadList().GetMutex());
741 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000742 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743 if (current_thread == NULL)
744 {
745 result.AppendError ("the process doesn't have a current thread");
746 result.SetStatus (eReturnStatusFailed);
747 return false;
748 }
749 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000750 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000751 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000752 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000753 if (thread == current_thread)
754 {
Daniel Malead01b2952012-11-29 21:49:15 +0000755 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 thread->SetResumeState (eStateRunning);
757 }
758 else
759 {
760 thread->SetResumeState (eStateSuspended);
761 }
762 }
763 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000764
765 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000766 Error error (process->Resume());
767 if (error.Success())
768 {
Daniel Malead01b2952012-11-29 21:49:15 +0000769 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770 if (synchronous_execution)
771 {
Greg Claytonb1320972010-07-14 00:18:15 +0000772 state = process->WaitForProcessToStop (NULL);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000773
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +0000775 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000776 result.SetStatus (eReturnStatusSuccessFinishNoResult);
777 }
778 else
779 {
780 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
781 }
782 }
783 else
784 {
785 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
786 result.SetStatus (eReturnStatusFailed);
787 }
788 }
789 else
790 {
791 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
792 StateAsCString(state));
793 result.SetStatus (eReturnStatusFailed);
794 }
795
796 return result.Succeeded();
797 }
798
799};
800
801//-------------------------------------------------------------------------
802// CommandObjectThreadUntil
803//-------------------------------------------------------------------------
804
Jim Ingham5a988412012-06-08 21:56:10 +0000805class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000806{
807public:
808
809 class CommandOptions : public Options
810 {
811 public:
812 uint32_t m_thread_idx;
813 uint32_t m_frame_idx;
814
Greg Claytoneb0103f2011-04-07 22:46:35 +0000815 CommandOptions (CommandInterpreter &interpreter) :
816 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817 m_thread_idx(LLDB_INVALID_THREAD_ID),
818 m_frame_idx(LLDB_INVALID_FRAME_ID)
819 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000820 // Keep default values of all options in one place: OptionParsingStarting ()
821 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822 }
823
824 virtual
825 ~CommandOptions ()
826 {
827 }
828
829 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000830 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000831 {
832 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000833 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834
835 switch (short_option)
836 {
837 case 't':
838 {
Greg Claytonb1320972010-07-14 00:18:15 +0000839 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840 if (m_thread_idx == LLDB_INVALID_INDEX32)
841 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000842 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843 }
844 }
845 break;
846 case 'f':
847 {
848 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
849 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
850 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000851 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852 }
853 }
854 break;
855 case 'm':
856 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000858 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000859
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000860 if (error.Success())
861 {
862 if (run_mode == eAllThreads)
863 m_stop_others = false;
864 else
865 m_stop_others = true;
866 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867 }
868 break;
869 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000870 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871 break;
872
873 }
874 return error;
875 }
876
877 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000878 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000879 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880 m_thread_idx = LLDB_INVALID_THREAD_ID;
881 m_frame_idx = 0;
882 m_stop_others = false;
883 }
884
Greg Claytone0d378b2011-03-24 21:19:54 +0000885 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886 GetDefinitions ()
887 {
888 return g_option_table;
889 }
890
891 uint32_t m_step_thread_idx;
892 bool m_stop_others;
893
894 // Options table: Required for subclasses of Options.
895
Greg Claytone0d378b2011-03-24 21:19:54 +0000896 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000897
898 // Instance variables to hold the values for command options.
899 };
900
Greg Claytona7015092010-09-18 01:14:36 +0000901 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000902 CommandObjectParsed (interpreter,
903 "thread until",
904 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
905 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000906 eFlagRequiresThread |
907 eFlagTryTargetAPILock |
908 eFlagProcessMustBeLaunched |
909 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000910 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 {
Caroline Tice405fe672010-10-04 22:28:36 +0000912 CommandArgumentEntry arg;
913 CommandArgumentData line_num_arg;
914
915 // Define the first (and only) variant of this arg.
916 line_num_arg.arg_type = eArgTypeLineNum;
917 line_num_arg.arg_repetition = eArgRepeatPlain;
918
919 // There is only one variant this argument could be; put it into the argument entry.
920 arg.push_back (line_num_arg);
921
922 // Push the data for the first argument into the m_arguments vector.
923 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924 }
925
926
927 virtual
928 ~CommandObjectThreadUntil ()
929 {
930 }
931
932 virtual
933 Options *
934 GetOptions ()
935 {
936 return &m_options;
937 }
938
Jim Ingham5a988412012-06-08 21:56:10 +0000939protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000940 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000941 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000942 {
Greg Claytona7015092010-09-18 01:14:36 +0000943 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000944
Greg Claytona7015092010-09-18 01:14:36 +0000945 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +0000946 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000947 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000948 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949 result.SetStatus (eReturnStatusFailed);
950 return false;
951 }
952
Greg Claytonf9fc6092013-01-09 19:44:40 +0000953 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954 if (process == NULL)
955 {
956 result.AppendError ("need a valid process to step");
957 result.SetStatus (eReturnStatusFailed);
958
959 }
960 else
961 {
962 Thread *thread = NULL;
963 uint32_t line_number;
964
965 if (command.GetArgumentCount() != 1)
966 {
967 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
968 result.SetStatus (eReturnStatusFailed);
969 return false;
970 }
971
972 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
973 if (line_number == UINT32_MAX)
974 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000975 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000976 result.SetStatus (eReturnStatusFailed);
977 return false;
978 }
979
980 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
981 {
Jim Ingham2976d002010-08-26 21:32:51 +0000982 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000983 }
984 else
985 {
Greg Clayton76927ee2012-05-31 00:29:20 +0000986 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987 }
988
989 if (thread == NULL)
990 {
991 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +0000992 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
993 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +0000994 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995 result.SetStatus (eReturnStatusFailed);
996 return false;
997 }
998
Jim Ingham7ba6e992012-05-11 23:47:32 +0000999 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001000
Jason Molendab57e4a12013-11-04 09:33:30 +00001001 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002 if (frame == NULL)
1003 {
1004
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001005 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1006 m_options.m_frame_idx,
1007 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001008 result.SetStatus (eReturnStatusFailed);
1009 return false;
1010 }
1011
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001012 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013
1014 if (frame->HasDebugInformation ())
1015 {
1016 // Finally we got here... Translate the given line number to a bunch of addresses:
1017 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1018 LineTable *line_table = NULL;
1019 if (sc.comp_unit)
1020 line_table = sc.comp_unit->GetLineTable();
1021
1022 if (line_table == NULL)
1023 {
1024 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1025 m_options.m_frame_idx, m_options.m_thread_idx);
1026 result.SetStatus (eReturnStatusFailed);
1027 return false;
1028 }
1029
1030 LineEntry function_start;
1031 uint32_t index_ptr = 0, end_ptr;
1032 std::vector<addr_t> address_list;
1033
1034 // Find the beginning & end index of the
1035 AddressRange fun_addr_range = sc.function->GetAddressRange();
1036 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1037 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1038
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001039 Address fun_end_addr(fun_start_addr.GetSection(),
1040 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001041 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1042
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001043 bool all_in_function = true;
1044
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001045 while (index_ptr <= end_ptr)
1046 {
1047 LineEntry line_entry;
Jim Ingham87df91b2011-09-23 00:54:11 +00001048 const bool exact = false;
1049 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050 if (index_ptr == UINT32_MAX)
1051 break;
1052
Greg Claytonf5e56de2010-09-14 23:36:40 +00001053 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 if (address != LLDB_INVALID_ADDRESS)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001055 {
1056 if (fun_addr_range.ContainsLoadAddress (address, target))
1057 address_list.push_back (address);
1058 else
1059 all_in_function = false;
1060 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061 index_ptr++;
1062 }
1063
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001064 if (address_list.size() == 0)
1065 {
1066 if (all_in_function)
1067 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1068 else
1069 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1070
1071 result.SetStatus (eReturnStatusFailed);
1072 return false;
1073 }
1074
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001075 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001076 &address_list.front(),
1077 address_list.size(),
1078 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001079 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001080 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1081 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1082 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001083 new_plan_sp->SetIsMasterPlan (true);
1084 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001085 }
1086 else
1087 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001088 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1089 m_options.m_frame_idx,
1090 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001091 result.SetStatus (eReturnStatusFailed);
1092 return false;
1093
1094 }
1095
Jim Ingham2976d002010-08-26 21:32:51 +00001096 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097 Error error (process->Resume ());
1098 if (error.Success())
1099 {
Daniel Malead01b2952012-11-29 21:49:15 +00001100 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 if (synchronous_execution)
1102 {
1103 StateType state = process->WaitForProcessToStop (NULL);
1104
1105 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +00001106 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001107 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1108 }
1109 else
1110 {
1111 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1112 }
1113 }
1114 else
1115 {
1116 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1117 result.SetStatus (eReturnStatusFailed);
1118 }
1119
1120 }
1121 return result.Succeeded();
1122 }
Jim Ingham5a988412012-06-08 21:56:10 +00001123
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001124 CommandOptions m_options;
1125
1126};
1127
Greg Claytone0d378b2011-03-24 21:19:54 +00001128OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1130{
Virgile Belloe2607b52013-09-05 16:42:23 +00001131{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1132{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1133{ 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 +00001134{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135};
1136
1137
1138//-------------------------------------------------------------------------
1139// CommandObjectThreadSelect
1140//-------------------------------------------------------------------------
1141
Jim Ingham5a988412012-06-08 21:56:10 +00001142class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143{
1144public:
1145
Greg Claytona7015092010-09-18 01:14:36 +00001146 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001147 CommandObjectParsed (interpreter,
1148 "thread select",
1149 "Select a thread as the currently active thread.",
1150 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001151 eFlagRequiresProcess |
1152 eFlagTryTargetAPILock |
1153 eFlagProcessMustBeLaunched |
1154 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001155 {
Caroline Tice405fe672010-10-04 22:28:36 +00001156 CommandArgumentEntry arg;
1157 CommandArgumentData thread_idx_arg;
1158
1159 // Define the first (and only) variant of this arg.
1160 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1161 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1162
1163 // There is only one variant this argument could be; put it into the argument entry.
1164 arg.push_back (thread_idx_arg);
1165
1166 // Push the data for the first argument into the m_arguments vector.
1167 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168 }
1169
1170
1171 virtual
1172 ~CommandObjectThreadSelect ()
1173 {
1174 }
1175
Jim Ingham5a988412012-06-08 21:56:10 +00001176protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001178 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001180 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181 if (process == NULL)
1182 {
1183 result.AppendError ("no process");
1184 result.SetStatus (eReturnStatusFailed);
1185 return false;
1186 }
1187 else if (command.GetArgumentCount() != 1)
1188 {
Jason Molendafd54b362011-09-20 21:44:10 +00001189 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 +00001190 result.SetStatus (eReturnStatusFailed);
1191 return false;
1192 }
1193
1194 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1195
1196 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1197 if (new_thread == NULL)
1198 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001199 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200 result.SetStatus (eReturnStatusFailed);
1201 return false;
1202 }
1203
Jim Inghamc3faa192012-12-11 02:31:48 +00001204 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001205 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001206
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001207 return result.Succeeded();
1208 }
1209
1210};
1211
1212
1213//-------------------------------------------------------------------------
1214// CommandObjectThreadList
1215//-------------------------------------------------------------------------
1216
Jim Ingham5a988412012-06-08 21:56:10 +00001217class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001218{
Greg Clayton66111032010-06-23 01:19:29 +00001219public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001220
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001221
Greg Claytona7015092010-09-18 01:14:36 +00001222 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001223 CommandObjectParsed (interpreter,
1224 "thread list",
1225 "Show a summary of all current threads in a process.",
1226 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001227 eFlagRequiresProcess |
1228 eFlagTryTargetAPILock |
1229 eFlagProcessMustBeLaunched |
1230 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231 {
Greg Clayton66111032010-06-23 01:19:29 +00001232 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001233
Greg Clayton66111032010-06-23 01:19:29 +00001234 ~CommandObjectThreadList()
1235 {
1236 }
1237
Jim Ingham5a988412012-06-08 21:56:10 +00001238protected:
Greg Clayton66111032010-06-23 01:19:29 +00001239 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001240 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001241 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001242 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001243 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001244 Process *process = m_exe_ctx.GetProcessPtr();
1245 const bool only_threads_with_stop_reason = false;
1246 const uint32_t start_frame = 0;
1247 const uint32_t num_frames = 0;
1248 const uint32_t num_frames_with_source = 0;
1249 process->GetStatus(strm);
1250 process->GetThreadStatus (strm,
1251 only_threads_with_stop_reason,
1252 start_frame,
1253 num_frames,
1254 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001255 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001256 }
Greg Clayton66111032010-06-23 01:19:29 +00001257};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001258
Jim Ingham93208b82013-01-31 21:46:01 +00001259//-------------------------------------------------------------------------
1260// CommandObjectThreadReturn
1261//-------------------------------------------------------------------------
1262
Jim Inghamcb640dd2012-09-14 02:14:15 +00001263class CommandObjectThreadReturn : public CommandObjectRaw
1264{
1265public:
Jim Ingham93208b82013-01-31 21:46:01 +00001266 class CommandOptions : public Options
1267 {
1268 public:
1269
1270 CommandOptions (CommandInterpreter &interpreter) :
1271 Options (interpreter),
1272 m_from_expression (false)
1273 {
1274 // Keep default values of all options in one place: OptionParsingStarting ()
1275 OptionParsingStarting ();
1276 }
1277
1278 virtual
1279 ~CommandOptions ()
1280 {
1281 }
1282
1283 virtual Error
1284 SetOptionValue (uint32_t option_idx, const char *option_arg)
1285 {
1286 Error error;
1287 const int short_option = m_getopt_table[option_idx].val;
1288
1289 switch (short_option)
1290 {
1291 case 'x':
1292 {
1293 bool success;
1294 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1295 if (success)
1296 m_from_expression = tmp_value;
1297 else
1298 {
1299 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1300 }
1301 }
1302 break;
1303 default:
1304 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1305 break;
1306
1307 }
1308 return error;
1309 }
1310
1311 void
1312 OptionParsingStarting ()
1313 {
1314 m_from_expression = false;
1315 }
1316
1317 const OptionDefinition*
1318 GetDefinitions ()
1319 {
1320 return g_option_table;
1321 }
1322
1323 bool m_from_expression;
1324
1325 // Options table: Required for subclasses of Options.
1326
1327 static OptionDefinition g_option_table[];
1328
1329 // Instance variables to hold the values for command options.
1330 };
1331
1332 virtual
1333 Options *
1334 GetOptions ()
1335 {
1336 return &m_options;
1337 }
1338
Jim Inghamcb640dd2012-09-14 02:14:15 +00001339 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1340 CommandObjectRaw (interpreter,
1341 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001342 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1343 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001344 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001345 eFlagRequiresFrame |
1346 eFlagTryTargetAPILock |
1347 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001348 eFlagProcessMustBePaused ),
1349 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001350 {
1351 CommandArgumentEntry arg;
1352 CommandArgumentData expression_arg;
1353
1354 // Define the first (and only) variant of this arg.
1355 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001356 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001357
1358 // There is only one variant this argument could be; put it into the argument entry.
1359 arg.push_back (expression_arg);
1360
1361 // Push the data for the first argument into the m_arguments vector.
1362 m_arguments.push_back (arg);
1363
1364
1365 }
1366
1367 ~CommandObjectThreadReturn()
1368 {
1369 }
1370
1371protected:
1372
1373 bool DoExecute
1374 (
1375 const char *command,
1376 CommandReturnObject &result
1377 )
1378 {
Jim Ingham93208b82013-01-31 21:46:01 +00001379 // I am going to handle this by hand, because I don't want you to have to say:
1380 // "thread return -- -5".
1381 if (command[0] == '-' && command[1] == 'x')
1382 {
1383 if (command && command[2] != '\0')
1384 result.AppendWarning("Return values ignored when returning from user called expressions");
1385
1386 Thread *thread = m_exe_ctx.GetThreadPtr();
1387 Error error;
1388 error = thread->UnwindInnermostExpression();
1389 if (!error.Success())
1390 {
1391 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1392 result.SetStatus (eReturnStatusFailed);
1393 }
1394 else
1395 {
1396 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1397 if (success)
1398 {
1399 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1400 result.SetStatus (eReturnStatusSuccessFinishResult);
1401 }
1402 else
1403 {
1404 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1405 result.SetStatus (eReturnStatusFailed);
1406 }
1407 }
1408 return result.Succeeded();
1409 }
1410
Jim Inghamcb640dd2012-09-14 02:14:15 +00001411 ValueObjectSP return_valobj_sp;
1412
Jason Molendab57e4a12013-11-04 09:33:30 +00001413 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001414 uint32_t frame_idx = frame_sp->GetFrameIndex();
1415
1416 if (frame_sp->IsInlined())
1417 {
1418 result.AppendError("Don't know how to return from inlined frames.");
1419 result.SetStatus (eReturnStatusFailed);
1420 return false;
1421 }
1422
1423 if (command && command[0] != '\0')
1424 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001425 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001426 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001427
1428 options.SetUnwindOnError(true);
1429 options.SetUseDynamic(eNoDynamicValues);
1430
1431 ExecutionResults exe_results = eExecutionSetupError;
1432 exe_results = target->EvaluateExpression (command,
1433 frame_sp.get(),
1434 return_valobj_sp,
1435 options);
1436 if (exe_results != eExecutionCompleted)
1437 {
1438 if (return_valobj_sp)
1439 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1440 else
1441 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1442 result.SetStatus (eReturnStatusFailed);
1443 return false;
1444
1445 }
1446 }
1447
1448 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001449 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001450 const bool broadcast = true;
1451 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001452 if (!error.Success())
1453 {
1454 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1455 result.SetStatus (eReturnStatusFailed);
1456 return false;
1457 }
1458
Jim Inghamcb640dd2012-09-14 02:14:15 +00001459 result.SetStatus (eReturnStatusSuccessFinishResult);
1460 return true;
1461 }
Jim Ingham93208b82013-01-31 21:46:01 +00001462
1463 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001464
1465};
Jim Ingham93208b82013-01-31 21:46:01 +00001466OptionDefinition
1467CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1468{
Virgile Belloe2607b52013-09-05 16:42:23 +00001469{ 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 +00001470{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1471};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001472
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001473//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001474// CommandObjectThreadJump
1475//-------------------------------------------------------------------------
1476
1477class CommandObjectThreadJump : public CommandObjectParsed
1478{
1479public:
1480 class CommandOptions : public Options
1481 {
1482 public:
1483
1484 CommandOptions (CommandInterpreter &interpreter) :
1485 Options (interpreter)
1486 {
1487 OptionParsingStarting ();
1488 }
1489
1490 void
1491 OptionParsingStarting ()
1492 {
1493 m_filenames.Clear();
1494 m_line_num = 0;
1495 m_line_offset = 0;
1496 m_load_addr = LLDB_INVALID_ADDRESS;
1497 m_force = false;
1498 }
1499
1500 virtual
1501 ~CommandOptions ()
1502 {
1503 }
1504
1505 virtual Error
1506 SetOptionValue (uint32_t option_idx, const char *option_arg)
1507 {
1508 bool success;
1509 const int short_option = m_getopt_table[option_idx].val;
1510 Error error;
1511
1512 switch (short_option)
1513 {
1514 case 'f':
1515 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1516 if (m_filenames.GetSize() > 1)
1517 return Error("only one source file expected.");
1518 break;
1519 case 'l':
1520 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1521 if (!success || m_line_num == 0)
1522 return Error("invalid line number: '%s'.", option_arg);
1523 break;
1524 case 'b':
1525 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1526 if (!success)
1527 return Error("invalid line offset: '%s'.", option_arg);
1528 break;
1529 case 'a':
1530 {
1531 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1532 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1533 }
1534 break;
1535 case 'r':
1536 m_force = true;
1537 break;
1538
1539 default:
1540 return Error("invalid short option character '%c'", short_option);
1541
1542 }
1543 return error;
1544 }
1545
1546 const OptionDefinition*
1547 GetDefinitions ()
1548 {
1549 return g_option_table;
1550 }
1551
1552 FileSpecList m_filenames;
1553 uint32_t m_line_num;
1554 int32_t m_line_offset;
1555 lldb::addr_t m_load_addr;
1556 bool m_force;
1557
1558 static OptionDefinition g_option_table[];
1559 };
1560
1561 virtual
1562 Options *
1563 GetOptions ()
1564 {
1565 return &m_options;
1566 }
1567
1568 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1569 CommandObjectParsed (interpreter,
1570 "thread jump",
1571 "Sets the program counter to a new address.",
1572 "thread jump",
1573 eFlagRequiresFrame |
1574 eFlagTryTargetAPILock |
1575 eFlagProcessMustBeLaunched |
1576 eFlagProcessMustBePaused ),
1577 m_options (interpreter)
1578 {
1579 }
1580
1581 ~CommandObjectThreadJump()
1582 {
1583 }
1584
1585protected:
1586
1587 bool DoExecute (Args& args, CommandReturnObject &result)
1588 {
1589 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
Jason Molendab57e4a12013-11-04 09:33:30 +00001590 StackFrame *frame = m_exe_ctx.GetFramePtr();
Richard Mittonf86248d2013-09-12 02:20:34 +00001591 Thread *thread = m_exe_ctx.GetThreadPtr();
1592 Target *target = m_exe_ctx.GetTargetPtr();
1593 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1594
1595 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1596 {
1597 // Use this address directly.
1598 Address dest = Address(m_options.m_load_addr);
1599
1600 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1601 if (callAddr == LLDB_INVALID_ADDRESS)
1602 {
1603 result.AppendErrorWithFormat ("Invalid destination address.");
1604 result.SetStatus (eReturnStatusFailed);
1605 return false;
1606 }
1607
1608 if (!reg_ctx->SetPC (callAddr))
1609 {
1610 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1611 result.SetStatus (eReturnStatusFailed);
1612 return false;
1613 }
1614 }
1615 else
1616 {
1617 // Pick either the absolute line, or work out a relative one.
1618 int32_t line = (int32_t)m_options.m_line_num;
1619 if (line == 0)
1620 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1621
1622 // Try the current file, but override if asked.
1623 FileSpec file = sym_ctx.line_entry.file;
1624 if (m_options.m_filenames.GetSize() == 1)
1625 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1626
1627 if (!file)
1628 {
1629 result.AppendErrorWithFormat ("No source file available for the current location.");
1630 result.SetStatus (eReturnStatusFailed);
1631 return false;
1632 }
1633
1634 std::string warnings;
1635 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1636
1637 if (err.Fail())
1638 {
1639 result.SetError (err);
1640 return false;
1641 }
1642
1643 if (!warnings.empty())
1644 result.AppendWarning (warnings.c_str());
1645 }
1646
1647 result.SetStatus (eReturnStatusSuccessFinishResult);
1648 return true;
1649 }
1650
1651 CommandOptions m_options;
1652};
1653OptionDefinition
1654CommandObjectThreadJump::CommandOptions::g_option_table[] =
1655{
1656 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1657 "Specifies the source file to jump to."},
1658
1659 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
1660 "Specifies the line number to jump to."},
1661
1662 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset,
1663 "Jumps by a relative line offset from the current line."},
1664
1665 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression,
1666 "Jumps to a specific address."},
1667
1668 { LLDB_OPT_SET_1|
1669 LLDB_OPT_SET_2|
1670 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
1671
1672 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1673};
1674
1675//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001676// CommandObjectMultiwordThread
1677//-------------------------------------------------------------------------
1678
Greg Clayton66111032010-06-23 01:19:29 +00001679CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001680 CommandObjectMultiword (interpreter,
1681 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001682 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001683 "thread <subcommand> [<subcommand-options>]")
1684{
Greg Claytona7015092010-09-18 01:14:36 +00001685 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1686 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1687 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00001688 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00001689 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001690 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1691 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1692 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1693 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00001694 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00001695 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001696 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001697 eStepTypeInto,
1698 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00001699
Greg Claytona7015092010-09-18 01:14:36 +00001700 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1701 interpreter,
1702 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00001703 "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 +00001704 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001705 eStepTypeOut,
1706 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001707
Greg Claytona7015092010-09-18 01:14:36 +00001708 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1709 interpreter,
1710 "thread step-over",
1711 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001712 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001713 eStepTypeOver,
1714 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001715
Greg Claytona7015092010-09-18 01:14:36 +00001716 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1717 interpreter,
1718 "thread step-inst",
1719 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001720 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001721 eStepTypeTrace,
1722 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00001723
Greg Claytona7015092010-09-18 01:14:36 +00001724 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1725 interpreter,
1726 "thread step-inst-over",
1727 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001728 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001729 eStepTypeTraceOver,
1730 eStepScopeInstruction)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001731}
1732
1733CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1734{
1735}
1736
1737