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/SystemRuntime.h" 32 #include "lldb/Target/Target.h" 33 #include "lldb/Target/Thread.h" 34 #include "lldb/Target/ThreadPlan.h" 35 #include "lldb/Target/ThreadPlanStepInstruction.h" 36 #include "lldb/Target/ThreadPlanStepOut.h" 37 #include "lldb/Target/ThreadPlanStepRange.h" 38 #include "lldb/Target/ThreadPlanStepInRange.h" 39 40 41 using namespace lldb; 42 using namespace lldb_private; 43 44 45 //------------------------------------------------------------------------- 46 // CommandObjectThreadBacktrace 47 //------------------------------------------------------------------------- 48 49 class CommandObjectThreadBacktrace : public CommandObjectParsed 50 { 51 public: 52 53 class CommandOptions : public Options 54 { 55 public: 56 57 CommandOptions (CommandInterpreter &interpreter) : 58 Options(interpreter) 59 { 60 // Keep default values of all options in one place: OptionParsingStarting () 61 OptionParsingStarting (); 62 } 63 64 virtual 65 ~CommandOptions () 66 { 67 } 68 69 virtual Error 70 SetOptionValue (uint32_t option_idx, const char *option_arg) 71 { 72 Error error; 73 const int short_option = m_getopt_table[option_idx].val; 74 75 switch (short_option) 76 { 77 case 'c': 78 { 79 bool success; 80 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success); 81 if (!success) 82 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); 83 if (input_count < -1) 84 m_count = UINT32_MAX; 85 else 86 m_count = input_count; 87 } 88 break; 89 case 's': 90 { 91 bool success; 92 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 93 if (!success) 94 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); 95 } 96 case 'e': 97 { 98 bool success; 99 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success); 100 if (!success) 101 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); 102 } 103 break; 104 default: 105 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 106 break; 107 108 } 109 return error; 110 } 111 112 void 113 OptionParsingStarting () 114 { 115 m_count = UINT32_MAX; 116 m_start = 0; 117 m_extended_backtrace = false; 118 } 119 120 const OptionDefinition* 121 GetDefinitions () 122 { 123 return g_option_table; 124 } 125 126 // Options table: Required for subclasses of Options. 127 128 static OptionDefinition g_option_table[]; 129 130 // Instance variables to hold the values for command options. 131 uint32_t m_count; 132 uint32_t m_start; 133 bool m_extended_backtrace; 134 }; 135 136 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) : 137 CommandObjectParsed (interpreter, 138 "thread backtrace", 139 "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.", 140 NULL, 141 eFlagRequiresProcess | 142 eFlagRequiresThread | 143 eFlagTryTargetAPILock | 144 eFlagProcessMustBeLaunched | 145 eFlagProcessMustBePaused ), 146 m_options(interpreter) 147 { 148 CommandArgumentEntry arg; 149 CommandArgumentData thread_idx_arg; 150 151 // Define the first (and only) variant of this arg. 152 thread_idx_arg.arg_type = eArgTypeThreadIndex; 153 thread_idx_arg.arg_repetition = eArgRepeatStar; 154 155 // There is only one variant this argument could be; put it into the argument entry. 156 arg.push_back (thread_idx_arg); 157 158 // Push the data for the first argument into the m_arguments vector. 159 m_arguments.push_back (arg); 160 } 161 162 ~CommandObjectThreadBacktrace() 163 { 164 } 165 166 virtual Options * 167 GetOptions () 168 { 169 return &m_options; 170 } 171 172 protected: 173 void 174 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result) 175 { 176 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime(); 177 if (runtime) 178 { 179 Stream &strm = result.GetOutputStream(); 180 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes(); 181 for (auto type : types) 182 { 183 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type); 184 if (ext_thread_sp && ext_thread_sp->IsValid ()) 185 { 186 const uint32_t num_frames_with_source = 0; 187 if (ext_thread_sp->GetStatus (strm, 188 m_options.m_start, 189 m_options.m_count, 190 num_frames_with_source)) 191 { 192 DoExtendedBacktrace (ext_thread_sp.get(), result); 193 } 194 } 195 } 196 } 197 } 198 199 virtual bool 200 DoExecute (Args& command, CommandReturnObject &result) 201 { 202 result.SetStatus (eReturnStatusSuccessFinishResult); 203 Stream &strm = result.GetOutputStream(); 204 205 // Don't show source context when doing backtraces. 206 const uint32_t num_frames_with_source = 0; 207 if (command.GetArgumentCount() == 0) 208 { 209 Thread *thread = m_exe_ctx.GetThreadPtr(); 210 // Thread::GetStatus() returns the number of frames shown. 211 if (thread->GetStatus (strm, 212 m_options.m_start, 213 m_options.m_count, 214 num_frames_with_source)) 215 { 216 result.SetStatus (eReturnStatusSuccessFinishResult); 217 if (m_options.m_extended_backtrace) 218 { 219 DoExtendedBacktrace (thread, result); 220 } 221 } 222 } 223 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) 224 { 225 Process *process = m_exe_ctx.GetProcessPtr(); 226 uint32_t idx = 0; 227 for (ThreadSP thread_sp : process->Threads()) 228 { 229 if (idx != 0) 230 result.AppendMessage(""); 231 232 if (!thread_sp->GetStatus (strm, 233 m_options.m_start, 234 m_options.m_count, 235 num_frames_with_source)) 236 { 237 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", idx); 238 result.SetStatus (eReturnStatusFailed); 239 return false; 240 } 241 if (m_options.m_extended_backtrace) 242 { 243 DoExtendedBacktrace (thread_sp.get(), result); 244 } 245 246 ++idx; 247 } 248 } 249 else 250 { 251 const size_t num_args = command.GetArgumentCount(); 252 Process *process = m_exe_ctx.GetProcessPtr(); 253 Mutex::Locker locker (process->GetThreadList().GetMutex()); 254 std::vector<ThreadSP> thread_sps; 255 256 for (size_t i = 0; i < num_args; i++) 257 { 258 bool success; 259 260 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success); 261 if (!success) 262 { 263 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); 264 result.SetStatus (eReturnStatusFailed); 265 return false; 266 } 267 268 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx)); 269 270 if (!thread_sps[i]) 271 { 272 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); 273 result.SetStatus (eReturnStatusFailed); 274 return false; 275 } 276 277 } 278 279 for (uint32_t i = 0; i < num_args; i++) 280 { 281 if (!thread_sps[i]->GetStatus (strm, 282 m_options.m_start, 283 m_options.m_count, 284 num_frames_with_source)) 285 { 286 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i)); 287 result.SetStatus (eReturnStatusFailed); 288 return false; 289 } 290 if (m_options.m_extended_backtrace) 291 { 292 DoExtendedBacktrace (thread_sps[i].get(), result); 293 } 294 295 if (i < num_args - 1) 296 result.AppendMessage(""); 297 } 298 } 299 return result.Succeeded(); 300 } 301 302 CommandOptions m_options; 303 }; 304 305 OptionDefinition 306 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] = 307 { 308 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, 309 { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, 310 { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, 311 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 312 }; 313 314 enum StepScope 315 { 316 eStepScopeSource, 317 eStepScopeInstruction 318 }; 319 320 class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed 321 { 322 public: 323 324 class CommandOptions : public Options 325 { 326 public: 327 328 CommandOptions (CommandInterpreter &interpreter) : 329 Options (interpreter) 330 { 331 // Keep default values of all options in one place: OptionParsingStarting () 332 OptionParsingStarting (); 333 } 334 335 virtual 336 ~CommandOptions () 337 { 338 } 339 340 virtual Error 341 SetOptionValue (uint32_t option_idx, const char *option_arg) 342 { 343 Error error; 344 const int short_option = m_getopt_table[option_idx].val; 345 346 switch (short_option) 347 { 348 case 'a': 349 { 350 bool success; 351 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success); 352 if (!success) 353 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); 354 } 355 break; 356 357 case 'm': 358 { 359 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 360 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 361 } 362 break; 363 364 case 'r': 365 { 366 m_avoid_regexp.clear(); 367 m_avoid_regexp.assign(option_arg); 368 } 369 break; 370 371 case 't': 372 { 373 m_step_in_target.clear(); 374 m_step_in_target.assign(option_arg); 375 376 } 377 break; 378 default: 379 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 380 break; 381 382 } 383 return error; 384 } 385 386 void 387 OptionParsingStarting () 388 { 389 m_avoid_no_debug = true; 390 m_run_mode = eOnlyDuringStepping; 391 m_avoid_regexp.clear(); 392 m_step_in_target.clear(); 393 } 394 395 const OptionDefinition* 396 GetDefinitions () 397 { 398 return g_option_table; 399 } 400 401 // Options table: Required for subclasses of Options. 402 403 static OptionDefinition g_option_table[]; 404 405 // Instance variables to hold the values for command options. 406 bool m_avoid_no_debug; 407 RunMode m_run_mode; 408 std::string m_avoid_regexp; 409 std::string m_step_in_target; 410 }; 411 412 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter, 413 const char *name, 414 const char *help, 415 const char *syntax, 416 StepType step_type, 417 StepScope step_scope) : 418 CommandObjectParsed (interpreter, name, help, syntax, 419 eFlagRequiresProcess | 420 eFlagRequiresThread | 421 eFlagTryTargetAPILock | 422 eFlagProcessMustBeLaunched | 423 eFlagProcessMustBePaused ), 424 m_step_type (step_type), 425 m_step_scope (step_scope), 426 m_options (interpreter) 427 { 428 CommandArgumentEntry arg; 429 CommandArgumentData thread_id_arg; 430 431 // Define the first (and only) variant of this arg. 432 thread_id_arg.arg_type = eArgTypeThreadID; 433 thread_id_arg.arg_repetition = eArgRepeatOptional; 434 435 // There is only one variant this argument could be; put it into the argument entry. 436 arg.push_back (thread_id_arg); 437 438 // Push the data for the first argument into the m_arguments vector. 439 m_arguments.push_back (arg); 440 } 441 442 virtual 443 ~CommandObjectThreadStepWithTypeAndScope () 444 { 445 } 446 447 virtual 448 Options * 449 GetOptions () 450 { 451 return &m_options; 452 } 453 454 protected: 455 virtual bool 456 DoExecute (Args& command, CommandReturnObject &result) 457 { 458 Process *process = m_exe_ctx.GetProcessPtr(); 459 bool synchronous_execution = m_interpreter.GetSynchronous(); 460 461 const uint32_t num_threads = process->GetThreadList().GetSize(); 462 Thread *thread = NULL; 463 464 if (command.GetArgumentCount() == 0) 465 { 466 thread = process->GetThreadList().GetSelectedThread().get(); 467 if (thread == NULL) 468 { 469 result.AppendError ("no selected thread in process"); 470 result.SetStatus (eReturnStatusFailed); 471 return false; 472 } 473 } 474 else 475 { 476 const char *thread_idx_cstr = command.GetArgumentAtIndex(0); 477 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32); 478 if (step_thread_idx == LLDB_INVALID_INDEX32) 479 { 480 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr); 481 result.SetStatus (eReturnStatusFailed); 482 return false; 483 } 484 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get(); 485 if (thread == NULL) 486 { 487 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 488 step_thread_idx, num_threads); 489 result.SetStatus (eReturnStatusFailed); 490 return false; 491 } 492 } 493 494 const bool abort_other_plans = false; 495 const lldb::RunMode stop_other_threads = m_options.m_run_mode; 496 497 // This is a bit unfortunate, but not all the commands in this command object support 498 // only while stepping, so I use the bool for them. 499 bool bool_stop_other_threads; 500 if (m_options.m_run_mode == eAllThreads) 501 bool_stop_other_threads = false; 502 else if (m_options.m_run_mode == eOnlyDuringStepping) 503 { 504 if (m_step_type == eStepTypeOut) 505 bool_stop_other_threads = false; 506 else 507 bool_stop_other_threads = true; 508 } 509 else 510 bool_stop_other_threads = true; 511 512 ThreadPlanSP new_plan_sp; 513 514 if (m_step_type == eStepTypeInto) 515 { 516 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 517 518 if (frame->HasDebugInformation ()) 519 { 520 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 521 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 522 frame->GetSymbolContext(eSymbolContextEverything), 523 m_options.m_step_in_target.c_str(), 524 stop_other_threads, 525 m_options.m_avoid_no_debug); 526 if (new_plan_sp && !m_options.m_avoid_regexp.empty()) 527 { 528 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get()); 529 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); 530 } 531 } 532 else 533 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 534 535 } 536 else if (m_step_type == eStepTypeOver) 537 { 538 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 539 540 if (frame->HasDebugInformation()) 541 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 542 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 543 frame->GetSymbolContext(eSymbolContextEverything), 544 stop_other_threads); 545 else 546 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 547 abort_other_plans, 548 bool_stop_other_threads); 549 550 } 551 else if (m_step_type == eStepTypeTrace) 552 { 553 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 554 } 555 else if (m_step_type == eStepTypeTraceOver) 556 { 557 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); 558 } 559 else if (m_step_type == eStepTypeOut) 560 { 561 new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans, 562 NULL, 563 false, 564 bool_stop_other_threads, 565 eVoteYes, 566 eVoteNoOpinion, 567 thread->GetSelectedFrameIndex()); 568 } 569 else 570 { 571 result.AppendError ("step type is not supported"); 572 result.SetStatus (eReturnStatusFailed); 573 return false; 574 } 575 576 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans 577 // so that they can be interruptible). Then resume the process. 578 579 if (new_plan_sp) 580 { 581 new_plan_sp->SetIsMasterPlan (true); 582 new_plan_sp->SetOkayToDiscard (false); 583 584 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 585 process->Resume (); 586 587 588 if (synchronous_execution) 589 { 590 StateType state = process->WaitForProcessToStop (NULL); 591 592 //EventSP event_sp; 593 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp); 594 //while (! StateIsStoppedState (state)) 595 // { 596 // state = process->WaitForStateChangedEvents (NULL, event_sp); 597 // } 598 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 599 result.SetDidChangeProcessState (true); 600 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 601 result.SetStatus (eReturnStatusSuccessFinishNoResult); 602 } 603 else 604 { 605 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 606 } 607 } 608 else 609 { 610 result.AppendError ("Couldn't find thread plan to implement step type."); 611 result.SetStatus (eReturnStatusFailed); 612 } 613 return result.Succeeded(); 614 } 615 616 protected: 617 StepType m_step_type; 618 StepScope m_step_scope; 619 CommandOptions m_options; 620 }; 621 622 static OptionEnumValueElement 623 g_tri_running_mode[] = 624 { 625 { eOnlyThisThread, "this-thread", "Run only this thread"}, 626 { eAllThreads, "all-threads", "Run all threads"}, 627 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"}, 628 { 0, NULL, NULL } 629 }; 630 631 static OptionEnumValueElement 632 g_duo_running_mode[] = 633 { 634 { eOnlyThisThread, "this-thread", "Run only this thread"}, 635 { eAllThreads, "all-threads", "Run all threads"}, 636 { 0, NULL, NULL } 637 }; 638 639 OptionDefinition 640 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = 641 { 642 { LLDB_OPT_SET_1, false, "avoid-no-debug", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether step-in will step over functions with no debug information."}, 643 { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."}, 644 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."}, 645 { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, 646 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 647 }; 648 649 650 //------------------------------------------------------------------------- 651 // CommandObjectThreadContinue 652 //------------------------------------------------------------------------- 653 654 class CommandObjectThreadContinue : public CommandObjectParsed 655 { 656 public: 657 658 CommandObjectThreadContinue (CommandInterpreter &interpreter) : 659 CommandObjectParsed (interpreter, 660 "thread continue", 661 "Continue execution of one or more threads in an active process.", 662 NULL, 663 eFlagRequiresThread | 664 eFlagTryTargetAPILock | 665 eFlagProcessMustBeLaunched | 666 eFlagProcessMustBePaused) 667 { 668 CommandArgumentEntry arg; 669 CommandArgumentData thread_idx_arg; 670 671 // Define the first (and only) variant of this arg. 672 thread_idx_arg.arg_type = eArgTypeThreadIndex; 673 thread_idx_arg.arg_repetition = eArgRepeatPlus; 674 675 // There is only one variant this argument could be; put it into the argument entry. 676 arg.push_back (thread_idx_arg); 677 678 // Push the data for the first argument into the m_arguments vector. 679 m_arguments.push_back (arg); 680 } 681 682 683 virtual 684 ~CommandObjectThreadContinue () 685 { 686 } 687 688 virtual bool 689 DoExecute (Args& command, CommandReturnObject &result) 690 { 691 bool synchronous_execution = m_interpreter.GetSynchronous (); 692 693 if (!m_interpreter.GetDebugger().GetSelectedTarget().get()) 694 { 695 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 696 result.SetStatus (eReturnStatusFailed); 697 return false; 698 } 699 700 Process *process = m_exe_ctx.GetProcessPtr(); 701 if (process == NULL) 702 { 703 result.AppendError ("no process exists. Cannot continue"); 704 result.SetStatus (eReturnStatusFailed); 705 return false; 706 } 707 708 StateType state = process->GetState(); 709 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended)) 710 { 711 const size_t argc = command.GetArgumentCount(); 712 if (argc > 0) 713 { 714 // These two lines appear at the beginning of both blocks in 715 // this if..else, but that is because we need to release the 716 // lock before calling process->Resume below. 717 Mutex::Locker locker (process->GetThreadList().GetMutex()); 718 const uint32_t num_threads = process->GetThreadList().GetSize(); 719 std::vector<Thread *> resume_threads; 720 for (uint32_t i=0; i<argc; ++i) 721 { 722 bool success; 723 const int base = 0; 724 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success); 725 if (success) 726 { 727 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get(); 728 729 if (thread) 730 { 731 resume_threads.push_back(thread); 732 } 733 else 734 { 735 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx); 736 result.SetStatus (eReturnStatusFailed); 737 return false; 738 } 739 } 740 else 741 { 742 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i)); 743 result.SetStatus (eReturnStatusFailed); 744 return false; 745 } 746 } 747 748 if (resume_threads.empty()) 749 { 750 result.AppendError ("no valid thread indexes were specified"); 751 result.SetStatus (eReturnStatusFailed); 752 return false; 753 } 754 else 755 { 756 if (resume_threads.size() == 1) 757 result.AppendMessageWithFormat ("Resuming thread: "); 758 else 759 result.AppendMessageWithFormat ("Resuming threads: "); 760 761 for (uint32_t idx=0; idx<num_threads; ++idx) 762 { 763 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 764 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread); 765 766 if (this_thread_pos != resume_threads.end()) 767 { 768 resume_threads.erase(this_thread_pos); 769 if (resume_threads.size() > 0) 770 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID()); 771 else 772 result.AppendMessageWithFormat ("%u ", thread->GetIndexID()); 773 774 thread->SetResumeState (eStateRunning); 775 } 776 else 777 { 778 thread->SetResumeState (eStateSuspended); 779 } 780 } 781 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID()); 782 } 783 } 784 else 785 { 786 // These two lines appear at the beginning of both blocks in 787 // this if..else, but that is because we need to release the 788 // lock before calling process->Resume below. 789 Mutex::Locker locker (process->GetThreadList().GetMutex()); 790 const uint32_t num_threads = process->GetThreadList().GetSize(); 791 Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); 792 if (current_thread == NULL) 793 { 794 result.AppendError ("the process doesn't have a current thread"); 795 result.SetStatus (eReturnStatusFailed); 796 return false; 797 } 798 // Set the actions that the threads should each take when resuming 799 for (uint32_t idx=0; idx<num_threads; ++idx) 800 { 801 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 802 if (thread == current_thread) 803 { 804 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID()); 805 thread->SetResumeState (eStateRunning); 806 } 807 else 808 { 809 thread->SetResumeState (eStateSuspended); 810 } 811 } 812 } 813 814 // We should not be holding the thread list lock when we do this. 815 Error error (process->Resume()); 816 if (error.Success()) 817 { 818 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 819 if (synchronous_execution) 820 { 821 state = process->WaitForProcessToStop (NULL); 822 823 result.SetDidChangeProcessState (true); 824 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 825 result.SetStatus (eReturnStatusSuccessFinishNoResult); 826 } 827 else 828 { 829 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 830 } 831 } 832 else 833 { 834 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString()); 835 result.SetStatus (eReturnStatusFailed); 836 } 837 } 838 else 839 { 840 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 841 StateAsCString(state)); 842 result.SetStatus (eReturnStatusFailed); 843 } 844 845 return result.Succeeded(); 846 } 847 848 }; 849 850 //------------------------------------------------------------------------- 851 // CommandObjectThreadUntil 852 //------------------------------------------------------------------------- 853 854 class CommandObjectThreadUntil : public CommandObjectParsed 855 { 856 public: 857 858 class CommandOptions : public Options 859 { 860 public: 861 uint32_t m_thread_idx; 862 uint32_t m_frame_idx; 863 864 CommandOptions (CommandInterpreter &interpreter) : 865 Options (interpreter), 866 m_thread_idx(LLDB_INVALID_THREAD_ID), 867 m_frame_idx(LLDB_INVALID_FRAME_ID) 868 { 869 // Keep default values of all options in one place: OptionParsingStarting () 870 OptionParsingStarting (); 871 } 872 873 virtual 874 ~CommandOptions () 875 { 876 } 877 878 virtual Error 879 SetOptionValue (uint32_t option_idx, const char *option_arg) 880 { 881 Error error; 882 const int short_option = m_getopt_table[option_idx].val; 883 884 switch (short_option) 885 { 886 case 't': 887 { 888 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32); 889 if (m_thread_idx == LLDB_INVALID_INDEX32) 890 { 891 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg); 892 } 893 } 894 break; 895 case 'f': 896 { 897 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID); 898 if (m_frame_idx == LLDB_INVALID_FRAME_ID) 899 { 900 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg); 901 } 902 } 903 break; 904 case 'm': 905 { 906 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 907 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 908 909 if (error.Success()) 910 { 911 if (run_mode == eAllThreads) 912 m_stop_others = false; 913 else 914 m_stop_others = true; 915 } 916 } 917 break; 918 default: 919 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 920 break; 921 922 } 923 return error; 924 } 925 926 void 927 OptionParsingStarting () 928 { 929 m_thread_idx = LLDB_INVALID_THREAD_ID; 930 m_frame_idx = 0; 931 m_stop_others = false; 932 } 933 934 const OptionDefinition* 935 GetDefinitions () 936 { 937 return g_option_table; 938 } 939 940 uint32_t m_step_thread_idx; 941 bool m_stop_others; 942 943 // Options table: Required for subclasses of Options. 944 945 static OptionDefinition g_option_table[]; 946 947 // Instance variables to hold the values for command options. 948 }; 949 950 CommandObjectThreadUntil (CommandInterpreter &interpreter) : 951 CommandObjectParsed (interpreter, 952 "thread until", 953 "Run the current or specified thread until it reaches a given line number or leaves the current function.", 954 NULL, 955 eFlagRequiresThread | 956 eFlagTryTargetAPILock | 957 eFlagProcessMustBeLaunched | 958 eFlagProcessMustBePaused ), 959 m_options (interpreter) 960 { 961 CommandArgumentEntry arg; 962 CommandArgumentData line_num_arg; 963 964 // Define the first (and only) variant of this arg. 965 line_num_arg.arg_type = eArgTypeLineNum; 966 line_num_arg.arg_repetition = eArgRepeatPlain; 967 968 // There is only one variant this argument could be; put it into the argument entry. 969 arg.push_back (line_num_arg); 970 971 // Push the data for the first argument into the m_arguments vector. 972 m_arguments.push_back (arg); 973 } 974 975 976 virtual 977 ~CommandObjectThreadUntil () 978 { 979 } 980 981 virtual 982 Options * 983 GetOptions () 984 { 985 return &m_options; 986 } 987 988 protected: 989 virtual bool 990 DoExecute (Args& command, CommandReturnObject &result) 991 { 992 bool synchronous_execution = m_interpreter.GetSynchronous (); 993 994 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 995 if (target == NULL) 996 { 997 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 998 result.SetStatus (eReturnStatusFailed); 999 return false; 1000 } 1001 1002 Process *process = m_exe_ctx.GetProcessPtr(); 1003 if (process == NULL) 1004 { 1005 result.AppendError ("need a valid process to step"); 1006 result.SetStatus (eReturnStatusFailed); 1007 1008 } 1009 else 1010 { 1011 Thread *thread = NULL; 1012 uint32_t line_number; 1013 1014 if (command.GetArgumentCount() != 1) 1015 { 1016 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax()); 1017 result.SetStatus (eReturnStatusFailed); 1018 return false; 1019 } 1020 1021 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); 1022 if (line_number == UINT32_MAX) 1023 { 1024 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); 1025 result.SetStatus (eReturnStatusFailed); 1026 return false; 1027 } 1028 1029 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) 1030 { 1031 thread = process->GetThreadList().GetSelectedThread().get(); 1032 } 1033 else 1034 { 1035 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get(); 1036 } 1037 1038 if (thread == NULL) 1039 { 1040 const uint32_t num_threads = process->GetThreadList().GetSize(); 1041 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 1042 m_options.m_thread_idx, 1043 num_threads); 1044 result.SetStatus (eReturnStatusFailed); 1045 return false; 1046 } 1047 1048 const bool abort_other_plans = false; 1049 1050 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get(); 1051 if (frame == NULL) 1052 { 1053 1054 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", 1055 m_options.m_frame_idx, 1056 m_options.m_thread_idx); 1057 result.SetStatus (eReturnStatusFailed); 1058 return false; 1059 } 1060 1061 ThreadPlanSP new_plan_sp; 1062 1063 if (frame->HasDebugInformation ()) 1064 { 1065 // Finally we got here... Translate the given line number to a bunch of addresses: 1066 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit)); 1067 LineTable *line_table = NULL; 1068 if (sc.comp_unit) 1069 line_table = sc.comp_unit->GetLineTable(); 1070 1071 if (line_table == NULL) 1072 { 1073 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n", 1074 m_options.m_frame_idx, m_options.m_thread_idx); 1075 result.SetStatus (eReturnStatusFailed); 1076 return false; 1077 } 1078 1079 LineEntry function_start; 1080 uint32_t index_ptr = 0, end_ptr; 1081 std::vector<addr_t> address_list; 1082 1083 // Find the beginning & end index of the 1084 AddressRange fun_addr_range = sc.function->GetAddressRange(); 1085 Address fun_start_addr = fun_addr_range.GetBaseAddress(); 1086 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr); 1087 1088 Address fun_end_addr(fun_start_addr.GetSection(), 1089 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); 1090 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); 1091 1092 bool all_in_function = true; 1093 1094 while (index_ptr <= end_ptr) 1095 { 1096 LineEntry line_entry; 1097 const bool exact = false; 1098 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry); 1099 if (index_ptr == UINT32_MAX) 1100 break; 1101 1102 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); 1103 if (address != LLDB_INVALID_ADDRESS) 1104 { 1105 if (fun_addr_range.ContainsLoadAddress (address, target)) 1106 address_list.push_back (address); 1107 else 1108 all_in_function = false; 1109 } 1110 index_ptr++; 1111 } 1112 1113 if (address_list.size() == 0) 1114 { 1115 if (all_in_function) 1116 result.AppendErrorWithFormat ("No line entries matching until target.\n"); 1117 else 1118 result.AppendErrorWithFormat ("Until target outside of the current function.\n"); 1119 1120 result.SetStatus (eReturnStatusFailed); 1121 return false; 1122 } 1123 1124 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans, 1125 &address_list.front(), 1126 address_list.size(), 1127 m_options.m_stop_others, 1128 m_options.m_frame_idx); 1129 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint) 1130 // and other plans executed by the user (stepping around the breakpoint) and then a "continue" 1131 // will resume the original plan. 1132 new_plan_sp->SetIsMasterPlan (true); 1133 new_plan_sp->SetOkayToDiscard(false); 1134 } 1135 else 1136 { 1137 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", 1138 m_options.m_frame_idx, 1139 m_options.m_thread_idx); 1140 result.SetStatus (eReturnStatusFailed); 1141 return false; 1142 1143 } 1144 1145 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); 1146 Error error (process->Resume ()); 1147 if (error.Success()) 1148 { 1149 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 1150 if (synchronous_execution) 1151 { 1152 StateType state = process->WaitForProcessToStop (NULL); 1153 1154 result.SetDidChangeProcessState (true); 1155 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 1156 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1157 } 1158 else 1159 { 1160 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 1161 } 1162 } 1163 else 1164 { 1165 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 1166 result.SetStatus (eReturnStatusFailed); 1167 } 1168 1169 } 1170 return result.Succeeded(); 1171 } 1172 1173 CommandOptions m_options; 1174 1175 }; 1176 1177 OptionDefinition 1178 CommandObjectThreadUntil::CommandOptions::g_option_table[] = 1179 { 1180 { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, 1181 { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, 1182 { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"}, 1183 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1184 }; 1185 1186 1187 //------------------------------------------------------------------------- 1188 // CommandObjectThreadSelect 1189 //------------------------------------------------------------------------- 1190 1191 class CommandObjectThreadSelect : public CommandObjectParsed 1192 { 1193 public: 1194 1195 CommandObjectThreadSelect (CommandInterpreter &interpreter) : 1196 CommandObjectParsed (interpreter, 1197 "thread select", 1198 "Select a thread as the currently active thread.", 1199 NULL, 1200 eFlagRequiresProcess | 1201 eFlagTryTargetAPILock | 1202 eFlagProcessMustBeLaunched | 1203 eFlagProcessMustBePaused ) 1204 { 1205 CommandArgumentEntry arg; 1206 CommandArgumentData thread_idx_arg; 1207 1208 // Define the first (and only) variant of this arg. 1209 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1210 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1211 1212 // There is only one variant this argument could be; put it into the argument entry. 1213 arg.push_back (thread_idx_arg); 1214 1215 // Push the data for the first argument into the m_arguments vector. 1216 m_arguments.push_back (arg); 1217 } 1218 1219 1220 virtual 1221 ~CommandObjectThreadSelect () 1222 { 1223 } 1224 1225 protected: 1226 virtual bool 1227 DoExecute (Args& command, CommandReturnObject &result) 1228 { 1229 Process *process = m_exe_ctx.GetProcessPtr(); 1230 if (process == NULL) 1231 { 1232 result.AppendError ("no process"); 1233 result.SetStatus (eReturnStatusFailed); 1234 return false; 1235 } 1236 else if (command.GetArgumentCount() != 1) 1237 { 1238 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1239 result.SetStatus (eReturnStatusFailed); 1240 return false; 1241 } 1242 1243 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0); 1244 1245 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); 1246 if (new_thread == NULL) 1247 { 1248 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0)); 1249 result.SetStatus (eReturnStatusFailed); 1250 return false; 1251 } 1252 1253 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true); 1254 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1255 1256 return result.Succeeded(); 1257 } 1258 1259 }; 1260 1261 1262 //------------------------------------------------------------------------- 1263 // CommandObjectThreadList 1264 //------------------------------------------------------------------------- 1265 1266 class CommandObjectThreadList : public CommandObjectParsed 1267 { 1268 public: 1269 1270 1271 CommandObjectThreadList (CommandInterpreter &interpreter): 1272 CommandObjectParsed (interpreter, 1273 "thread list", 1274 "Show a summary of all current threads in a process.", 1275 "thread list", 1276 eFlagRequiresProcess | 1277 eFlagTryTargetAPILock | 1278 eFlagProcessMustBeLaunched | 1279 eFlagProcessMustBePaused ) 1280 { 1281 } 1282 1283 ~CommandObjectThreadList() 1284 { 1285 } 1286 1287 protected: 1288 bool 1289 DoExecute (Args& command, CommandReturnObject &result) 1290 { 1291 Stream &strm = result.GetOutputStream(); 1292 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1293 Process *process = m_exe_ctx.GetProcessPtr(); 1294 const bool only_threads_with_stop_reason = false; 1295 const uint32_t start_frame = 0; 1296 const uint32_t num_frames = 0; 1297 const uint32_t num_frames_with_source = 0; 1298 process->GetStatus(strm); 1299 process->GetThreadStatus (strm, 1300 only_threads_with_stop_reason, 1301 start_frame, 1302 num_frames, 1303 num_frames_with_source); 1304 return result.Succeeded(); 1305 } 1306 }; 1307 1308 //------------------------------------------------------------------------- 1309 // CommandObjectThreadReturn 1310 //------------------------------------------------------------------------- 1311 1312 class CommandObjectThreadReturn : public CommandObjectRaw 1313 { 1314 public: 1315 class CommandOptions : public Options 1316 { 1317 public: 1318 1319 CommandOptions (CommandInterpreter &interpreter) : 1320 Options (interpreter), 1321 m_from_expression (false) 1322 { 1323 // Keep default values of all options in one place: OptionParsingStarting () 1324 OptionParsingStarting (); 1325 } 1326 1327 virtual 1328 ~CommandOptions () 1329 { 1330 } 1331 1332 virtual Error 1333 SetOptionValue (uint32_t option_idx, const char *option_arg) 1334 { 1335 Error error; 1336 const int short_option = m_getopt_table[option_idx].val; 1337 1338 switch (short_option) 1339 { 1340 case 'x': 1341 { 1342 bool success; 1343 bool tmp_value = Args::StringToBoolean (option_arg, false, &success); 1344 if (success) 1345 m_from_expression = tmp_value; 1346 else 1347 { 1348 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg); 1349 } 1350 } 1351 break; 1352 default: 1353 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1354 break; 1355 1356 } 1357 return error; 1358 } 1359 1360 void 1361 OptionParsingStarting () 1362 { 1363 m_from_expression = false; 1364 } 1365 1366 const OptionDefinition* 1367 GetDefinitions () 1368 { 1369 return g_option_table; 1370 } 1371 1372 bool m_from_expression; 1373 1374 // Options table: Required for subclasses of Options. 1375 1376 static OptionDefinition g_option_table[]; 1377 1378 // Instance variables to hold the values for command options. 1379 }; 1380 1381 virtual 1382 Options * 1383 GetOptions () 1384 { 1385 return &m_options; 1386 } 1387 1388 CommandObjectThreadReturn (CommandInterpreter &interpreter) : 1389 CommandObjectRaw (interpreter, 1390 "thread return", 1391 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value," 1392 " or with the -x option from the innermost function evaluation.", 1393 "thread return", 1394 eFlagRequiresFrame | 1395 eFlagTryTargetAPILock | 1396 eFlagProcessMustBeLaunched | 1397 eFlagProcessMustBePaused ), 1398 m_options (interpreter) 1399 { 1400 CommandArgumentEntry arg; 1401 CommandArgumentData expression_arg; 1402 1403 // Define the first (and only) variant of this arg. 1404 expression_arg.arg_type = eArgTypeExpression; 1405 expression_arg.arg_repetition = eArgRepeatOptional; 1406 1407 // There is only one variant this argument could be; put it into the argument entry. 1408 arg.push_back (expression_arg); 1409 1410 // Push the data for the first argument into the m_arguments vector. 1411 m_arguments.push_back (arg); 1412 1413 1414 } 1415 1416 ~CommandObjectThreadReturn() 1417 { 1418 } 1419 1420 protected: 1421 1422 bool DoExecute 1423 ( 1424 const char *command, 1425 CommandReturnObject &result 1426 ) 1427 { 1428 // I am going to handle this by hand, because I don't want you to have to say: 1429 // "thread return -- -5". 1430 if (command[0] == '-' && command[1] == 'x') 1431 { 1432 if (command && command[2] != '\0') 1433 result.AppendWarning("Return values ignored when returning from user called expressions"); 1434 1435 Thread *thread = m_exe_ctx.GetThreadPtr(); 1436 Error error; 1437 error = thread->UnwindInnermostExpression(); 1438 if (!error.Success()) 1439 { 1440 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString()); 1441 result.SetStatus (eReturnStatusFailed); 1442 } 1443 else 1444 { 1445 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream()); 1446 if (success) 1447 { 1448 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ()); 1449 result.SetStatus (eReturnStatusSuccessFinishResult); 1450 } 1451 else 1452 { 1453 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression."); 1454 result.SetStatus (eReturnStatusFailed); 1455 } 1456 } 1457 return result.Succeeded(); 1458 } 1459 1460 ValueObjectSP return_valobj_sp; 1461 1462 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP(); 1463 uint32_t frame_idx = frame_sp->GetFrameIndex(); 1464 1465 if (frame_sp->IsInlined()) 1466 { 1467 result.AppendError("Don't know how to return from inlined frames."); 1468 result.SetStatus (eReturnStatusFailed); 1469 return false; 1470 } 1471 1472 if (command && command[0] != '\0') 1473 { 1474 Target *target = m_exe_ctx.GetTargetPtr(); 1475 EvaluateExpressionOptions options; 1476 1477 options.SetUnwindOnError(true); 1478 options.SetUseDynamic(eNoDynamicValues); 1479 1480 ExecutionResults exe_results = eExecutionSetupError; 1481 exe_results = target->EvaluateExpression (command, 1482 frame_sp.get(), 1483 return_valobj_sp, 1484 options); 1485 if (exe_results != eExecutionCompleted) 1486 { 1487 if (return_valobj_sp) 1488 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString()); 1489 else 1490 result.AppendErrorWithFormat("Unknown error evaluating result expression."); 1491 result.SetStatus (eReturnStatusFailed); 1492 return false; 1493 1494 } 1495 } 1496 1497 Error error; 1498 ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); 1499 const bool broadcast = true; 1500 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast); 1501 if (!error.Success()) 1502 { 1503 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString()); 1504 result.SetStatus (eReturnStatusFailed); 1505 return false; 1506 } 1507 1508 result.SetStatus (eReturnStatusSuccessFinishResult); 1509 return true; 1510 } 1511 1512 CommandOptions m_options; 1513 1514 }; 1515 OptionDefinition 1516 CommandObjectThreadReturn::CommandOptions::g_option_table[] = 1517 { 1518 { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."}, 1519 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1520 }; 1521 1522 //------------------------------------------------------------------------- 1523 // CommandObjectThreadJump 1524 //------------------------------------------------------------------------- 1525 1526 class CommandObjectThreadJump : public CommandObjectParsed 1527 { 1528 public: 1529 class CommandOptions : public Options 1530 { 1531 public: 1532 1533 CommandOptions (CommandInterpreter &interpreter) : 1534 Options (interpreter) 1535 { 1536 OptionParsingStarting (); 1537 } 1538 1539 void 1540 OptionParsingStarting () 1541 { 1542 m_filenames.Clear(); 1543 m_line_num = 0; 1544 m_line_offset = 0; 1545 m_load_addr = LLDB_INVALID_ADDRESS; 1546 m_force = false; 1547 } 1548 1549 virtual 1550 ~CommandOptions () 1551 { 1552 } 1553 1554 virtual Error 1555 SetOptionValue (uint32_t option_idx, const char *option_arg) 1556 { 1557 bool success; 1558 const int short_option = m_getopt_table[option_idx].val; 1559 Error error; 1560 1561 switch (short_option) 1562 { 1563 case 'f': 1564 m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 1565 if (m_filenames.GetSize() > 1) 1566 return Error("only one source file expected."); 1567 break; 1568 case 'l': 1569 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success); 1570 if (!success || m_line_num == 0) 1571 return Error("invalid line number: '%s'.", option_arg); 1572 break; 1573 case 'b': 1574 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success); 1575 if (!success) 1576 return Error("invalid line offset: '%s'.", option_arg); 1577 break; 1578 case 'a': 1579 { 1580 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 1581 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 1582 } 1583 break; 1584 case 'r': 1585 m_force = true; 1586 break; 1587 1588 default: 1589 return Error("invalid short option character '%c'", short_option); 1590 1591 } 1592 return error; 1593 } 1594 1595 const OptionDefinition* 1596 GetDefinitions () 1597 { 1598 return g_option_table; 1599 } 1600 1601 FileSpecList m_filenames; 1602 uint32_t m_line_num; 1603 int32_t m_line_offset; 1604 lldb::addr_t m_load_addr; 1605 bool m_force; 1606 1607 static OptionDefinition g_option_table[]; 1608 }; 1609 1610 virtual 1611 Options * 1612 GetOptions () 1613 { 1614 return &m_options; 1615 } 1616 1617 CommandObjectThreadJump (CommandInterpreter &interpreter) : 1618 CommandObjectParsed (interpreter, 1619 "thread jump", 1620 "Sets the program counter to a new address.", 1621 "thread jump", 1622 eFlagRequiresFrame | 1623 eFlagTryTargetAPILock | 1624 eFlagProcessMustBeLaunched | 1625 eFlagProcessMustBePaused ), 1626 m_options (interpreter) 1627 { 1628 } 1629 1630 ~CommandObjectThreadJump() 1631 { 1632 } 1633 1634 protected: 1635 1636 bool DoExecute (Args& args, CommandReturnObject &result) 1637 { 1638 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext(); 1639 StackFrame *frame = m_exe_ctx.GetFramePtr(); 1640 Thread *thread = m_exe_ctx.GetThreadPtr(); 1641 Target *target = m_exe_ctx.GetTargetPtr(); 1642 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry); 1643 1644 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 1645 { 1646 // Use this address directly. 1647 Address dest = Address(m_options.m_load_addr); 1648 1649 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target); 1650 if (callAddr == LLDB_INVALID_ADDRESS) 1651 { 1652 result.AppendErrorWithFormat ("Invalid destination address."); 1653 result.SetStatus (eReturnStatusFailed); 1654 return false; 1655 } 1656 1657 if (!reg_ctx->SetPC (callAddr)) 1658 { 1659 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID()); 1660 result.SetStatus (eReturnStatusFailed); 1661 return false; 1662 } 1663 } 1664 else 1665 { 1666 // Pick either the absolute line, or work out a relative one. 1667 int32_t line = (int32_t)m_options.m_line_num; 1668 if (line == 0) 1669 line = sym_ctx.line_entry.line + m_options.m_line_offset; 1670 1671 // Try the current file, but override if asked. 1672 FileSpec file = sym_ctx.line_entry.file; 1673 if (m_options.m_filenames.GetSize() == 1) 1674 file = m_options.m_filenames.GetFileSpecAtIndex(0); 1675 1676 if (!file) 1677 { 1678 result.AppendErrorWithFormat ("No source file available for the current location."); 1679 result.SetStatus (eReturnStatusFailed); 1680 return false; 1681 } 1682 1683 std::string warnings; 1684 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings); 1685 1686 if (err.Fail()) 1687 { 1688 result.SetError (err); 1689 return false; 1690 } 1691 1692 if (!warnings.empty()) 1693 result.AppendWarning (warnings.c_str()); 1694 } 1695 1696 result.SetStatus (eReturnStatusSuccessFinishResult); 1697 return true; 1698 } 1699 1700 CommandOptions m_options; 1701 }; 1702 OptionDefinition 1703 CommandObjectThreadJump::CommandOptions::g_option_table[] = 1704 { 1705 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 1706 "Specifies the source file to jump to."}, 1707 1708 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, 1709 "Specifies the line number to jump to."}, 1710 1711 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, 1712 "Jumps by a relative line offset from the current line."}, 1713 1714 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, 1715 "Jumps to a specific address."}, 1716 1717 { LLDB_OPT_SET_1| 1718 LLDB_OPT_SET_2| 1719 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."}, 1720 1721 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1722 }; 1723 1724 //------------------------------------------------------------------------- 1725 // CommandObjectMultiwordThread 1726 //------------------------------------------------------------------------- 1727 1728 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : 1729 CommandObjectMultiword (interpreter, 1730 "thread", 1731 "A set of commands for operating on one or more threads within a running process.", 1732 "thread <subcommand> [<subcommand-options>]") 1733 { 1734 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); 1735 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); 1736 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter))); 1737 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter))); 1738 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter))); 1739 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); 1740 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); 1741 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1742 interpreter, 1743 "thread step-in", 1744 "Source level single step in specified thread (current thread, if none specified).", 1745 NULL, 1746 eStepTypeInto, 1747 eStepScopeSource))); 1748 1749 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1750 interpreter, 1751 "thread step-out", 1752 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).", 1753 NULL, 1754 eStepTypeOut, 1755 eStepScopeSource))); 1756 1757 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1758 interpreter, 1759 "thread step-over", 1760 "Source level single step in specified thread (current thread, if none specified), stepping over calls.", 1761 NULL, 1762 eStepTypeOver, 1763 eStepScopeSource))); 1764 1765 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1766 interpreter, 1767 "thread step-inst", 1768 "Single step one instruction in specified thread (current thread, if none specified).", 1769 NULL, 1770 eStepTypeTrace, 1771 eStepScopeInstruction))); 1772 1773 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1774 interpreter, 1775 "thread step-inst-over", 1776 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", 1777 NULL, 1778 eStepTypeTraceOver, 1779 eStepScopeInstruction))); 1780 } 1781 1782 CommandObjectMultiwordThread::~CommandObjectMultiwordThread () 1783 { 1784 } 1785 1786 1787