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