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 "CommandObjectThread.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Interpreter/Options.h" 17 #include "lldb/Core/State.h" 18 #include "lldb/Core/SourceManager.h" 19 20 #include "lldb/Host/Host.h" 21 22 #include "lldb/Interpreter/CommandInterpreter.h" 23 #include "lldb/Interpreter/CommandReturnObject.h" 24 25 #include "lldb/Target/Process.h" 26 #include "lldb/Target/RegisterContext.h" 27 #include "lldb/Target/Target.h" 28 #include "lldb/Target/Thread.h" 29 #include "lldb/Target/ThreadPlan.h" 30 #include "lldb/Target/ThreadPlanStepInstruction.h" 31 #include "lldb/Target/ThreadPlanStepOut.h" 32 #include "lldb/Target/ThreadPlanStepRange.h" 33 #include "lldb/Target/ThreadPlanStepInRange.h" 34 #include "lldb/Symbol/LineTable.h" 35 #include "lldb/Symbol/LineEntry.h" 36 37 using namespace lldb; 38 using namespace lldb_private; 39 40 41 //------------------------------------------------------------------------- 42 // CommandObjectThreadBacktrace 43 //------------------------------------------------------------------------- 44 45 class CommandObjectThreadBacktrace : public CommandObject 46 { 47 public: 48 49 class CommandOptions : public Options 50 { 51 public: 52 53 CommandOptions (CommandInterpreter &interpreter) : 54 Options(interpreter) 55 { 56 // Keep default values of all options in one place: OptionParsingStarting () 57 OptionParsingStarting (); 58 } 59 60 virtual 61 ~CommandOptions () 62 { 63 } 64 65 virtual Error 66 SetOptionValue (uint32_t option_idx, const char *option_arg) 67 { 68 Error error; 69 char short_option = (char) m_getopt_table[option_idx].val; 70 71 switch (short_option) 72 { 73 case 'c': 74 { 75 bool success; 76 int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success); 77 if (!success) 78 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); 79 if (input_count < -1) 80 m_count = UINT32_MAX; 81 else 82 m_count = input_count; 83 } 84 break; 85 case 's': 86 { 87 bool success; 88 m_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 89 if (!success) 90 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); 91 } 92 break; 93 default: 94 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 95 break; 96 97 } 98 return error; 99 } 100 101 void 102 OptionParsingStarting () 103 { 104 m_count = UINT32_MAX; 105 m_start = 0; 106 } 107 108 const OptionDefinition* 109 GetDefinitions () 110 { 111 return g_option_table; 112 } 113 114 // Options table: Required for subclasses of Options. 115 116 static OptionDefinition g_option_table[]; 117 118 // Instance variables to hold the values for command options. 119 uint32_t m_count; 120 uint32_t m_start; 121 }; 122 123 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) : 124 CommandObject (interpreter, 125 "thread backtrace", 126 "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.", 127 NULL, 128 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 129 m_options(interpreter) 130 { 131 CommandArgumentEntry arg; 132 CommandArgumentData thread_idx_arg; 133 134 // Define the first (and only) variant of this arg. 135 thread_idx_arg.arg_type = eArgTypeThreadIndex; 136 thread_idx_arg.arg_repetition = eArgRepeatStar; 137 138 // There is only one variant this argument could be; put it into the argument entry. 139 arg.push_back (thread_idx_arg); 140 141 // Push the data for the first argument into the m_arguments vector. 142 m_arguments.push_back (arg); 143 } 144 145 ~CommandObjectThreadBacktrace() 146 { 147 } 148 149 virtual Options * 150 GetOptions () 151 { 152 return &m_options; 153 } 154 155 virtual bool 156 Execute (Args& command, CommandReturnObject &result) 157 { 158 result.SetStatus (eReturnStatusSuccessFinishResult); 159 Stream &strm = result.GetOutputStream(); 160 161 // Don't show source context when doing backtraces. 162 const uint32_t num_frames_with_source = 0; 163 if (command.GetArgumentCount() == 0) 164 { 165 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 166 Thread *thread = exe_ctx.GetThreadPtr(); 167 if (thread) 168 { 169 // Thread::GetStatus() returns the number of frames shown. 170 if (thread->GetStatus (strm, 171 m_options.m_start, 172 m_options.m_count, 173 num_frames_with_source)) 174 { 175 result.SetStatus (eReturnStatusSuccessFinishResult); 176 } 177 } 178 else 179 { 180 result.AppendError ("invalid thread"); 181 result.SetStatus (eReturnStatusFailed); 182 } 183 } 184 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) 185 { 186 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 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 uint32_t num_args = command.GetArgumentCount(); 209 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 210 std::vector<ThreadSP> thread_sps; 211 212 for (uint32_t i = 0; i < num_args; i++) 213 { 214 bool success; 215 216 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success); 217 if (!success) 218 { 219 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); 220 result.SetStatus (eReturnStatusFailed); 221 return false; 222 } 223 224 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx)); 225 226 if (!thread_sps[i]) 227 { 228 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); 229 result.SetStatus (eReturnStatusFailed); 230 return false; 231 } 232 233 } 234 235 for (uint32_t i = 0; i < num_args; i++) 236 { 237 if (!thread_sps[i]->GetStatus (strm, 238 m_options.m_start, 239 m_options.m_count, 240 num_frames_with_source)) 241 { 242 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i)); 243 result.SetStatus (eReturnStatusFailed); 244 return false; 245 } 246 247 if (i < num_args - 1) 248 result.AppendMessage(""); 249 } 250 } 251 return result.Succeeded(); 252 } 253 protected: 254 CommandOptions m_options; 255 }; 256 257 OptionDefinition 258 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] = 259 { 260 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, 261 { LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, 262 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 263 }; 264 265 enum StepScope 266 { 267 eStepScopeSource, 268 eStepScopeInstruction 269 }; 270 271 class CommandObjectThreadStepWithTypeAndScope : public CommandObject 272 { 273 public: 274 275 class CommandOptions : public Options 276 { 277 public: 278 279 CommandOptions (CommandInterpreter &interpreter) : 280 Options (interpreter) 281 { 282 // Keep default values of all options in one place: OptionParsingStarting () 283 OptionParsingStarting (); 284 } 285 286 virtual 287 ~CommandOptions () 288 { 289 } 290 291 virtual Error 292 SetOptionValue (uint32_t option_idx, const char *option_arg) 293 { 294 Error error; 295 char short_option = (char) m_getopt_table[option_idx].val; 296 297 switch (short_option) 298 { 299 case 'a': 300 { 301 bool success; 302 m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success); 303 if (!success) 304 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); 305 } 306 break; 307 308 case 'm': 309 { 310 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 311 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 312 } 313 break; 314 315 case 'r': 316 { 317 m_avoid_regexp.clear(); 318 m_avoid_regexp.assign(option_arg); 319 } 320 break; 321 322 default: 323 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 324 break; 325 326 } 327 return error; 328 } 329 330 void 331 OptionParsingStarting () 332 { 333 m_avoid_no_debug = true; 334 m_run_mode = eOnlyDuringStepping; 335 m_avoid_regexp.clear(); 336 } 337 338 const OptionDefinition* 339 GetDefinitions () 340 { 341 return g_option_table; 342 } 343 344 // Options table: Required for subclasses of Options. 345 346 static OptionDefinition g_option_table[]; 347 348 // Instance variables to hold the values for command options. 349 bool m_avoid_no_debug; 350 RunMode m_run_mode; 351 std::string m_avoid_regexp; 352 }; 353 354 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter, 355 const char *name, 356 const char *help, 357 const char *syntax, 358 uint32_t flags, 359 StepType step_type, 360 StepScope step_scope) : 361 CommandObject (interpreter, name, help, syntax, flags), 362 m_step_type (step_type), 363 m_step_scope (step_scope), 364 m_options (interpreter) 365 { 366 CommandArgumentEntry arg; 367 CommandArgumentData thread_id_arg; 368 369 // Define the first (and only) variant of this arg. 370 thread_id_arg.arg_type = eArgTypeThreadID; 371 thread_id_arg.arg_repetition = eArgRepeatOptional; 372 373 // There is only one variant this argument could be; put it into the argument entry. 374 arg.push_back (thread_id_arg); 375 376 // Push the data for the first argument into the m_arguments vector. 377 m_arguments.push_back (arg); 378 } 379 380 virtual 381 ~CommandObjectThreadStepWithTypeAndScope () 382 { 383 } 384 385 virtual 386 Options * 387 GetOptions () 388 { 389 return &m_options; 390 } 391 392 virtual bool 393 Execute 394 ( 395 Args& command, 396 CommandReturnObject &result 397 ) 398 { 399 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 400 bool synchronous_execution = m_interpreter.GetSynchronous(); 401 402 if (process == NULL) 403 { 404 result.AppendError ("need a valid process to step"); 405 result.SetStatus (eReturnStatusFailed); 406 407 } 408 else 409 { 410 const uint32_t num_threads = process->GetThreadList().GetSize(); 411 Thread *thread = NULL; 412 413 if (command.GetArgumentCount() == 0) 414 { 415 thread = process->GetThreadList().GetSelectedThread().get(); 416 if (thread == NULL) 417 { 418 result.AppendError ("no selected thread in process"); 419 result.SetStatus (eReturnStatusFailed); 420 return false; 421 } 422 } 423 else 424 { 425 const char *thread_idx_cstr = command.GetArgumentAtIndex(0); 426 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32); 427 if (step_thread_idx == LLDB_INVALID_INDEX32) 428 { 429 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr); 430 result.SetStatus (eReturnStatusFailed); 431 return false; 432 } 433 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get(); 434 if (thread == NULL) 435 { 436 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 437 step_thread_idx, num_threads); 438 result.SetStatus (eReturnStatusFailed); 439 return false; 440 } 441 } 442 443 const bool abort_other_plans = false; 444 const lldb::RunMode stop_other_threads = m_options.m_run_mode; 445 446 // This is a bit unfortunate, but not all the commands in this command object support 447 // only while stepping, so I use the bool for them. 448 bool bool_stop_other_threads; 449 if (m_options.m_run_mode == eAllThreads) 450 bool_stop_other_threads = false; 451 else 452 bool_stop_other_threads = true; 453 454 ThreadPlan *new_plan = NULL; 455 456 if (m_step_type == eStepTypeInto) 457 { 458 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 459 460 if (frame->HasDebugInformation ()) 461 { 462 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type, 463 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 464 frame->GetSymbolContext(eSymbolContextEverything), 465 stop_other_threads, 466 m_options.m_avoid_no_debug); 467 if (new_plan && !m_options.m_avoid_regexp.empty()) 468 { 469 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan); 470 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); 471 } 472 } 473 else 474 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 475 476 } 477 else if (m_step_type == eStepTypeOver) 478 { 479 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 480 481 if (frame->HasDebugInformation()) 482 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, 483 m_step_type, 484 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 485 frame->GetSymbolContext(eSymbolContextEverything), 486 stop_other_threads, 487 false); 488 else 489 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, 490 abort_other_plans, 491 bool_stop_other_threads); 492 493 } 494 else if (m_step_type == eStepTypeTrace) 495 { 496 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 497 } 498 else if (m_step_type == eStepTypeTraceOver) 499 { 500 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); 501 } 502 else if (m_step_type == eStepTypeOut) 503 { 504 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, 505 NULL, 506 false, 507 bool_stop_other_threads, 508 eVoteYes, 509 eVoteNoOpinion, 510 thread->GetSelectedFrameIndex()); 511 } 512 else 513 { 514 result.AppendError ("step type is not supported"); 515 result.SetStatus (eReturnStatusFailed); 516 return false; 517 } 518 519 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans 520 // so that they can be interruptible). Then resume the process. 521 522 if (new_plan != NULL) 523 { 524 new_plan->SetIsMasterPlan (true); 525 new_plan->SetOkayToDiscard (false); 526 527 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 528 process->Resume (); 529 530 531 if (synchronous_execution) 532 { 533 StateType state = process->WaitForProcessToStop (NULL); 534 535 //EventSP event_sp; 536 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp); 537 //while (! StateIsStoppedState (state)) 538 // { 539 // state = process->WaitForStateChangedEvents (NULL, event_sp); 540 // } 541 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 542 result.SetDidChangeProcessState (true); 543 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 544 result.SetStatus (eReturnStatusSuccessFinishNoResult); 545 } 546 else 547 { 548 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 549 } 550 } 551 else 552 { 553 result.AppendError ("Couldn't find thread plan to implement step type."); 554 result.SetStatus (eReturnStatusFailed); 555 } 556 } 557 return result.Succeeded(); 558 } 559 560 protected: 561 StepType m_step_type; 562 StepScope m_step_scope; 563 CommandOptions m_options; 564 }; 565 566 static OptionEnumValueElement 567 g_tri_running_mode[] = 568 { 569 { eOnlyThisThread, "this-thread", "Run only this thread"}, 570 { eAllThreads, "all-threads", "Run all threads"}, 571 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"}, 572 { 0, NULL, NULL } 573 }; 574 575 static OptionEnumValueElement 576 g_duo_running_mode[] = 577 { 578 { eOnlyThisThread, "this-thread", "Run only this thread"}, 579 { eAllThreads, "all-threads", "Run all threads"}, 580 { 0, NULL, NULL } 581 }; 582 583 OptionDefinition 584 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = 585 { 586 { 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."}, 587 { 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."}, 588 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."}, 589 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 590 }; 591 592 593 //------------------------------------------------------------------------- 594 // CommandObjectThreadContinue 595 //------------------------------------------------------------------------- 596 597 class CommandObjectThreadContinue : public CommandObject 598 { 599 public: 600 601 CommandObjectThreadContinue (CommandInterpreter &interpreter) : 602 CommandObject (interpreter, 603 "thread continue", 604 "Continue execution of one or more threads in an active process.", 605 NULL, 606 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 607 { 608 CommandArgumentEntry arg; 609 CommandArgumentData thread_idx_arg; 610 611 // Define the first (and only) variant of this arg. 612 thread_idx_arg.arg_type = eArgTypeThreadIndex; 613 thread_idx_arg.arg_repetition = eArgRepeatPlus; 614 615 // There is only one variant this argument could be; put it into the argument entry. 616 arg.push_back (thread_idx_arg); 617 618 // Push the data for the first argument into the m_arguments vector. 619 m_arguments.push_back (arg); 620 } 621 622 623 virtual 624 ~CommandObjectThreadContinue () 625 { 626 } 627 628 virtual bool 629 Execute 630 ( 631 Args& command, 632 CommandReturnObject &result 633 ) 634 { 635 bool synchronous_execution = m_interpreter.GetSynchronous (); 636 637 if (!m_interpreter.GetDebugger().GetSelectedTarget().get()) 638 { 639 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 640 result.SetStatus (eReturnStatusFailed); 641 return false; 642 } 643 644 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 645 if (process == NULL) 646 { 647 result.AppendError ("no process exists. Cannot continue"); 648 result.SetStatus (eReturnStatusFailed); 649 return false; 650 } 651 652 StateType state = process->GetState(); 653 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended)) 654 { 655 const uint32_t num_threads = process->GetThreadList().GetSize(); 656 uint32_t idx; 657 const size_t argc = command.GetArgumentCount(); 658 if (argc > 0) 659 { 660 std::vector<uint32_t> resume_thread_indexes; 661 for (uint32_t i=0; i<argc; ++i) 662 { 663 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32); 664 if (idx < num_threads) 665 resume_thread_indexes.push_back(idx); 666 else 667 result.AppendWarningWithFormat("Thread index %u out of range.\n", idx); 668 } 669 670 if (resume_thread_indexes.empty()) 671 { 672 result.AppendError ("no valid thread indexes were specified"); 673 result.SetStatus (eReturnStatusFailed); 674 return false; 675 } 676 else 677 { 678 result.AppendMessage ("Resuming thread "); 679 for (idx=0; idx<num_threads; ++idx) 680 { 681 Thread *thread = process->GetThreadList().FindThreadByIndexID(idx).get(); 682 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end()) 683 { 684 result.AppendMessageWithFormat ("%u ", idx); 685 thread->SetResumeState (eStateRunning); 686 } 687 else 688 { 689 thread->SetResumeState (eStateSuspended); 690 } 691 } 692 result.AppendMessageWithFormat ("in process %llu\n", process->GetID()); 693 } 694 } 695 else 696 { 697 Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); 698 if (current_thread == NULL) 699 { 700 result.AppendError ("the process doesn't have a current thread"); 701 result.SetStatus (eReturnStatusFailed); 702 return false; 703 } 704 // Set the actions that the threads should each take when resuming 705 for (idx=0; idx<num_threads; ++idx) 706 { 707 Thread *thread = process->GetThreadList().FindThreadByIndexID(idx).get(); 708 if (thread == current_thread) 709 { 710 result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID()); 711 thread->SetResumeState (eStateRunning); 712 } 713 else 714 { 715 thread->SetResumeState (eStateSuspended); 716 } 717 } 718 } 719 720 Error error (process->Resume()); 721 if (error.Success()) 722 { 723 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID()); 724 if (synchronous_execution) 725 { 726 state = process->WaitForProcessToStop (NULL); 727 728 result.SetDidChangeProcessState (true); 729 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 730 result.SetStatus (eReturnStatusSuccessFinishNoResult); 731 } 732 else 733 { 734 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 735 } 736 } 737 else 738 { 739 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString()); 740 result.SetStatus (eReturnStatusFailed); 741 } 742 } 743 else 744 { 745 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 746 StateAsCString(state)); 747 result.SetStatus (eReturnStatusFailed); 748 } 749 750 return result.Succeeded(); 751 } 752 753 }; 754 755 //------------------------------------------------------------------------- 756 // CommandObjectThreadUntil 757 //------------------------------------------------------------------------- 758 759 class CommandObjectThreadUntil : public CommandObject 760 { 761 public: 762 763 class CommandOptions : public Options 764 { 765 public: 766 uint32_t m_thread_idx; 767 uint32_t m_frame_idx; 768 769 CommandOptions (CommandInterpreter &interpreter) : 770 Options (interpreter), 771 m_thread_idx(LLDB_INVALID_THREAD_ID), 772 m_frame_idx(LLDB_INVALID_FRAME_ID) 773 { 774 // Keep default values of all options in one place: OptionParsingStarting () 775 OptionParsingStarting (); 776 } 777 778 virtual 779 ~CommandOptions () 780 { 781 } 782 783 virtual Error 784 SetOptionValue (uint32_t option_idx, const char *option_arg) 785 { 786 Error error; 787 char short_option = (char) m_getopt_table[option_idx].val; 788 789 switch (short_option) 790 { 791 case 't': 792 { 793 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32); 794 if (m_thread_idx == LLDB_INVALID_INDEX32) 795 { 796 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg); 797 } 798 } 799 break; 800 case 'f': 801 { 802 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID); 803 if (m_frame_idx == LLDB_INVALID_FRAME_ID) 804 { 805 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg); 806 } 807 } 808 break; 809 case 'm': 810 { 811 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 812 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 813 814 if (error.Success()) 815 { 816 if (run_mode == eAllThreads) 817 m_stop_others = false; 818 else 819 m_stop_others = true; 820 } 821 } 822 break; 823 default: 824 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 825 break; 826 827 } 828 return error; 829 } 830 831 void 832 OptionParsingStarting () 833 { 834 m_thread_idx = LLDB_INVALID_THREAD_ID; 835 m_frame_idx = 0; 836 m_stop_others = false; 837 } 838 839 const OptionDefinition* 840 GetDefinitions () 841 { 842 return g_option_table; 843 } 844 845 uint32_t m_step_thread_idx; 846 bool m_stop_others; 847 848 // Options table: Required for subclasses of Options. 849 850 static OptionDefinition g_option_table[]; 851 852 // Instance variables to hold the values for command options. 853 }; 854 855 CommandObjectThreadUntil (CommandInterpreter &interpreter) : 856 CommandObject (interpreter, 857 "thread until", 858 "Run the current or specified thread until it reaches a given line number or leaves the current function.", 859 NULL, 860 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 861 m_options (interpreter) 862 { 863 CommandArgumentEntry arg; 864 CommandArgumentData line_num_arg; 865 866 // Define the first (and only) variant of this arg. 867 line_num_arg.arg_type = eArgTypeLineNum; 868 line_num_arg.arg_repetition = eArgRepeatPlain; 869 870 // There is only one variant this argument could be; put it into the argument entry. 871 arg.push_back (line_num_arg); 872 873 // Push the data for the first argument into the m_arguments vector. 874 m_arguments.push_back (arg); 875 } 876 877 878 virtual 879 ~CommandObjectThreadUntil () 880 { 881 } 882 883 virtual 884 Options * 885 GetOptions () 886 { 887 return &m_options; 888 } 889 890 virtual bool 891 Execute 892 ( 893 Args& command, 894 CommandReturnObject &result 895 ) 896 { 897 bool synchronous_execution = m_interpreter.GetSynchronous (); 898 899 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 900 if (target == NULL) 901 { 902 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 903 result.SetStatus (eReturnStatusFailed); 904 return false; 905 } 906 907 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 908 if (process == NULL) 909 { 910 result.AppendError ("need a valid process to step"); 911 result.SetStatus (eReturnStatusFailed); 912 913 } 914 else 915 { 916 Thread *thread = NULL; 917 uint32_t line_number; 918 919 if (command.GetArgumentCount() != 1) 920 { 921 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax()); 922 result.SetStatus (eReturnStatusFailed); 923 return false; 924 } 925 926 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); 927 if (line_number == UINT32_MAX) 928 { 929 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); 930 result.SetStatus (eReturnStatusFailed); 931 return false; 932 } 933 934 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) 935 { 936 thread = process->GetThreadList().GetSelectedThread().get(); 937 } 938 else 939 { 940 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get(); 941 } 942 943 if (thread == NULL) 944 { 945 const uint32_t num_threads = process->GetThreadList().GetSize(); 946 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 947 m_options.m_thread_idx, 948 num_threads); 949 result.SetStatus (eReturnStatusFailed); 950 return false; 951 } 952 953 const bool abort_other_plans = false; 954 955 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get(); 956 if (frame == NULL) 957 { 958 959 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", 960 m_options.m_frame_idx, 961 m_options.m_thread_idx); 962 result.SetStatus (eReturnStatusFailed); 963 return false; 964 } 965 966 ThreadPlan *new_plan = NULL; 967 968 if (frame->HasDebugInformation ()) 969 { 970 // Finally we got here... Translate the given line number to a bunch of addresses: 971 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit)); 972 LineTable *line_table = NULL; 973 if (sc.comp_unit) 974 line_table = sc.comp_unit->GetLineTable(); 975 976 if (line_table == NULL) 977 { 978 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n", 979 m_options.m_frame_idx, m_options.m_thread_idx); 980 result.SetStatus (eReturnStatusFailed); 981 return false; 982 } 983 984 LineEntry function_start; 985 uint32_t index_ptr = 0, end_ptr; 986 std::vector<addr_t> address_list; 987 988 // Find the beginning & end index of the 989 AddressRange fun_addr_range = sc.function->GetAddressRange(); 990 Address fun_start_addr = fun_addr_range.GetBaseAddress(); 991 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr); 992 993 Address fun_end_addr(fun_start_addr.GetSection(), 994 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); 995 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); 996 997 bool all_in_function = true; 998 999 while (index_ptr <= end_ptr) 1000 { 1001 LineEntry line_entry; 1002 const bool exact = false; 1003 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry); 1004 if (index_ptr == UINT32_MAX) 1005 break; 1006 1007 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); 1008 if (address != LLDB_INVALID_ADDRESS) 1009 { 1010 if (fun_addr_range.ContainsLoadAddress (address, target)) 1011 address_list.push_back (address); 1012 else 1013 all_in_function = false; 1014 } 1015 index_ptr++; 1016 } 1017 1018 if (address_list.size() == 0) 1019 { 1020 if (all_in_function) 1021 result.AppendErrorWithFormat ("No line entries matching until target.\n"); 1022 else 1023 result.AppendErrorWithFormat ("Until target outside of the current function.\n"); 1024 1025 result.SetStatus (eReturnStatusFailed); 1026 return false; 1027 } 1028 1029 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, 1030 &address_list.front(), 1031 address_list.size(), 1032 m_options.m_stop_others, 1033 thread->GetSelectedFrameIndex ()); 1034 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint) 1035 // and other plans executed by the user (stepping around the breakpoint) and then a "continue" 1036 // will resume the original plan. 1037 new_plan->SetIsMasterPlan (true); 1038 new_plan->SetOkayToDiscard(false); 1039 } 1040 else 1041 { 1042 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", 1043 m_options.m_frame_idx, 1044 m_options.m_thread_idx); 1045 result.SetStatus (eReturnStatusFailed); 1046 return false; 1047 1048 } 1049 1050 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); 1051 Error error (process->Resume ()); 1052 if (error.Success()) 1053 { 1054 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID()); 1055 if (synchronous_execution) 1056 { 1057 StateType state = process->WaitForProcessToStop (NULL); 1058 1059 result.SetDidChangeProcessState (true); 1060 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 1061 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1062 } 1063 else 1064 { 1065 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 1066 } 1067 } 1068 else 1069 { 1070 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 1071 result.SetStatus (eReturnStatusFailed); 1072 } 1073 1074 } 1075 return result.Succeeded(); 1076 } 1077 protected: 1078 CommandOptions m_options; 1079 1080 }; 1081 1082 OptionDefinition 1083 CommandObjectThreadUntil::CommandOptions::g_option_table[] = 1084 { 1085 { LLDB_OPT_SET_1, false, "frame", 'f', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, 1086 { LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, 1087 { 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"}, 1088 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1089 }; 1090 1091 1092 //------------------------------------------------------------------------- 1093 // CommandObjectThreadSelect 1094 //------------------------------------------------------------------------- 1095 1096 class CommandObjectThreadSelect : public CommandObject 1097 { 1098 public: 1099 1100 CommandObjectThreadSelect (CommandInterpreter &interpreter) : 1101 CommandObject (interpreter, 1102 "thread select", 1103 "Select a thread as the currently active thread.", 1104 NULL, 1105 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1106 { 1107 CommandArgumentEntry arg; 1108 CommandArgumentData thread_idx_arg; 1109 1110 // Define the first (and only) variant of this arg. 1111 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1112 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1113 1114 // There is only one variant this argument could be; put it into the argument entry. 1115 arg.push_back (thread_idx_arg); 1116 1117 // Push the data for the first argument into the m_arguments vector. 1118 m_arguments.push_back (arg); 1119 } 1120 1121 1122 virtual 1123 ~CommandObjectThreadSelect () 1124 { 1125 } 1126 1127 virtual bool 1128 Execute 1129 ( 1130 Args& command, 1131 CommandReturnObject &result 1132 ) 1133 { 1134 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 1135 if (process == NULL) 1136 { 1137 result.AppendError ("no process"); 1138 result.SetStatus (eReturnStatusFailed); 1139 return false; 1140 } 1141 else if (command.GetArgumentCount() != 1) 1142 { 1143 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1144 result.SetStatus (eReturnStatusFailed); 1145 return false; 1146 } 1147 1148 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0); 1149 1150 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); 1151 if (new_thread == NULL) 1152 { 1153 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0)); 1154 result.SetStatus (eReturnStatusFailed); 1155 return false; 1156 } 1157 1158 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID()); 1159 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1160 1161 const uint32_t start_frame = 0; 1162 const uint32_t num_frames = 1; 1163 const uint32_t num_frames_with_source = 1; 1164 new_thread->GetStatus (result.GetOutputStream(), 1165 start_frame, 1166 num_frames, 1167 num_frames_with_source); 1168 1169 return result.Succeeded(); 1170 } 1171 1172 }; 1173 1174 1175 //------------------------------------------------------------------------- 1176 // CommandObjectThreadList 1177 //------------------------------------------------------------------------- 1178 1179 class CommandObjectThreadList : public CommandObject 1180 { 1181 public: 1182 1183 1184 CommandObjectThreadList (CommandInterpreter &interpreter): 1185 CommandObject (interpreter, 1186 "thread list", 1187 "Show a summary of all current threads in a process.", 1188 "thread list", 1189 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1190 { 1191 } 1192 1193 ~CommandObjectThreadList() 1194 { 1195 } 1196 1197 bool 1198 Execute 1199 ( 1200 Args& command, 1201 CommandReturnObject &result 1202 ) 1203 { 1204 Stream &strm = result.GetOutputStream(); 1205 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1206 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 1207 Process *process = exe_ctx.GetProcessPtr(); 1208 if (process) 1209 { 1210 const bool only_threads_with_stop_reason = false; 1211 const uint32_t start_frame = 0; 1212 const uint32_t num_frames = 0; 1213 const uint32_t num_frames_with_source = 0; 1214 process->GetStatus(strm); 1215 process->GetThreadStatus (strm, 1216 only_threads_with_stop_reason, 1217 start_frame, 1218 num_frames, 1219 num_frames_with_source); 1220 } 1221 else 1222 { 1223 result.AppendError ("no current location or status available"); 1224 result.SetStatus (eReturnStatusFailed); 1225 } 1226 return result.Succeeded(); 1227 } 1228 }; 1229 1230 //------------------------------------------------------------------------- 1231 // CommandObjectMultiwordThread 1232 //------------------------------------------------------------------------- 1233 1234 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : 1235 CommandObjectMultiword (interpreter, 1236 "thread", 1237 "A set of commands for operating on one or more threads within a running process.", 1238 "thread <subcommand> [<subcommand-options>]") 1239 { 1240 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); 1241 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); 1242 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter))); 1243 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); 1244 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); 1245 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1246 interpreter, 1247 "thread step-in", 1248 "Source level single step in specified thread (current thread, if none specified).", 1249 NULL, 1250 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1251 eStepTypeInto, 1252 eStepScopeSource))); 1253 1254 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1255 interpreter, 1256 "thread step-out", 1257 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).", 1258 NULL, 1259 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1260 eStepTypeOut, 1261 eStepScopeSource))); 1262 1263 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1264 interpreter, 1265 "thread step-over", 1266 "Source level single step in specified thread (current thread, if none specified), stepping over calls.", 1267 NULL, 1268 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1269 eStepTypeOver, 1270 eStepScopeSource))); 1271 1272 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1273 interpreter, 1274 "thread step-inst", 1275 "Single step one instruction in specified thread (current thread, if none specified).", 1276 NULL, 1277 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1278 eStepTypeTrace, 1279 eStepScopeInstruction))); 1280 1281 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1282 interpreter, 1283 "thread step-inst-over", 1284 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", 1285 NULL, 1286 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1287 eStepTypeTraceOver, 1288 eStepScopeInstruction))); 1289 } 1290 1291 CommandObjectMultiwordThread::~CommandObjectMultiwordThread () 1292 { 1293 } 1294 1295 1296