1 //===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/lldb-python.h"
11
12 #include "CommandObjectThread.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/lldb-private.h"
19 #include "lldb/Core/State.h"
20 #include "lldb/Core/SourceManager.h"
21 #include "lldb/Host/Host.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/CommandReturnObject.h"
24 #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"
29 #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"
34 #include "lldb/Target/ThreadPlanStepInstruction.h"
35 #include "lldb/Target/ThreadPlanStepOut.h"
36 #include "lldb/Target/ThreadPlanStepRange.h"
37 #include "lldb/Target/ThreadPlanStepInRange.h"
38
39
40 using namespace lldb;
41 using namespace lldb_private;
42
43
44 //-------------------------------------------------------------------------
45 // CommandObjectThreadBacktrace
46 //-------------------------------------------------------------------------
47
48 class CommandObjectThreadBacktrace : public CommandObjectParsed
49 {
50 public:
51
52 class CommandOptions : public Options
53 {
54 public:
55
CommandOptions(CommandInterpreter & interpreter)56 CommandOptions (CommandInterpreter &interpreter) :
57 Options(interpreter)
58 {
59 // Keep default values of all options in one place: OptionParsingStarting ()
60 OptionParsingStarting ();
61 }
62
63 virtual
~CommandOptions()64 ~CommandOptions ()
65 {
66 }
67
68 virtual Error
SetOptionValue(uint32_t option_idx,const char * option_arg)69 SetOptionValue (uint32_t option_idx, const char *option_arg)
70 {
71 Error error;
72 const int short_option = m_getopt_table[option_idx].val;
73
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)
81 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
82 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)
93 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
94 }
95 break;
96 default:
97 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
98 break;
99
100 }
101 return error;
102 }
103
104 void
OptionParsingStarting()105 OptionParsingStarting ()
106 {
107 m_count = UINT32_MAX;
108 m_start = 0;
109 }
110
111 const OptionDefinition*
GetDefinitions()112 GetDefinitions ()
113 {
114 return g_option_table;
115 }
116
117 // Options table: Required for subclasses of Options.
118
119 static OptionDefinition g_option_table[];
120
121 // Instance variables to hold the values for command options.
122 uint32_t m_count;
123 uint32_t m_start;
124 };
125
CommandObjectThreadBacktrace(CommandInterpreter & interpreter)126 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
127 CommandObjectParsed (interpreter,
128 "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 ),
136 m_options(interpreter)
137 {
138 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);
150 }
151
~CommandObjectThreadBacktrace()152 ~CommandObjectThreadBacktrace()
153 {
154 }
155
156 virtual Options *
GetOptions()157 GetOptions ()
158 {
159 return &m_options;
160 }
161
162 protected:
163 virtual bool
DoExecute(Args & command,CommandReturnObject & result)164 DoExecute (Args& command, CommandReturnObject &result)
165 {
166 result.SetStatus (eReturnStatusSuccessFinishResult);
167 Stream &strm = result.GetOutputStream();
168
169 // Don't show source context when doing backtraces.
170 const uint32_t num_frames_with_source = 0;
171 if (command.GetArgumentCount() == 0)
172 {
173 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))
179 {
180 result.SetStatus (eReturnStatusSuccessFinishResult);
181 }
182 }
183 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
184 {
185 Process *process = m_exe_ctx.GetProcessPtr();
186 Mutex::Locker locker (process->GetThreadList().GetMutex());
187 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);
191 if (!thread_sp->GetStatus (strm,
192 m_options.m_start,
193 m_options.m_count,
194 num_frames_with_source))
195 {
196 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
197 result.SetStatus (eReturnStatusFailed);
198 return false;
199 }
200
201 if (i < num_threads - 1)
202 result.AppendMessage("");
203
204 }
205 }
206 else
207 {
208 const size_t num_args = command.GetArgumentCount();
209 Process *process = m_exe_ctx.GetProcessPtr();
210 Mutex::Locker locker (process->GetThreadList().GetMutex());
211 std::vector<ThreadSP> thread_sps;
212
213 for (size_t i = 0; i < num_args; i++)
214 {
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 {
238 if (!thread_sps[i]->GetStatus (strm,
239 m_options.m_start,
240 m_options.m_count,
241 num_frames_with_source))
242 {
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 }
251 }
252 return result.Succeeded();
253 }
254
255 CommandOptions m_options;
256 };
257
258 OptionDefinition
259 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
260 {
261 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
262 { LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
263 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
264 };
265
266 enum StepScope
267 {
268 eStepScopeSource,
269 eStepScopeInstruction
270 };
271
272 class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
273 {
274 public:
275
276 class CommandOptions : public Options
277 {
278 public:
279
CommandOptions(CommandInterpreter & interpreter)280 CommandOptions (CommandInterpreter &interpreter) :
281 Options (interpreter)
282 {
283 // Keep default values of all options in one place: OptionParsingStarting ()
284 OptionParsingStarting ();
285 }
286
287 virtual
~CommandOptions()288 ~CommandOptions ()
289 {
290 }
291
292 virtual Error
SetOptionValue(uint32_t option_idx,const char * option_arg)293 SetOptionValue (uint32_t option_idx, const char *option_arg)
294 {
295 Error error;
296 const int short_option = m_getopt_table[option_idx].val;
297
298 switch (short_option)
299 {
300 case 'a':
301 {
302 bool success;
303 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
304 if (!success)
305 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
306 }
307 break;
308
309 case 'm':
310 {
311 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
312 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
313 }
314 break;
315
316 case 'r':
317 {
318 m_avoid_regexp.clear();
319 m_avoid_regexp.assign(option_arg);
320 }
321 break;
322
323 case 't':
324 {
325 m_step_in_target.clear();
326 m_step_in_target.assign(option_arg);
327
328 }
329 break;
330 default:
331 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
332 break;
333
334 }
335 return error;
336 }
337
338 void
OptionParsingStarting()339 OptionParsingStarting ()
340 {
341 m_avoid_no_debug = true;
342 m_run_mode = eOnlyDuringStepping;
343 m_avoid_regexp.clear();
344 m_step_in_target.clear();
345 }
346
347 const OptionDefinition*
GetDefinitions()348 GetDefinitions ()
349 {
350 return g_option_table;
351 }
352
353 // Options table: Required for subclasses of Options.
354
355 static OptionDefinition g_option_table[];
356
357 // Instance variables to hold the values for command options.
358 bool m_avoid_no_debug;
359 RunMode m_run_mode;
360 std::string m_avoid_regexp;
361 std::string m_step_in_target;
362 };
363
CommandObjectThreadStepWithTypeAndScope(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,StepType step_type,StepScope step_scope)364 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
365 const char *name,
366 const char *help,
367 const char *syntax,
368 StepType step_type,
369 StepScope step_scope) :
370 CommandObjectParsed (interpreter, name, help, syntax,
371 eFlagRequiresProcess |
372 eFlagRequiresThread |
373 eFlagTryTargetAPILock |
374 eFlagProcessMustBeLaunched |
375 eFlagProcessMustBePaused ),
376 m_step_type (step_type),
377 m_step_scope (step_scope),
378 m_options (interpreter)
379 {
380 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);
392 }
393
394 virtual
~CommandObjectThreadStepWithTypeAndScope()395 ~CommandObjectThreadStepWithTypeAndScope ()
396 {
397 }
398
399 virtual
400 Options *
GetOptions()401 GetOptions ()
402 {
403 return &m_options;
404 }
405
406 protected:
407 virtual bool
DoExecute(Args & command,CommandReturnObject & result)408 DoExecute (Args& command, CommandReturnObject &result)
409 {
410 Process *process = m_exe_ctx.GetProcessPtr();
411 bool synchronous_execution = m_interpreter.GetSynchronous();
412
413 const uint32_t num_threads = process->GetThreadList().GetSize();
414 Thread *thread = NULL;
415
416 if (command.GetArgumentCount() == 0)
417 {
418 thread = process->GetThreadList().GetSelectedThread().get();
419 if (thread == NULL)
420 {
421 result.AppendError ("no selected thread in process");
422 result.SetStatus (eReturnStatusFailed);
423 return false;
424 }
425 }
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)
431 {
432 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 }
445
446 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;
463
464 ThreadPlanSP new_plan_sp;
465
466 if (m_step_type == eStepTypeInto)
467 {
468 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
469
470 if (frame->HasDebugInformation ())
471 {
472 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
473 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);
478 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
479 {
480 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
481 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
482 }
483 }
484 else
485 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
486
487 }
488 else if (m_step_type == eStepTypeOver)
489 {
490 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
491
492 if (frame->HasDebugInformation())
493 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
494 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
495 frame->GetSymbolContext(eSymbolContextEverything),
496 stop_other_threads);
497 else
498 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
499 abort_other_plans,
500 bool_stop_other_threads);
501
502 }
503 else if (m_step_type == eStepTypeTrace)
504 {
505 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
506 }
507 else if (m_step_type == eStepTypeTraceOver)
508 {
509 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
510 }
511 else if (m_step_type == eStepTypeOut)
512 {
513 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
514 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
531 if (new_plan_sp)
532 {
533 new_plan_sp->SetIsMasterPlan (true);
534 new_plan_sp->SetOkayToDiscard (false);
535
536 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
537 process->Resume ();
538
539
540 if (synchronous_execution)
541 {
542 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);
554 }
555 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);
564 }
565 return result.Succeeded();
566 }
567
568 protected:
569 StepType m_step_type;
570 StepScope m_step_scope;
571 CommandOptions m_options;
572 };
573
574 static OptionEnumValueElement
575 g_tri_running_mode[] =
576 {
577 { eOnlyThisThread, "this-thread", "Run only this thread"},
578 { eAllThreads, "all-threads", "Run all threads"},
579 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
580 { 0, NULL, NULL }
581 };
582
583 static OptionEnumValueElement
584 g_duo_running_mode[] =
585 {
586 { eOnlyThisThread, "this-thread", "Run only this thread"},
587 { eAllThreads, "all-threads", "Run all threads"},
588 { 0, NULL, NULL }
589 };
590
591 OptionDefinition
592 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
593 {
594 { LLDB_OPT_SET_1, false, "avoid-no-debug", 'a', required_argument, 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', required_argument, 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', required_argument, 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', required_argument, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
598 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
599 };
600
601
602 //-------------------------------------------------------------------------
603 // CommandObjectThreadContinue
604 //-------------------------------------------------------------------------
605
606 class CommandObjectThreadContinue : public CommandObjectParsed
607 {
608 public:
609
CommandObjectThreadContinue(CommandInterpreter & interpreter)610 CommandObjectThreadContinue (CommandInterpreter &interpreter) :
611 CommandObjectParsed (interpreter,
612 "thread continue",
613 "Continue execution of one or more threads in an active process.",
614 NULL,
615 eFlagRequiresThread |
616 eFlagTryTargetAPILock |
617 eFlagProcessMustBeLaunched |
618 eFlagProcessMustBePaused)
619 {
620 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);
632 }
633
634
635 virtual
~CommandObjectThreadContinue()636 ~CommandObjectThreadContinue ()
637 {
638 }
639
640 virtual bool
DoExecute(Args & command,CommandReturnObject & result)641 DoExecute (Args& command, CommandReturnObject &result)
642 {
643 bool synchronous_execution = m_interpreter.GetSynchronous ();
644
645 if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
646 {
647 result.AppendError ("invalid target, create a debug target using the 'target create' command");
648 result.SetStatus (eReturnStatusFailed);
649 return false;
650 }
651
652 Process *process = m_exe_ctx.GetProcessPtr();
653 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 {
663 Mutex::Locker locker (process->GetThreadList().GetMutex());
664 const uint32_t num_threads = process->GetThreadList().GetSize();
665 const size_t argc = command.GetArgumentCount();
666 if (argc > 0)
667 {
668 std::vector<Thread *> resume_threads;
669 for (uint32_t i=0; i<argc; ++i)
670 {
671 bool success;
672 const int base = 0;
673 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
674 if (success)
675 {
676 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
677
678 if (thread)
679 {
680 resume_threads.push_back(thread);
681 }
682 else
683 {
684 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
685 result.SetStatus (eReturnStatusFailed);
686 return false;
687 }
688 }
689 else
690 {
691 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
692 result.SetStatus (eReturnStatusFailed);
693 return false;
694 }
695 }
696
697 if (resume_threads.empty())
698 {
699 result.AppendError ("no valid thread indexes were specified");
700 result.SetStatus (eReturnStatusFailed);
701 return false;
702 }
703 else
704 {
705 if (resume_threads.size() == 1)
706 result.AppendMessageWithFormat ("Resuming thread: ");
707 else
708 result.AppendMessageWithFormat ("Resuming threads: ");
709
710 for (uint32_t idx=0; idx<num_threads; ++idx)
711 {
712 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
713 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
714
715 if (this_thread_pos != resume_threads.end())
716 {
717 resume_threads.erase(this_thread_pos);
718 if (resume_threads.size() > 0)
719 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
720 else
721 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
722
723 thread->SetResumeState (eStateRunning);
724 }
725 else
726 {
727 thread->SetResumeState (eStateSuspended);
728 }
729 }
730 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
731 }
732 }
733 else
734 {
735 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
736 if (current_thread == NULL)
737 {
738 result.AppendError ("the process doesn't have a current thread");
739 result.SetStatus (eReturnStatusFailed);
740 return false;
741 }
742 // Set the actions that the threads should each take when resuming
743 for (uint32_t idx=0; idx<num_threads; ++idx)
744 {
745 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
746 if (thread == current_thread)
747 {
748 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
749 thread->SetResumeState (eStateRunning);
750 }
751 else
752 {
753 thread->SetResumeState (eStateSuspended);
754 }
755 }
756 }
757
758 Error error (process->Resume());
759 if (error.Success())
760 {
761 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
762 if (synchronous_execution)
763 {
764 state = process->WaitForProcessToStop (NULL);
765
766 result.SetDidChangeProcessState (true);
767 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
768 result.SetStatus (eReturnStatusSuccessFinishNoResult);
769 }
770 else
771 {
772 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
773 }
774 }
775 else
776 {
777 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
778 result.SetStatus (eReturnStatusFailed);
779 }
780 }
781 else
782 {
783 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
784 StateAsCString(state));
785 result.SetStatus (eReturnStatusFailed);
786 }
787
788 return result.Succeeded();
789 }
790
791 };
792
793 //-------------------------------------------------------------------------
794 // CommandObjectThreadUntil
795 //-------------------------------------------------------------------------
796
797 class CommandObjectThreadUntil : public CommandObjectParsed
798 {
799 public:
800
801 class CommandOptions : public Options
802 {
803 public:
804 uint32_t m_thread_idx;
805 uint32_t m_frame_idx;
806
CommandOptions(CommandInterpreter & interpreter)807 CommandOptions (CommandInterpreter &interpreter) :
808 Options (interpreter),
809 m_thread_idx(LLDB_INVALID_THREAD_ID),
810 m_frame_idx(LLDB_INVALID_FRAME_ID)
811 {
812 // Keep default values of all options in one place: OptionParsingStarting ()
813 OptionParsingStarting ();
814 }
815
816 virtual
~CommandOptions()817 ~CommandOptions ()
818 {
819 }
820
821 virtual Error
SetOptionValue(uint32_t option_idx,const char * option_arg)822 SetOptionValue (uint32_t option_idx, const char *option_arg)
823 {
824 Error error;
825 const int short_option = m_getopt_table[option_idx].val;
826
827 switch (short_option)
828 {
829 case 't':
830 {
831 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
832 if (m_thread_idx == LLDB_INVALID_INDEX32)
833 {
834 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
835 }
836 }
837 break;
838 case 'f':
839 {
840 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
841 if (m_frame_idx == LLDB_INVALID_FRAME_ID)
842 {
843 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
844 }
845 }
846 break;
847 case 'm':
848 {
849 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
850 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
851
852 if (error.Success())
853 {
854 if (run_mode == eAllThreads)
855 m_stop_others = false;
856 else
857 m_stop_others = true;
858 }
859 }
860 break;
861 default:
862 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
863 break;
864
865 }
866 return error;
867 }
868
869 void
OptionParsingStarting()870 OptionParsingStarting ()
871 {
872 m_thread_idx = LLDB_INVALID_THREAD_ID;
873 m_frame_idx = 0;
874 m_stop_others = false;
875 }
876
877 const OptionDefinition*
GetDefinitions()878 GetDefinitions ()
879 {
880 return g_option_table;
881 }
882
883 uint32_t m_step_thread_idx;
884 bool m_stop_others;
885
886 // Options table: Required for subclasses of Options.
887
888 static OptionDefinition g_option_table[];
889
890 // Instance variables to hold the values for command options.
891 };
892
CommandObjectThreadUntil(CommandInterpreter & interpreter)893 CommandObjectThreadUntil (CommandInterpreter &interpreter) :
894 CommandObjectParsed (interpreter,
895 "thread until",
896 "Run the current or specified thread until it reaches a given line number or leaves the current function.",
897 NULL,
898 eFlagRequiresThread |
899 eFlagTryTargetAPILock |
900 eFlagProcessMustBeLaunched |
901 eFlagProcessMustBePaused ),
902 m_options (interpreter)
903 {
904 CommandArgumentEntry arg;
905 CommandArgumentData line_num_arg;
906
907 // Define the first (and only) variant of this arg.
908 line_num_arg.arg_type = eArgTypeLineNum;
909 line_num_arg.arg_repetition = eArgRepeatPlain;
910
911 // There is only one variant this argument could be; put it into the argument entry.
912 arg.push_back (line_num_arg);
913
914 // Push the data for the first argument into the m_arguments vector.
915 m_arguments.push_back (arg);
916 }
917
918
919 virtual
~CommandObjectThreadUntil()920 ~CommandObjectThreadUntil ()
921 {
922 }
923
924 virtual
925 Options *
GetOptions()926 GetOptions ()
927 {
928 return &m_options;
929 }
930
931 protected:
932 virtual bool
DoExecute(Args & command,CommandReturnObject & result)933 DoExecute (Args& command, CommandReturnObject &result)
934 {
935 bool synchronous_execution = m_interpreter.GetSynchronous ();
936
937 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
938 if (target == NULL)
939 {
940 result.AppendError ("invalid target, create a debug target using the 'target create' command");
941 result.SetStatus (eReturnStatusFailed);
942 return false;
943 }
944
945 Process *process = m_exe_ctx.GetProcessPtr();
946 if (process == NULL)
947 {
948 result.AppendError ("need a valid process to step");
949 result.SetStatus (eReturnStatusFailed);
950
951 }
952 else
953 {
954 Thread *thread = NULL;
955 uint32_t line_number;
956
957 if (command.GetArgumentCount() != 1)
958 {
959 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
960 result.SetStatus (eReturnStatusFailed);
961 return false;
962 }
963
964 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
965 if (line_number == UINT32_MAX)
966 {
967 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
968 result.SetStatus (eReturnStatusFailed);
969 return false;
970 }
971
972 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
973 {
974 thread = process->GetThreadList().GetSelectedThread().get();
975 }
976 else
977 {
978 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
979 }
980
981 if (thread == NULL)
982 {
983 const uint32_t num_threads = process->GetThreadList().GetSize();
984 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
985 m_options.m_thread_idx,
986 num_threads);
987 result.SetStatus (eReturnStatusFailed);
988 return false;
989 }
990
991 const bool abort_other_plans = false;
992
993 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
994 if (frame == NULL)
995 {
996
997 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
998 m_options.m_frame_idx,
999 m_options.m_thread_idx);
1000 result.SetStatus (eReturnStatusFailed);
1001 return false;
1002 }
1003
1004 ThreadPlanSP new_plan_sp;
1005
1006 if (frame->HasDebugInformation ())
1007 {
1008 // Finally we got here... Translate the given line number to a bunch of addresses:
1009 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1010 LineTable *line_table = NULL;
1011 if (sc.comp_unit)
1012 line_table = sc.comp_unit->GetLineTable();
1013
1014 if (line_table == NULL)
1015 {
1016 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1017 m_options.m_frame_idx, m_options.m_thread_idx);
1018 result.SetStatus (eReturnStatusFailed);
1019 return false;
1020 }
1021
1022 LineEntry function_start;
1023 uint32_t index_ptr = 0, end_ptr;
1024 std::vector<addr_t> address_list;
1025
1026 // Find the beginning & end index of the
1027 AddressRange fun_addr_range = sc.function->GetAddressRange();
1028 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1029 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1030
1031 Address fun_end_addr(fun_start_addr.GetSection(),
1032 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1033 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1034
1035 bool all_in_function = true;
1036
1037 while (index_ptr <= end_ptr)
1038 {
1039 LineEntry line_entry;
1040 const bool exact = false;
1041 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
1042 if (index_ptr == UINT32_MAX)
1043 break;
1044
1045 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1046 if (address != LLDB_INVALID_ADDRESS)
1047 {
1048 if (fun_addr_range.ContainsLoadAddress (address, target))
1049 address_list.push_back (address);
1050 else
1051 all_in_function = false;
1052 }
1053 index_ptr++;
1054 }
1055
1056 if (address_list.size() == 0)
1057 {
1058 if (all_in_function)
1059 result.AppendErrorWithFormat ("No line entries matching until target.\n");
1060 else
1061 result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1062
1063 result.SetStatus (eReturnStatusFailed);
1064 return false;
1065 }
1066
1067 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1068 &address_list.front(),
1069 address_list.size(),
1070 m_options.m_stop_others,
1071 m_options.m_frame_idx);
1072 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1073 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1074 // will resume the original plan.
1075 new_plan_sp->SetIsMasterPlan (true);
1076 new_plan_sp->SetOkayToDiscard(false);
1077 }
1078 else
1079 {
1080 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1081 m_options.m_frame_idx,
1082 m_options.m_thread_idx);
1083 result.SetStatus (eReturnStatusFailed);
1084 return false;
1085
1086 }
1087
1088 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1089 Error error (process->Resume ());
1090 if (error.Success())
1091 {
1092 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
1093 if (synchronous_execution)
1094 {
1095 StateType state = process->WaitForProcessToStop (NULL);
1096
1097 result.SetDidChangeProcessState (true);
1098 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
1099 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1100 }
1101 else
1102 {
1103 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1104 }
1105 }
1106 else
1107 {
1108 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1109 result.SetStatus (eReturnStatusFailed);
1110 }
1111
1112 }
1113 return result.Succeeded();
1114 }
1115
1116 CommandOptions m_options;
1117
1118 };
1119
1120 OptionDefinition
1121 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1122 {
1123 { LLDB_OPT_SET_1, false, "frame", 'f', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
1124 { LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
1125 { LLDB_OPT_SET_1, false, "run-mode",'m', required_argument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
1126 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1127 };
1128
1129
1130 //-------------------------------------------------------------------------
1131 // CommandObjectThreadSelect
1132 //-------------------------------------------------------------------------
1133
1134 class CommandObjectThreadSelect : public CommandObjectParsed
1135 {
1136 public:
1137
CommandObjectThreadSelect(CommandInterpreter & interpreter)1138 CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1139 CommandObjectParsed (interpreter,
1140 "thread select",
1141 "Select a thread as the currently active thread.",
1142 NULL,
1143 eFlagRequiresProcess |
1144 eFlagTryTargetAPILock |
1145 eFlagProcessMustBeLaunched |
1146 eFlagProcessMustBePaused )
1147 {
1148 CommandArgumentEntry arg;
1149 CommandArgumentData thread_idx_arg;
1150
1151 // Define the first (and only) variant of this arg.
1152 thread_idx_arg.arg_type = eArgTypeThreadIndex;
1153 thread_idx_arg.arg_repetition = eArgRepeatPlain;
1154
1155 // There is only one variant this argument could be; put it into the argument entry.
1156 arg.push_back (thread_idx_arg);
1157
1158 // Push the data for the first argument into the m_arguments vector.
1159 m_arguments.push_back (arg);
1160 }
1161
1162
1163 virtual
~CommandObjectThreadSelect()1164 ~CommandObjectThreadSelect ()
1165 {
1166 }
1167
1168 protected:
1169 virtual bool
DoExecute(Args & command,CommandReturnObject & result)1170 DoExecute (Args& command, CommandReturnObject &result)
1171 {
1172 Process *process = m_exe_ctx.GetProcessPtr();
1173 if (process == NULL)
1174 {
1175 result.AppendError ("no process");
1176 result.SetStatus (eReturnStatusFailed);
1177 return false;
1178 }
1179 else if (command.GetArgumentCount() != 1)
1180 {
1181 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1182 result.SetStatus (eReturnStatusFailed);
1183 return false;
1184 }
1185
1186 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1187
1188 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1189 if (new_thread == NULL)
1190 {
1191 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1192 result.SetStatus (eReturnStatusFailed);
1193 return false;
1194 }
1195
1196 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1197 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1198
1199 return result.Succeeded();
1200 }
1201
1202 };
1203
1204
1205 //-------------------------------------------------------------------------
1206 // CommandObjectThreadList
1207 //-------------------------------------------------------------------------
1208
1209 class CommandObjectThreadList : public CommandObjectParsed
1210 {
1211 public:
1212
1213
CommandObjectThreadList(CommandInterpreter & interpreter)1214 CommandObjectThreadList (CommandInterpreter &interpreter):
1215 CommandObjectParsed (interpreter,
1216 "thread list",
1217 "Show a summary of all current threads in a process.",
1218 "thread list",
1219 eFlagRequiresProcess |
1220 eFlagTryTargetAPILock |
1221 eFlagProcessMustBeLaunched |
1222 eFlagProcessMustBePaused )
1223 {
1224 }
1225
~CommandObjectThreadList()1226 ~CommandObjectThreadList()
1227 {
1228 }
1229
1230 protected:
1231 bool
DoExecute(Args & command,CommandReturnObject & result)1232 DoExecute (Args& command, CommandReturnObject &result)
1233 {
1234 Stream &strm = result.GetOutputStream();
1235 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1236 Process *process = m_exe_ctx.GetProcessPtr();
1237 const bool only_threads_with_stop_reason = false;
1238 const uint32_t start_frame = 0;
1239 const uint32_t num_frames = 0;
1240 const uint32_t num_frames_with_source = 0;
1241 process->GetStatus(strm);
1242 process->GetThreadStatus (strm,
1243 only_threads_with_stop_reason,
1244 start_frame,
1245 num_frames,
1246 num_frames_with_source);
1247 return result.Succeeded();
1248 }
1249 };
1250
1251 //-------------------------------------------------------------------------
1252 // CommandObjectThreadReturn
1253 //-------------------------------------------------------------------------
1254
1255 class CommandObjectThreadReturn : public CommandObjectRaw
1256 {
1257 public:
1258 class CommandOptions : public Options
1259 {
1260 public:
1261
CommandOptions(CommandInterpreter & interpreter)1262 CommandOptions (CommandInterpreter &interpreter) :
1263 Options (interpreter),
1264 m_from_expression (false)
1265 {
1266 // Keep default values of all options in one place: OptionParsingStarting ()
1267 OptionParsingStarting ();
1268 }
1269
1270 virtual
~CommandOptions()1271 ~CommandOptions ()
1272 {
1273 }
1274
1275 virtual Error
SetOptionValue(uint32_t option_idx,const char * option_arg)1276 SetOptionValue (uint32_t option_idx, const char *option_arg)
1277 {
1278 Error error;
1279 const int short_option = m_getopt_table[option_idx].val;
1280
1281 switch (short_option)
1282 {
1283 case 'x':
1284 {
1285 bool success;
1286 bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1287 if (success)
1288 m_from_expression = tmp_value;
1289 else
1290 {
1291 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1292 }
1293 }
1294 break;
1295 default:
1296 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1297 break;
1298
1299 }
1300 return error;
1301 }
1302
1303 void
OptionParsingStarting()1304 OptionParsingStarting ()
1305 {
1306 m_from_expression = false;
1307 }
1308
1309 const OptionDefinition*
GetDefinitions()1310 GetDefinitions ()
1311 {
1312 return g_option_table;
1313 }
1314
1315 bool m_from_expression;
1316
1317 // Options table: Required for subclasses of Options.
1318
1319 static OptionDefinition g_option_table[];
1320
1321 // Instance variables to hold the values for command options.
1322 };
1323
1324 virtual
1325 Options *
GetOptions()1326 GetOptions ()
1327 {
1328 return &m_options;
1329 }
1330
CommandObjectThreadReturn(CommandInterpreter & interpreter)1331 CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1332 CommandObjectRaw (interpreter,
1333 "thread return",
1334 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1335 " or with the -x option from the innermost function evaluation.",
1336 "thread return",
1337 eFlagRequiresFrame |
1338 eFlagTryTargetAPILock |
1339 eFlagProcessMustBeLaunched |
1340 eFlagProcessMustBePaused ),
1341 m_options (interpreter)
1342 {
1343 CommandArgumentEntry arg;
1344 CommandArgumentData expression_arg;
1345
1346 // Define the first (and only) variant of this arg.
1347 expression_arg.arg_type = eArgTypeExpression;
1348 expression_arg.arg_repetition = eArgRepeatOptional;
1349
1350 // There is only one variant this argument could be; put it into the argument entry.
1351 arg.push_back (expression_arg);
1352
1353 // Push the data for the first argument into the m_arguments vector.
1354 m_arguments.push_back (arg);
1355
1356
1357 }
1358
~CommandObjectThreadReturn()1359 ~CommandObjectThreadReturn()
1360 {
1361 }
1362
1363 protected:
1364
DoExecute(const char * command,CommandReturnObject & result)1365 bool DoExecute
1366 (
1367 const char *command,
1368 CommandReturnObject &result
1369 )
1370 {
1371 // I am going to handle this by hand, because I don't want you to have to say:
1372 // "thread return -- -5".
1373 if (command[0] == '-' && command[1] == 'x')
1374 {
1375 if (command && command[2] != '\0')
1376 result.AppendWarning("Return values ignored when returning from user called expressions");
1377
1378 Thread *thread = m_exe_ctx.GetThreadPtr();
1379 Error error;
1380 error = thread->UnwindInnermostExpression();
1381 if (!error.Success())
1382 {
1383 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1384 result.SetStatus (eReturnStatusFailed);
1385 }
1386 else
1387 {
1388 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1389 if (success)
1390 {
1391 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1392 result.SetStatus (eReturnStatusSuccessFinishResult);
1393 }
1394 else
1395 {
1396 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1397 result.SetStatus (eReturnStatusFailed);
1398 }
1399 }
1400 return result.Succeeded();
1401 }
1402
1403 ValueObjectSP return_valobj_sp;
1404
1405 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1406 uint32_t frame_idx = frame_sp->GetFrameIndex();
1407
1408 if (frame_sp->IsInlined())
1409 {
1410 result.AppendError("Don't know how to return from inlined frames.");
1411 result.SetStatus (eReturnStatusFailed);
1412 return false;
1413 }
1414
1415 if (command && command[0] != '\0')
1416 {
1417 Target *target = m_exe_ctx.GetTargetPtr();
1418 EvaluateExpressionOptions options;
1419
1420 options.SetUnwindOnError(true);
1421 options.SetUseDynamic(eNoDynamicValues);
1422
1423 ExecutionResults exe_results = eExecutionSetupError;
1424 exe_results = target->EvaluateExpression (command,
1425 frame_sp.get(),
1426 return_valobj_sp,
1427 options);
1428 if (exe_results != eExecutionCompleted)
1429 {
1430 if (return_valobj_sp)
1431 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1432 else
1433 result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1434 result.SetStatus (eReturnStatusFailed);
1435 return false;
1436
1437 }
1438 }
1439
1440 Error error;
1441 ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1442 const bool broadcast = true;
1443 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
1444 if (!error.Success())
1445 {
1446 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1447 result.SetStatus (eReturnStatusFailed);
1448 return false;
1449 }
1450
1451 result.SetStatus (eReturnStatusSuccessFinishResult);
1452 return true;
1453 }
1454
1455 CommandOptions m_options;
1456
1457 };
1458 OptionDefinition
1459 CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1460 {
1461 { LLDB_OPT_SET_ALL, false, "from-expression", 'x', no_argument, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
1462 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1463 };
1464
1465 //-------------------------------------------------------------------------
1466 // CommandObjectMultiwordThread
1467 //-------------------------------------------------------------------------
1468
CommandObjectMultiwordThread(CommandInterpreter & interpreter)1469 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1470 CommandObjectMultiword (interpreter,
1471 "thread",
1472 "A set of commands for operating on one or more threads within a running process.",
1473 "thread <subcommand> [<subcommand-options>]")
1474 {
1475 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1476 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1477 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
1478 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
1479 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1480 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1481 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1482 interpreter,
1483 "thread step-in",
1484 "Source level single step in specified thread (current thread, if none specified).",
1485 NULL,
1486 eStepTypeInto,
1487 eStepScopeSource)));
1488
1489 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1490 interpreter,
1491 "thread step-out",
1492 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
1493 NULL,
1494 eStepTypeOut,
1495 eStepScopeSource)));
1496
1497 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1498 interpreter,
1499 "thread step-over",
1500 "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1501 NULL,
1502 eStepTypeOver,
1503 eStepScopeSource)));
1504
1505 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1506 interpreter,
1507 "thread step-inst",
1508 "Single step one instruction in specified thread (current thread, if none specified).",
1509 NULL,
1510 eStepTypeTrace,
1511 eStepScopeInstruction)));
1512
1513 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1514 interpreter,
1515 "thread step-inst-over",
1516 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1517 NULL,
1518 eStepTypeTraceOver,
1519 eStepScopeInstruction)));
1520 }
1521
~CommandObjectMultiwordThread()1522 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1523 {
1524 }
1525
1526
1527