blob: f46a2219a50986c3afd41aacfb8079e7ffe2bf67 [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();
Jim Ingham41f2b942012-09-10 20:50:15 +0000186 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Ingham09b263e2010-08-27 00:58:05 +0000187 uint32_t num_threads = process->GetThreadList().GetSize();
188 for (uint32_t i = 0; i < num_threads; i++)
189 {
190 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
Johnny Chenf2ddc712011-06-01 23:19:52 +0000191 if (!thread_sp->GetStatus (strm,
192 m_options.m_start,
193 m_options.m_count,
194 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000195 {
Greg Clayton1346f7e2010-09-03 22:45:01 +0000196 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
Jim Ingham09b263e2010-08-27 00:58:05 +0000197 result.SetStatus (eReturnStatusFailed);
198 return false;
199 }
Jim Ingham5c4df7a2011-07-26 02:39:59 +0000200
201 if (i < num_threads - 1)
202 result.AppendMessage("");
203
Jim Ingham09b263e2010-08-27 00:58:05 +0000204 }
205 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206 else
207 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000208 const size_t num_args = command.GetArgumentCount();
Greg Claytonf9fc6092013-01-09 19:44:40 +0000209 Process *process = m_exe_ctx.GetProcessPtr();
Jim Ingham41f2b942012-09-10 20:50:15 +0000210 Mutex::Locker locker (process->GetThreadList().GetMutex());
Jim Ingham09b263e2010-08-27 00:58:05 +0000211 std::vector<ThreadSP> thread_sps;
212
Greg Claytonc7bece562013-01-25 18:06:21 +0000213 for (size_t i = 0; i < num_args; i++)
Jim Ingham09b263e2010-08-27 00:58:05 +0000214 {
215 bool success;
216
217 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
218 if (!success)
219 {
220 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
221 result.SetStatus (eReturnStatusFailed);
222 return false;
223 }
224
225 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
226
227 if (!thread_sps[i])
228 {
229 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
230 result.SetStatus (eReturnStatusFailed);
231 return false;
232 }
233
234 }
235
236 for (uint32_t i = 0; i < num_args; i++)
237 {
Greg Clayton7260f622011-04-18 08:33:37 +0000238 if (!thread_sps[i]->GetStatus (strm,
239 m_options.m_start,
240 m_options.m_count,
241 num_frames_with_source))
Jim Ingham09b263e2010-08-27 00:58:05 +0000242 {
243 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
244 result.SetStatus (eReturnStatusFailed);
245 return false;
246 }
247
248 if (i < num_args - 1)
249 result.AppendMessage("");
250 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251 }
252 return result.Succeeded();
253 }
Jim Ingham5a988412012-06-08 21:56:10 +0000254
Jim Inghame2e0b452010-08-26 23:36:03 +0000255 CommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256};
257
Greg Claytone0d378b2011-03-24 21:19:54 +0000258OptionDefinition
Jim Inghame2e0b452010-08-26 23:36:03 +0000259CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
260{
Virgile Belloe2607b52013-09-05 16:42:23 +0000261{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
262{ 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 +0000263{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Inghame2e0b452010-08-26 23:36:03 +0000264};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265
Greg Clayton69b518f2010-07-07 17:07:17 +0000266enum StepScope
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267{
268 eStepScopeSource,
269 eStepScopeInstruction
270};
271
Jim Ingham5a988412012-06-08 21:56:10 +0000272class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273{
274public:
275
276 class CommandOptions : public Options
277 {
278 public:
279
Greg Claytoneb0103f2011-04-07 22:46:35 +0000280 CommandOptions (CommandInterpreter &interpreter) :
281 Options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000283 // Keep default values of all options in one place: OptionParsingStarting ()
284 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285 }
286
287 virtual
288 ~CommandOptions ()
289 {
290 }
291
292 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000293 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 {
295 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000296 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297
298 switch (short_option)
299 {
Greg Clayton8087ca22010-10-08 04:20:14 +0000300 case 'a':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 {
302 bool success;
303 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
304 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000305 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306 }
307 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000308
309 case 'm':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000312 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 }
314 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000315
316 case 'r':
Jim Inghama56c8002010-07-10 02:27:39 +0000317 {
318 m_avoid_regexp.clear();
319 m_avoid_regexp.assign(option_arg);
320 }
321 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000322
Jim Inghamc6276822012-12-12 19:58:40 +0000323 case 't':
324 {
325 m_step_in_target.clear();
326 m_step_in_target.assign(option_arg);
327
328 }
329 break;
Greg Clayton8087ca22010-10-08 04:20:14 +0000330 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000331 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Clayton8087ca22010-10-08 04:20:14 +0000332 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333
334 }
335 return error;
336 }
337
338 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000339 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341 m_avoid_no_debug = true;
342 m_run_mode = eOnlyDuringStepping;
Jim Inghama56c8002010-07-10 02:27:39 +0000343 m_avoid_regexp.clear();
Jim Inghamc6276822012-12-12 19:58:40 +0000344 m_step_in_target.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 }
346
Greg Claytone0d378b2011-03-24 21:19:54 +0000347 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 GetDefinitions ()
349 {
350 return g_option_table;
351 }
352
353 // Options table: Required for subclasses of Options.
354
Greg Claytone0d378b2011-03-24 21:19:54 +0000355 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356
357 // Instance variables to hold the values for command options.
358 bool m_avoid_no_debug;
359 RunMode m_run_mode;
Jim Inghama56c8002010-07-10 02:27:39 +0000360 std::string m_avoid_regexp;
Jim Inghamc6276822012-12-12 19:58:40 +0000361 std::string m_step_in_target;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362 };
363
Greg Claytona7015092010-09-18 01:14:36 +0000364 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
365 const char *name,
366 const char *help,
367 const char *syntax,
Greg Claytona7015092010-09-18 01:14:36 +0000368 StepType step_type,
369 StepScope step_scope) :
Greg Claytonf9fc6092013-01-09 19:44:40 +0000370 CommandObjectParsed (interpreter, name, help, syntax,
371 eFlagRequiresProcess |
372 eFlagRequiresThread |
373 eFlagTryTargetAPILock |
374 eFlagProcessMustBeLaunched |
375 eFlagProcessMustBePaused ),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 m_step_type (step_type),
377 m_step_scope (step_scope),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000378 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379 {
Caroline Tice405fe672010-10-04 22:28:36 +0000380 CommandArgumentEntry arg;
381 CommandArgumentData thread_id_arg;
382
383 // Define the first (and only) variant of this arg.
384 thread_id_arg.arg_type = eArgTypeThreadID;
385 thread_id_arg.arg_repetition = eArgRepeatOptional;
386
387 // There is only one variant this argument could be; put it into the argument entry.
388 arg.push_back (thread_id_arg);
389
390 // Push the data for the first argument into the m_arguments vector.
391 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 }
393
394 virtual
395 ~CommandObjectThreadStepWithTypeAndScope ()
396 {
397 }
398
399 virtual
400 Options *
401 GetOptions ()
402 {
403 return &m_options;
404 }
405
Jim Ingham5a988412012-06-08 21:56:10 +0000406protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000408 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000410 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000411 bool synchronous_execution = m_interpreter.GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412
Greg Claytonf9fc6092013-01-09 19:44:40 +0000413 const uint32_t num_threads = process->GetThreadList().GetSize();
414 Thread *thread = NULL;
415
416 if (command.GetArgumentCount() == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000418 thread = process->GetThreadList().GetSelectedThread().get();
419 if (thread == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000421 result.AppendError ("no selected thread in process");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422 result.SetStatus (eReturnStatusFailed);
Jim Ingham64e7ead2012-05-03 21:19:36 +0000423 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000425 }
426 else
427 {
428 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
429 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
430 if (step_thread_idx == LLDB_INVALID_INDEX32)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000432 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
433 result.SetStatus (eReturnStatusFailed);
434 return false;
435 }
436 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
437 if (thread == NULL)
438 {
439 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
440 step_thread_idx, num_threads);
441 result.SetStatus (eReturnStatusFailed);
442 return false;
443 }
444 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000445
Greg Claytonf9fc6092013-01-09 19:44:40 +0000446 const bool abort_other_plans = false;
447 const lldb::RunMode stop_other_threads = m_options.m_run_mode;
448
449 // This is a bit unfortunate, but not all the commands in this command object support
450 // only while stepping, so I use the bool for them.
451 bool bool_stop_other_threads;
452 if (m_options.m_run_mode == eAllThreads)
453 bool_stop_other_threads = false;
454 else if (m_options.m_run_mode == eOnlyDuringStepping)
455 {
456 if (m_step_type == eStepTypeOut)
457 bool_stop_other_threads = false;
458 else
459 bool_stop_other_threads = true;
460 }
461 else
462 bool_stop_other_threads = true;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000463
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000464 ThreadPlanSP new_plan_sp;
Greg Claytonf9fc6092013-01-09 19:44:40 +0000465
466 if (m_step_type == eStepTypeInto)
467 {
468 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
469
470 if (frame->HasDebugInformation ())
471 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000472 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000473 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
474 frame->GetSymbolContext(eSymbolContextEverything),
475 m_options.m_step_in_target.c_str(),
476 stop_other_threads,
477 m_options.m_avoid_no_debug);
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000478 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
Jim Ingham64e7ead2012-05-03 21:19:36 +0000479 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000480 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000481 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
Jim Ingham29412d12012-05-16 00:37:40 +0000482 }
Jim Ingham64e7ead2012-05-03 21:19:36 +0000483 }
484 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000485 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000486
487 }
488 else if (m_step_type == eStepTypeOver)
489 {
490 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
491
492 if (frame->HasDebugInformation())
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000493 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000494 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
495 frame->GetSymbolContext(eSymbolContextEverything),
496 stop_other_threads);
497 else
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000498 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000499 abort_other_plans,
500 bool_stop_other_threads);
501
502 }
503 else if (m_step_type == eStepTypeTrace)
504 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000505 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000506 }
507 else if (m_step_type == eStepTypeTraceOver)
508 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000509 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000510 }
511 else if (m_step_type == eStepTypeOut)
512 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000513 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000514 NULL,
515 false,
516 bool_stop_other_threads,
517 eVoteYes,
518 eVoteNoOpinion,
519 thread->GetSelectedFrameIndex());
520 }
521 else
522 {
523 result.AppendError ("step type is not supported");
524 result.SetStatus (eReturnStatusFailed);
525 return false;
526 }
527
528 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
529 // so that they can be interruptible). Then resume the process.
530
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000531 if (new_plan_sp)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000532 {
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000533 new_plan_sp->SetIsMasterPlan (true);
534 new_plan_sp->SetOkayToDiscard (false);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000535
536 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
537 process->Resume ();
538
539
540 if (synchronous_execution)
Jim Ingham64e7ead2012-05-03 21:19:36 +0000541 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000542 StateType state = process->WaitForProcessToStop (NULL);
543
544 //EventSP event_sp;
545 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
546 //while (! StateIsStoppedState (state))
547 // {
548 // state = process->WaitForStateChangedEvents (NULL, event_sp);
549 // }
550 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
551 result.SetDidChangeProcessState (true);
552 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
553 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000554 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000555 else
556 {
557 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
558 }
559 }
560 else
561 {
562 result.AppendError ("Couldn't find thread plan to implement step type.");
563 result.SetStatus (eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 }
565 return result.Succeeded();
566 }
567
568protected:
569 StepType m_step_type;
570 StepScope m_step_scope;
571 CommandOptions m_options;
572};
573
Greg Claytone0d378b2011-03-24 21:19:54 +0000574static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575g_tri_running_mode[] =
576{
Greg Claytoned8a7052010-09-18 03:37:20 +0000577{ eOnlyThisThread, "this-thread", "Run only this thread"},
578{ eAllThreads, "all-threads", "Run all threads"},
579{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580{ 0, NULL, NULL }
581};
582
Greg Claytone0d378b2011-03-24 21:19:54 +0000583static OptionEnumValueElement
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584g_duo_running_mode[] =
585{
Greg Claytoned8a7052010-09-18 03:37:20 +0000586{ eOnlyThisThread, "this-thread", "Run only this thread"},
587{ eAllThreads, "all-threads", "Run all threads"},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588{ 0, NULL, NULL }
589};
590
Greg Claytone0d378b2011-03-24 21:19:54 +0000591OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000592CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
593{
Virgile Belloe2607b52013-09-05 16:42:23 +0000594{ 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."},
595{ 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."},
596{ 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."},
597{ 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 +0000598{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599};
600
601
602//-------------------------------------------------------------------------
603// CommandObjectThreadContinue
604//-------------------------------------------------------------------------
605
Jim Ingham5a988412012-06-08 21:56:10 +0000606class CommandObjectThreadContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607{
608public:
609
Greg Claytona7015092010-09-18 01:14:36 +0000610 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000611 CommandObjectParsed (interpreter,
612 "thread continue",
613 "Continue execution of one or more threads in an active process.",
614 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000615 eFlagRequiresThread |
616 eFlagTryTargetAPILock |
617 eFlagProcessMustBeLaunched |
618 eFlagProcessMustBePaused)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000619 {
Caroline Tice405fe672010-10-04 22:28:36 +0000620 CommandArgumentEntry arg;
621 CommandArgumentData thread_idx_arg;
622
623 // Define the first (and only) variant of this arg.
624 thread_idx_arg.arg_type = eArgTypeThreadIndex;
625 thread_idx_arg.arg_repetition = eArgRepeatPlus;
626
627 // There is only one variant this argument could be; put it into the argument entry.
628 arg.push_back (thread_idx_arg);
629
630 // Push the data for the first argument into the m_arguments vector.
631 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632 }
633
634
635 virtual
636 ~CommandObjectThreadContinue ()
637 {
638 }
639
640 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000641 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642 {
Greg Claytona7015092010-09-18 01:14:36 +0000643 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644
Greg Claytona7015092010-09-18 01:14:36 +0000645 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000647 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000648 result.SetStatus (eReturnStatusFailed);
649 return false;
650 }
651
Greg Claytonf9fc6092013-01-09 19:44:40 +0000652 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000653 if (process == NULL)
654 {
655 result.AppendError ("no process exists. Cannot continue");
656 result.SetStatus (eReturnStatusFailed);
657 return false;
658 }
659
660 StateType state = process->GetState();
661 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
662 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663 const size_t argc = command.GetArgumentCount();
664 if (argc > 0)
665 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000666 // These two lines appear at the beginning of both blocks in
667 // this if..else, but that is because we need to release the
668 // lock before calling process->Resume below.
669 Mutex::Locker locker (process->GetThreadList().GetMutex());
670 const uint32_t num_threads = process->GetThreadList().GetSize();
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000671 std::vector<Thread *> resume_threads;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672 for (uint32_t i=0; i<argc; ++i)
673 {
Jim Inghamce76c622012-05-31 20:48:41 +0000674 bool success;
675 const int base = 0;
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000676 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
677 if (success)
Jim Inghamce76c622012-05-31 20:48:41 +0000678 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000679 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000680
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000681 if (thread)
682 {
683 resume_threads.push_back(thread);
684 }
685 else
686 {
687 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
688 result.SetStatus (eReturnStatusFailed);
689 return false;
690 }
Jim Inghamce76c622012-05-31 20:48:41 +0000691 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000692 else
Jim Inghamce76c622012-05-31 20:48:41 +0000693 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000694 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamce76c622012-05-31 20:48:41 +0000695 result.SetStatus (eReturnStatusFailed);
696 return false;
697 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000699
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000700 if (resume_threads.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701 {
702 result.AppendError ("no valid thread indexes were specified");
703 result.SetStatus (eReturnStatusFailed);
704 return false;
705 }
706 else
707 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000708 if (resume_threads.size() == 1)
Jim Inghamce76c622012-05-31 20:48:41 +0000709 result.AppendMessageWithFormat ("Resuming thread: ");
710 else
711 result.AppendMessageWithFormat ("Resuming threads: ");
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000712
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000713 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000715 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
716 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000717
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000718 if (this_thread_pos != resume_threads.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000720 resume_threads.erase(this_thread_pos);
721 if (resume_threads.size() > 0)
Jim Inghamce76c622012-05-31 20:48:41 +0000722 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
723 else
724 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000725
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000726 thread->SetResumeState (eStateRunning);
727 }
728 else
729 {
730 thread->SetResumeState (eStateSuspended);
731 }
732 }
Daniel Malead01b2952012-11-29 21:49:15 +0000733 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734 }
735 }
736 else
737 {
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000738 // These two lines appear at the beginning of both blocks in
739 // this if..else, but that is because we need to release the
740 // lock before calling process->Resume below.
741 Mutex::Locker locker (process->GetThreadList().GetMutex());
742 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham2976d002010-08-26 21:32:51 +0000743 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744 if (current_thread == NULL)
745 {
746 result.AppendError ("the process doesn't have a current thread");
747 result.SetStatus (eReturnStatusFailed);
748 return false;
749 }
750 // Set the actions that the threads should each take when resuming
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000751 for (uint32_t idx=0; idx<num_threads; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752 {
Greg Claytonc8a0ce02012-07-03 20:54:16 +0000753 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 if (thread == current_thread)
755 {
Daniel Malead01b2952012-11-29 21:49:15 +0000756 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 thread->SetResumeState (eStateRunning);
758 }
759 else
760 {
761 thread->SetResumeState (eStateSuspended);
762 }
763 }
764 }
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000765
766 // We should not be holding the thread list lock when we do this.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767 Error error (process->Resume());
768 if (error.Success())
769 {
Daniel Malead01b2952012-11-29 21:49:15 +0000770 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771 if (synchronous_execution)
772 {
Greg Claytonb1320972010-07-14 00:18:15 +0000773 state = process->WaitForProcessToStop (NULL);
Andrew Kaylor9063bf42013-09-12 19:15:05 +0000774
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +0000776 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000777 result.SetStatus (eReturnStatusSuccessFinishNoResult);
778 }
779 else
780 {
781 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
782 }
783 }
784 else
785 {
786 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
787 result.SetStatus (eReturnStatusFailed);
788 }
789 }
790 else
791 {
792 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
793 StateAsCString(state));
794 result.SetStatus (eReturnStatusFailed);
795 }
796
797 return result.Succeeded();
798 }
799
800};
801
802//-------------------------------------------------------------------------
803// CommandObjectThreadUntil
804//-------------------------------------------------------------------------
805
Jim Ingham5a988412012-06-08 21:56:10 +0000806class CommandObjectThreadUntil : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000807{
808public:
809
810 class CommandOptions : public Options
811 {
812 public:
813 uint32_t m_thread_idx;
814 uint32_t m_frame_idx;
815
Greg Claytoneb0103f2011-04-07 22:46:35 +0000816 CommandOptions (CommandInterpreter &interpreter) :
817 Options (interpreter),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000818 m_thread_idx(LLDB_INVALID_THREAD_ID),
819 m_frame_idx(LLDB_INVALID_FRAME_ID)
820 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000821 // Keep default values of all options in one place: OptionParsingStarting ()
822 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823 }
824
825 virtual
826 ~CommandOptions ()
827 {
828 }
829
830 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000831 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832 {
833 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000834 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835
836 switch (short_option)
837 {
838 case 't':
839 {
Greg Claytonb1320972010-07-14 00:18:15 +0000840 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841 if (m_thread_idx == LLDB_INVALID_INDEX32)
842 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000843 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000844 }
845 }
846 break;
847 case 'f':
848 {
849 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
850 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
851 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000852 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 }
854 }
855 break;
856 case 'm':
857 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000858 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000859 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860
Greg Claytoncf0e4f02011-10-07 18:58:12 +0000861 if (error.Success())
862 {
863 if (run_mode == eAllThreads)
864 m_stop_others = false;
865 else
866 m_stop_others = true;
867 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868 }
869 break;
870 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000871 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000872 break;
873
874 }
875 return error;
876 }
877
878 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000879 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000881 m_thread_idx = LLDB_INVALID_THREAD_ID;
882 m_frame_idx = 0;
883 m_stop_others = false;
884 }
885
Greg Claytone0d378b2011-03-24 21:19:54 +0000886 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000887 GetDefinitions ()
888 {
889 return g_option_table;
890 }
891
892 uint32_t m_step_thread_idx;
893 bool m_stop_others;
894
895 // Options table: Required for subclasses of Options.
896
Greg Claytone0d378b2011-03-24 21:19:54 +0000897 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898
899 // Instance variables to hold the values for command options.
900 };
901
Greg Claytona7015092010-09-18 01:14:36 +0000902 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000903 CommandObjectParsed (interpreter,
904 "thread until",
905 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
906 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000907 eFlagRequiresThread |
908 eFlagTryTargetAPILock |
909 eFlagProcessMustBeLaunched |
910 eFlagProcessMustBePaused ),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000911 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000912 {
Caroline Tice405fe672010-10-04 22:28:36 +0000913 CommandArgumentEntry arg;
914 CommandArgumentData line_num_arg;
915
916 // Define the first (and only) variant of this arg.
917 line_num_arg.arg_type = eArgTypeLineNum;
918 line_num_arg.arg_repetition = eArgRepeatPlain;
919
920 // There is only one variant this argument could be; put it into the argument entry.
921 arg.push_back (line_num_arg);
922
923 // Push the data for the first argument into the m_arguments vector.
924 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 }
926
927
928 virtual
929 ~CommandObjectThreadUntil ()
930 {
931 }
932
933 virtual
934 Options *
935 GetOptions ()
936 {
937 return &m_options;
938 }
939
Jim Ingham5a988412012-06-08 21:56:10 +0000940protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000941 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000942 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000943 {
Greg Claytona7015092010-09-18 01:14:36 +0000944 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000945
Greg Claytona7015092010-09-18 01:14:36 +0000946 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Claytonf5e56de2010-09-14 23:36:40 +0000947 if (target == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000948 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000949 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950 result.SetStatus (eReturnStatusFailed);
951 return false;
952 }
953
Greg Claytonf9fc6092013-01-09 19:44:40 +0000954 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955 if (process == NULL)
956 {
957 result.AppendError ("need a valid process to step");
958 result.SetStatus (eReturnStatusFailed);
959
960 }
961 else
962 {
963 Thread *thread = NULL;
964 uint32_t line_number;
965
966 if (command.GetArgumentCount() != 1)
967 {
968 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
969 result.SetStatus (eReturnStatusFailed);
970 return false;
971 }
972
973 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
974 if (line_number == UINT32_MAX)
975 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000976 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977 result.SetStatus (eReturnStatusFailed);
978 return false;
979 }
980
981 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
982 {
Jim Ingham2976d002010-08-26 21:32:51 +0000983 thread = process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984 }
985 else
986 {
Greg Clayton76927ee2012-05-31 00:29:20 +0000987 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988 }
989
990 if (thread == NULL)
991 {
992 const uint32_t num_threads = process->GetThreadList().GetSize();
Jim Ingham9b70ddb2011-05-08 00:56:32 +0000993 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
994 m_options.m_thread_idx,
Jim Ingham9b70ddb2011-05-08 00:56:32 +0000995 num_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996 result.SetStatus (eReturnStatusFailed);
997 return false;
998 }
999
Jim Ingham7ba6e992012-05-11 23:47:32 +00001000 const bool abort_other_plans = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001
1002 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
1003 if (frame == NULL)
1004 {
1005
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001006 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1007 m_options.m_frame_idx,
1008 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009 result.SetStatus (eReturnStatusFailed);
1010 return false;
1011 }
1012
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001013 ThreadPlanSP new_plan_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014
1015 if (frame->HasDebugInformation ())
1016 {
1017 // Finally we got here... Translate the given line number to a bunch of addresses:
1018 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1019 LineTable *line_table = NULL;
1020 if (sc.comp_unit)
1021 line_table = sc.comp_unit->GetLineTable();
1022
1023 if (line_table == NULL)
1024 {
1025 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1026 m_options.m_frame_idx, m_options.m_thread_idx);
1027 result.SetStatus (eReturnStatusFailed);
1028 return false;
1029 }
1030
1031 LineEntry function_start;
1032 uint32_t index_ptr = 0, end_ptr;
1033 std::vector<addr_t> address_list;
1034
1035 // Find the beginning & end index of the
1036 AddressRange fun_addr_range = sc.function->GetAddressRange();
1037 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1038 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1039
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001040 Address fun_end_addr(fun_start_addr.GetSection(),
1041 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1043
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001044 bool all_in_function = true;
1045
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046 while (index_ptr <= end_ptr)
1047 {
1048 LineEntry line_entry;
Jim Ingham87df91b2011-09-23 00:54:11 +00001049 const bool exact = false;
1050 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051 if (index_ptr == UINT32_MAX)
1052 break;
1053
Greg Claytonf5e56de2010-09-14 23:36:40 +00001054 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055 if (address != LLDB_INVALID_ADDRESS)
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001056 {
1057 if (fun_addr_range.ContainsLoadAddress (address, target))
1058 address_list.push_back (address);
1059 else
1060 all_in_function = false;
1061 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062 index_ptr++;
1063 }
1064
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001065 if (address_list.size() == 0)
1066 {
1067 if (all_in_function)
1068 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1069 else
1070 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1071
1072 result.SetStatus (eReturnStatusFailed);
1073 return false;
1074 }
1075
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001076 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001077 &address_list.front(),
1078 address_list.size(),
1079 m_options.m_stop_others,
Jim Inghamf76ab672012-09-14 20:48:14 +00001080 m_options.m_frame_idx);
Jim Ingham64e7ead2012-05-03 21:19:36 +00001081 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1082 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1083 // will resume the original plan.
Jim Ingham4d56e9c2013-07-18 21:48:26 +00001084 new_plan_sp->SetIsMasterPlan (true);
1085 new_plan_sp->SetOkayToDiscard(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001086 }
1087 else
1088 {
Jim Ingham9b70ddb2011-05-08 00:56:32 +00001089 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1090 m_options.m_frame_idx,
1091 m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001092 result.SetStatus (eReturnStatusFailed);
1093 return false;
1094
1095 }
1096
Jim Ingham2976d002010-08-26 21:32:51 +00001097 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001098 Error error (process->Resume ());
1099 if (error.Success())
1100 {
Daniel Malead01b2952012-11-29 21:49:15 +00001101 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102 if (synchronous_execution)
1103 {
1104 StateType state = process->WaitForProcessToStop (NULL);
1105
1106 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +00001107 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001108 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1109 }
1110 else
1111 {
1112 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1113 }
1114 }
1115 else
1116 {
1117 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1118 result.SetStatus (eReturnStatusFailed);
1119 }
1120
1121 }
1122 return result.Succeeded();
1123 }
Jim Ingham5a988412012-06-08 21:56:10 +00001124
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125 CommandOptions m_options;
1126
1127};
1128
Greg Claytone0d378b2011-03-24 21:19:54 +00001129OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001130CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1131{
Virgile Belloe2607b52013-09-05 16:42:23 +00001132{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1133{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1134{ 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 +00001135{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136};
1137
1138
1139//-------------------------------------------------------------------------
1140// CommandObjectThreadSelect
1141//-------------------------------------------------------------------------
1142
Jim Ingham5a988412012-06-08 21:56:10 +00001143class CommandObjectThreadSelect : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144{
1145public:
1146
Greg Claytona7015092010-09-18 01:14:36 +00001147 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001148 CommandObjectParsed (interpreter,
1149 "thread select",
1150 "Select a thread as the currently active thread.",
1151 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001152 eFlagRequiresProcess |
1153 eFlagTryTargetAPILock |
1154 eFlagProcessMustBeLaunched |
1155 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001156 {
Caroline Tice405fe672010-10-04 22:28:36 +00001157 CommandArgumentEntry arg;
1158 CommandArgumentData thread_idx_arg;
1159
1160 // Define the first (and only) variant of this arg.
1161 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1162 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1163
1164 // There is only one variant this argument could be; put it into the argument entry.
1165 arg.push_back (thread_idx_arg);
1166
1167 // Push the data for the first argument into the m_arguments vector.
1168 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001169 }
1170
1171
1172 virtual
1173 ~CommandObjectThreadSelect ()
1174 {
1175 }
1176
Jim Ingham5a988412012-06-08 21:56:10 +00001177protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001178 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001179 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001181 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182 if (process == NULL)
1183 {
1184 result.AppendError ("no process");
1185 result.SetStatus (eReturnStatusFailed);
1186 return false;
1187 }
1188 else if (command.GetArgumentCount() != 1)
1189 {
Jason Molendafd54b362011-09-20 21:44:10 +00001190 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 +00001191 result.SetStatus (eReturnStatusFailed);
1192 return false;
1193 }
1194
1195 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1196
1197 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1198 if (new_thread == NULL)
1199 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001200 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201 result.SetStatus (eReturnStatusFailed);
1202 return false;
1203 }
1204
Jim Inghamc3faa192012-12-11 02:31:48 +00001205 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
Johnny Chenc13ee522010-09-14 00:53:53 +00001206 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001207
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001208 return result.Succeeded();
1209 }
1210
1211};
1212
1213
1214//-------------------------------------------------------------------------
1215// CommandObjectThreadList
1216//-------------------------------------------------------------------------
1217
Jim Ingham5a988412012-06-08 21:56:10 +00001218class CommandObjectThreadList : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001219{
Greg Clayton66111032010-06-23 01:19:29 +00001220public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001221
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001222
Greg Claytona7015092010-09-18 01:14:36 +00001223 CommandObjectThreadList (CommandInterpreter &interpreter):
Jim Ingham5a988412012-06-08 21:56:10 +00001224 CommandObjectParsed (interpreter,
1225 "thread list",
1226 "Show a summary of all current threads in a process.",
1227 "thread list",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001228 eFlagRequiresProcess |
1229 eFlagTryTargetAPILock |
1230 eFlagProcessMustBeLaunched |
1231 eFlagProcessMustBePaused )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001232 {
Greg Clayton66111032010-06-23 01:19:29 +00001233 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001234
Greg Clayton66111032010-06-23 01:19:29 +00001235 ~CommandObjectThreadList()
1236 {
1237 }
1238
Jim Ingham5a988412012-06-08 21:56:10 +00001239protected:
Greg Clayton66111032010-06-23 01:19:29 +00001240 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001241 DoExecute (Args& command, CommandReturnObject &result)
Greg Clayton66111032010-06-23 01:19:29 +00001242 {
Jim Ingham85e8b812011-02-19 02:53:09 +00001243 Stream &strm = result.GetOutputStream();
Greg Clayton66111032010-06-23 01:19:29 +00001244 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001245 Process *process = m_exe_ctx.GetProcessPtr();
1246 const bool only_threads_with_stop_reason = false;
1247 const uint32_t start_frame = 0;
1248 const uint32_t num_frames = 0;
1249 const uint32_t num_frames_with_source = 0;
1250 process->GetStatus(strm);
1251 process->GetThreadStatus (strm,
1252 only_threads_with_stop_reason,
1253 start_frame,
1254 num_frames,
1255 num_frames_with_source);
Greg Clayton66111032010-06-23 01:19:29 +00001256 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257 }
Greg Clayton66111032010-06-23 01:19:29 +00001258};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259
Jim Ingham93208b82013-01-31 21:46:01 +00001260//-------------------------------------------------------------------------
1261// CommandObjectThreadReturn
1262//-------------------------------------------------------------------------
1263
Jim Inghamcb640dd2012-09-14 02:14:15 +00001264class CommandObjectThreadReturn : public CommandObjectRaw
1265{
1266public:
Jim Ingham93208b82013-01-31 21:46:01 +00001267 class CommandOptions : public Options
1268 {
1269 public:
1270
1271 CommandOptions (CommandInterpreter &interpreter) :
1272 Options (interpreter),
1273 m_from_expression (false)
1274 {
1275 // Keep default values of all options in one place: OptionParsingStarting ()
1276 OptionParsingStarting ();
1277 }
1278
1279 virtual
1280 ~CommandOptions ()
1281 {
1282 }
1283
1284 virtual Error
1285 SetOptionValue (uint32_t option_idx, const char *option_arg)
1286 {
1287 Error error;
1288 const int short_option = m_getopt_table[option_idx].val;
1289
1290 switch (short_option)
1291 {
1292 case 'x':
1293 {
1294 bool success;
1295 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1296 if (success)
1297 m_from_expression = tmp_value;
1298 else
1299 {
1300 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1301 }
1302 }
1303 break;
1304 default:
1305 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1306 break;
1307
1308 }
1309 return error;
1310 }
1311
1312 void
1313 OptionParsingStarting ()
1314 {
1315 m_from_expression = false;
1316 }
1317
1318 const OptionDefinition*
1319 GetDefinitions ()
1320 {
1321 return g_option_table;
1322 }
1323
1324 bool m_from_expression;
1325
1326 // Options table: Required for subclasses of Options.
1327
1328 static OptionDefinition g_option_table[];
1329
1330 // Instance variables to hold the values for command options.
1331 };
1332
1333 virtual
1334 Options *
1335 GetOptions ()
1336 {
1337 return &m_options;
1338 }
1339
Jim Inghamcb640dd2012-09-14 02:14:15 +00001340 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1341 CommandObjectRaw (interpreter,
1342 "thread return",
Jim Ingham93208b82013-01-31 21:46:01 +00001343 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1344 " or with the -x option from the innermost function evaluation.",
Jim Inghamcb640dd2012-09-14 02:14:15 +00001345 "thread return",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001346 eFlagRequiresFrame |
1347 eFlagTryTargetAPILock |
1348 eFlagProcessMustBeLaunched |
Jim Ingham93208b82013-01-31 21:46:01 +00001349 eFlagProcessMustBePaused ),
1350 m_options (interpreter)
Jim Inghamcb640dd2012-09-14 02:14:15 +00001351 {
1352 CommandArgumentEntry arg;
1353 CommandArgumentData expression_arg;
1354
1355 // Define the first (and only) variant of this arg.
1356 expression_arg.arg_type = eArgTypeExpression;
Jim Ingham93208b82013-01-31 21:46:01 +00001357 expression_arg.arg_repetition = eArgRepeatOptional;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001358
1359 // There is only one variant this argument could be; put it into the argument entry.
1360 arg.push_back (expression_arg);
1361
1362 // Push the data for the first argument into the m_arguments vector.
1363 m_arguments.push_back (arg);
1364
1365
1366 }
1367
1368 ~CommandObjectThreadReturn()
1369 {
1370 }
1371
1372protected:
1373
1374 bool DoExecute
1375 (
1376 const char *command,
1377 CommandReturnObject &result
1378 )
1379 {
Jim Ingham93208b82013-01-31 21:46:01 +00001380 // I am going to handle this by hand, because I don't want you to have to say:
1381 // "thread return -- -5".
1382 if (command[0] == '-' && command[1] == 'x')
1383 {
1384 if (command && command[2] != '\0')
1385 result.AppendWarning("Return values ignored when returning from user called expressions");
1386
1387 Thread *thread = m_exe_ctx.GetThreadPtr();
1388 Error error;
1389 error = thread->UnwindInnermostExpression();
1390 if (!error.Success())
1391 {
1392 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1393 result.SetStatus (eReturnStatusFailed);
1394 }
1395 else
1396 {
1397 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1398 if (success)
1399 {
1400 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1401 result.SetStatus (eReturnStatusSuccessFinishResult);
1402 }
1403 else
1404 {
1405 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1406 result.SetStatus (eReturnStatusFailed);
1407 }
1408 }
1409 return result.Succeeded();
1410 }
1411
Jim Inghamcb640dd2012-09-14 02:14:15 +00001412 ValueObjectSP return_valobj_sp;
1413
Greg Claytonf9fc6092013-01-09 19:44:40 +00001414 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
Jim Inghamcb640dd2012-09-14 02:14:15 +00001415 uint32_t frame_idx = frame_sp->GetFrameIndex();
1416
1417 if (frame_sp->IsInlined())
1418 {
1419 result.AppendError("Don't know how to return from inlined frames.");
1420 result.SetStatus (eReturnStatusFailed);
1421 return false;
1422 }
1423
1424 if (command && command[0] != '\0')
1425 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001426 Target *target = m_exe_ctx.GetTargetPtr();
Jim Ingham35e1bda2012-10-16 21:41:58 +00001427 EvaluateExpressionOptions options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001428
1429 options.SetUnwindOnError(true);
1430 options.SetUseDynamic(eNoDynamicValues);
1431
1432 ExecutionResults exe_results = eExecutionSetupError;
1433 exe_results = target->EvaluateExpression (command,
1434 frame_sp.get(),
1435 return_valobj_sp,
1436 options);
1437 if (exe_results != eExecutionCompleted)
1438 {
1439 if (return_valobj_sp)
1440 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1441 else
1442 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1443 result.SetStatus (eReturnStatusFailed);
1444 return false;
1445
1446 }
1447 }
1448
1449 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001450 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
Jim Ingham4f465cf2012-10-10 18:32:14 +00001451 const bool broadcast = true;
1452 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
Jim Inghamcb640dd2012-09-14 02:14:15 +00001453 if (!error.Success())
1454 {
1455 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1456 result.SetStatus (eReturnStatusFailed);
1457 return false;
1458 }
1459
Jim Inghamcb640dd2012-09-14 02:14:15 +00001460 result.SetStatus (eReturnStatusSuccessFinishResult);
1461 return true;
1462 }
Jim Ingham93208b82013-01-31 21:46:01 +00001463
1464 CommandOptions m_options;
Jim Inghamcb640dd2012-09-14 02:14:15 +00001465
1466};
Jim Ingham93208b82013-01-31 21:46:01 +00001467OptionDefinition
1468CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1469{
Virgile Belloe2607b52013-09-05 16:42:23 +00001470{ 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 +00001471{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1472};
Jim Inghamcb640dd2012-09-14 02:14:15 +00001473
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001474//-------------------------------------------------------------------------
Richard Mittonf86248d2013-09-12 02:20:34 +00001475// CommandObjectThreadJump
1476//-------------------------------------------------------------------------
1477
1478class CommandObjectThreadJump : public CommandObjectParsed
1479{
1480public:
1481 class CommandOptions : public Options
1482 {
1483 public:
1484
1485 CommandOptions (CommandInterpreter &interpreter) :
1486 Options (interpreter)
1487 {
1488 OptionParsingStarting ();
1489 }
1490
1491 void
1492 OptionParsingStarting ()
1493 {
1494 m_filenames.Clear();
1495 m_line_num = 0;
1496 m_line_offset = 0;
1497 m_load_addr = LLDB_INVALID_ADDRESS;
1498 m_force = false;
1499 }
1500
1501 virtual
1502 ~CommandOptions ()
1503 {
1504 }
1505
1506 virtual Error
1507 SetOptionValue (uint32_t option_idx, const char *option_arg)
1508 {
1509 bool success;
1510 const int short_option = m_getopt_table[option_idx].val;
1511 Error error;
1512
1513 switch (short_option)
1514 {
1515 case 'f':
1516 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1517 if (m_filenames.GetSize() > 1)
1518 return Error("only one source file expected.");
1519 break;
1520 case 'l':
1521 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1522 if (!success || m_line_num == 0)
1523 return Error("invalid line number: '%s'.", option_arg);
1524 break;
1525 case 'b':
1526 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1527 if (!success)
1528 return Error("invalid line offset: '%s'.", option_arg);
1529 break;
1530 case 'a':
1531 {
1532 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1533 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1534 }
1535 break;
1536 case 'r':
1537 m_force = true;
1538 break;
1539
1540 default:
1541 return Error("invalid short option character '%c'", short_option);
1542
1543 }
1544 return error;
1545 }
1546
1547 const OptionDefinition*
1548 GetDefinitions ()
1549 {
1550 return g_option_table;
1551 }
1552
1553 FileSpecList m_filenames;
1554 uint32_t m_line_num;
1555 int32_t m_line_offset;
1556 lldb::addr_t m_load_addr;
1557 bool m_force;
1558
1559 static OptionDefinition g_option_table[];
1560 };
1561
1562 virtual
1563 Options *
1564 GetOptions ()
1565 {
1566 return &m_options;
1567 }
1568
1569 CommandObjectThreadJump (CommandInterpreter &interpreter) :
1570 CommandObjectParsed (interpreter,
1571 "thread jump",
1572 "Sets the program counter to a new address.",
1573 "thread jump",
1574 eFlagRequiresFrame |
1575 eFlagTryTargetAPILock |
1576 eFlagProcessMustBeLaunched |
1577 eFlagProcessMustBePaused ),
1578 m_options (interpreter)
1579 {
1580 }
1581
1582 ~CommandObjectThreadJump()
1583 {
1584 }
1585
1586protected:
1587
1588 bool DoExecute (Args& args, CommandReturnObject &result)
1589 {
1590 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1591 StackFrame *frame = m_exe_ctx.GetFramePtr();
1592 Thread *thread = m_exe_ctx.GetThreadPtr();
1593 Target *target = m_exe_ctx.GetTargetPtr();
1594 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1595
1596 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1597 {
1598 // Use this address directly.
1599 Address dest = Address(m_options.m_load_addr);
1600
1601 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1602 if (callAddr == LLDB_INVALID_ADDRESS)
1603 {
1604 result.AppendErrorWithFormat ("Invalid destination address.");
1605 result.SetStatus (eReturnStatusFailed);
1606 return false;
1607 }
1608
1609 if (!reg_ctx->SetPC (callAddr))
1610 {
1611 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1612 result.SetStatus (eReturnStatusFailed);
1613 return false;
1614 }
1615 }
1616 else
1617 {
1618 // Pick either the absolute line, or work out a relative one.
1619 int32_t line = (int32_t)m_options.m_line_num;
1620 if (line == 0)
1621 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1622
1623 // Try the current file, but override if asked.
1624 FileSpec file = sym_ctx.line_entry.file;
1625 if (m_options.m_filenames.GetSize() == 1)
1626 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1627
1628 if (!file)
1629 {
1630 result.AppendErrorWithFormat ("No source file available for the current location.");
1631 result.SetStatus (eReturnStatusFailed);
1632 return false;
1633 }
1634
1635 std::string warnings;
1636 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1637
1638 if (err.Fail())
1639 {
1640 result.SetError (err);
1641 return false;
1642 }
1643
1644 if (!warnings.empty())
1645 result.AppendWarning (warnings.c_str());
1646 }
1647
1648 result.SetStatus (eReturnStatusSuccessFinishResult);
1649 return true;
1650 }
1651
1652 CommandOptions m_options;
1653};
1654OptionDefinition
1655CommandObjectThreadJump::CommandOptions::g_option_table[] =
1656{
1657 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1658 "Specifies the source file to jump to."},
1659
1660 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
1661 "Specifies the line number to jump to."},
1662
1663 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset,
1664 "Jumps by a relative line offset from the current line."},
1665
1666 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression,
1667 "Jumps to a specific address."},
1668
1669 { LLDB_OPT_SET_1|
1670 LLDB_OPT_SET_2|
1671 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
1672
1673 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1674};
1675
1676//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001677// CommandObjectMultiwordThread
1678//-------------------------------------------------------------------------
1679
Greg Clayton66111032010-06-23 01:19:29 +00001680CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001681 CommandObjectMultiword (interpreter,
1682 "thread",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001683 "A set of commands for operating on one or more threads within a running process.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001684 "thread <subcommand> [<subcommand-options>]")
1685{
Greg Claytona7015092010-09-18 01:14:36 +00001686 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1687 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1688 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
Jim Inghamcb640dd2012-09-14 02:14:15 +00001689 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
Richard Mittonf86248d2013-09-12 02:20:34 +00001690 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001691 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1692 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1693 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1694 interpreter,
Greg Clayton66111032010-06-23 01:19:29 +00001695 "thread step-in",
Greg Claytona7015092010-09-18 01:14:36 +00001696 "Source level single step in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001697 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001698 eStepTypeInto,
1699 eStepScopeSource)));
Greg Clayton66111032010-06-23 01:19:29 +00001700
Greg Claytona7015092010-09-18 01:14:36 +00001701 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1702 interpreter,
1703 "thread step-out",
Jim Ingham73ca05a2011-12-17 01:35:57 +00001704 "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 +00001705 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001706 eStepTypeOut,
1707 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001708
Greg Claytona7015092010-09-18 01:14:36 +00001709 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1710 interpreter,
1711 "thread step-over",
1712 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001713 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001714 eStepTypeOver,
1715 eStepScopeSource)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001716
Greg Claytona7015092010-09-18 01:14:36 +00001717 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1718 interpreter,
1719 "thread step-inst",
1720 "Single step one instruction in specified thread (current thread, if none specified).",
Caroline Tice405fe672010-10-04 22:28:36 +00001721 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001722 eStepTypeTrace,
1723 eStepScopeInstruction)));
Greg Clayton66111032010-06-23 01:19:29 +00001724
Greg Claytona7015092010-09-18 01:14:36 +00001725 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1726 interpreter,
1727 "thread step-inst-over",
1728 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
Caroline Tice405fe672010-10-04 22:28:36 +00001729 NULL,
Greg Claytona7015092010-09-18 01:14:36 +00001730 eStepTypeTraceOver,
1731 eStepScopeInstruction)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001732}
1733
1734CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1735{
1736}
1737
1738