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 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'.\n", short_option); 305 } 306 break; 307 308 case 'm': 309 { 310 bool found_one = false; 311 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 312 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one); 313 if (!found_one) 314 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option); 315 } 316 break; 317 318 case 'r': 319 { 320 m_avoid_regexp.clear(); 321 m_avoid_regexp.assign(option_arg); 322 } 323 break; 324 325 default: 326 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 327 break; 328 329 } 330 return error; 331 } 332 333 void 334 OptionParsingStarting () 335 { 336 m_avoid_no_debug = true; 337 m_run_mode = eOnlyDuringStepping; 338 m_avoid_regexp.clear(); 339 } 340 341 const OptionDefinition* 342 GetDefinitions () 343 { 344 return g_option_table; 345 } 346 347 // Options table: Required for subclasses of Options. 348 349 static OptionDefinition g_option_table[]; 350 351 // Instance variables to hold the values for command options. 352 bool m_avoid_no_debug; 353 RunMode m_run_mode; 354 std::string m_avoid_regexp; 355 }; 356 357 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter, 358 const char *name, 359 const char *help, 360 const char *syntax, 361 uint32_t flags, 362 StepType step_type, 363 StepScope step_scope) : 364 CommandObject (interpreter, name, help, syntax, flags), 365 m_step_type (step_type), 366 m_step_scope (step_scope), 367 m_options (interpreter) 368 { 369 CommandArgumentEntry arg; 370 CommandArgumentData thread_id_arg; 371 372 // Define the first (and only) variant of this arg. 373 thread_id_arg.arg_type = eArgTypeThreadID; 374 thread_id_arg.arg_repetition = eArgRepeatOptional; 375 376 // There is only one variant this argument could be; put it into the argument entry. 377 arg.push_back (thread_id_arg); 378 379 // Push the data for the first argument into the m_arguments vector. 380 m_arguments.push_back (arg); 381 } 382 383 virtual 384 ~CommandObjectThreadStepWithTypeAndScope () 385 { 386 } 387 388 virtual 389 Options * 390 GetOptions () 391 { 392 return &m_options; 393 } 394 395 virtual bool 396 Execute 397 ( 398 Args& command, 399 CommandReturnObject &result 400 ) 401 { 402 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 403 bool synchronous_execution = m_interpreter.GetSynchronous(); 404 405 if (process == NULL) 406 { 407 result.AppendError ("need a valid process to step"); 408 result.SetStatus (eReturnStatusFailed); 409 410 } 411 else 412 { 413 const uint32_t num_threads = process->GetThreadList().GetSize(); 414 Thread *thread = NULL; 415 416 if (command.GetArgumentCount() == 0) 417 { 418 thread = process->GetThreadList().GetSelectedThread().get(); 419 if (thread == NULL) 420 { 421 result.AppendError ("no selected thread in process"); 422 result.SetStatus (eReturnStatusFailed); 423 return false; 424 } 425 } 426 else 427 { 428 const char *thread_idx_cstr = command.GetArgumentAtIndex(0); 429 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32); 430 if (step_thread_idx == LLDB_INVALID_INDEX32) 431 { 432 result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr); 433 result.SetStatus (eReturnStatusFailed); 434 return false; 435 } 436 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get(); 437 if (thread == NULL) 438 { 439 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 440 step_thread_idx, num_threads); 441 result.SetStatus (eReturnStatusFailed); 442 return false; 443 } 444 } 445 446 const bool abort_other_plans = false; 447 const lldb::RunMode stop_other_threads = m_options.m_run_mode; 448 449 // This is a bit unfortunate, but not all the commands in this command object support 450 // only while stepping, so I use the bool for them. 451 bool bool_stop_other_threads; 452 if (m_options.m_run_mode == eAllThreads) 453 bool_stop_other_threads = false; 454 else 455 bool_stop_other_threads = true; 456 457 if (m_step_type == eStepTypeInto) 458 { 459 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 460 ThreadPlan *new_plan; 461 462 if (frame->HasDebugInformation ()) 463 { 464 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type, 465 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 466 frame->GetSymbolContext(eSymbolContextEverything), 467 stop_other_threads, 468 m_options.m_avoid_no_debug); 469 if (new_plan && !m_options.m_avoid_regexp.empty()) 470 { 471 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan); 472 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); 473 } 474 } 475 else 476 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 477 478 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 479 process->Resume (); 480 } 481 else if (m_step_type == eStepTypeOver) 482 { 483 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 484 ThreadPlan *new_plan; 485 486 if (frame->HasDebugInformation()) 487 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, 488 m_step_type, 489 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 490 frame->GetSymbolContext(eSymbolContextEverything), 491 stop_other_threads, 492 false); 493 else 494 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, 495 abort_other_plans, 496 bool_stop_other_threads); 497 498 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over. 499 // Maybe there should be a parameter to control this. 500 new_plan->SetOkayToDiscard(false); 501 502 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 503 process->Resume (); 504 } 505 else if (m_step_type == eStepTypeTrace) 506 { 507 thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 508 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 509 process->Resume (); 510 } 511 else if (m_step_type == eStepTypeTraceOver) 512 { 513 thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); 514 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 515 process->Resume (); 516 } 517 else if (m_step_type == eStepTypeOut) 518 { 519 ThreadPlan *new_plan; 520 521 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, 522 NULL, 523 false, 524 bool_stop_other_threads, 525 eVoteYes, 526 eVoteNoOpinion, 527 thread->GetSelectedFrameIndex()); 528 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over. 529 // Maybe there should be a parameter to control this. 530 new_plan->SetOkayToDiscard(false); 531 532 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 533 process->Resume (); 534 } 535 else 536 { 537 result.AppendError ("step type is not supported"); 538 result.SetStatus (eReturnStatusFailed); 539 } 540 if (synchronous_execution) 541 { 542 StateType state = process->WaitForProcessToStop (NULL); 543 544 //EventSP event_sp; 545 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp); 546 //while (! StateIsStoppedState (state)) 547 // { 548 // state = process->WaitForStateChangedEvents (NULL, event_sp); 549 // } 550 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 551 result.SetDidChangeProcessState (true); 552 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 553 result.SetStatus (eReturnStatusSuccessFinishNoResult); 554 } 555 } 556 return result.Succeeded(); 557 } 558 559 protected: 560 StepType m_step_type; 561 StepScope m_step_scope; 562 CommandOptions m_options; 563 }; 564 565 static OptionEnumValueElement 566 g_tri_running_mode[] = 567 { 568 { eOnlyThisThread, "this-thread", "Run only this thread"}, 569 { eAllThreads, "all-threads", "Run all threads"}, 570 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"}, 571 { 0, NULL, NULL } 572 }; 573 574 static OptionEnumValueElement 575 g_duo_running_mode[] = 576 { 577 { eOnlyThisThread, "this-thread", "Run only this thread"}, 578 { eAllThreads, "all-threads", "Run all threads"}, 579 { 0, NULL, NULL } 580 }; 581 582 OptionDefinition 583 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = 584 { 585 { 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."}, 586 { 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."}, 587 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."}, 588 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 589 }; 590 591 592 //------------------------------------------------------------------------- 593 // CommandObjectThreadContinue 594 //------------------------------------------------------------------------- 595 596 class CommandObjectThreadContinue : public CommandObject 597 { 598 public: 599 600 CommandObjectThreadContinue (CommandInterpreter &interpreter) : 601 CommandObject (interpreter, 602 "thread continue", 603 "Continue execution of one or more threads in an active process.", 604 NULL, 605 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 606 { 607 CommandArgumentEntry arg; 608 CommandArgumentData thread_idx_arg; 609 610 // Define the first (and only) variant of this arg. 611 thread_idx_arg.arg_type = eArgTypeThreadIndex; 612 thread_idx_arg.arg_repetition = eArgRepeatPlus; 613 614 // There is only one variant this argument could be; put it into the argument entry. 615 arg.push_back (thread_idx_arg); 616 617 // Push the data for the first argument into the m_arguments vector. 618 m_arguments.push_back (arg); 619 } 620 621 622 virtual 623 ~CommandObjectThreadContinue () 624 { 625 } 626 627 virtual bool 628 Execute 629 ( 630 Args& command, 631 CommandReturnObject &result 632 ) 633 { 634 bool synchronous_execution = m_interpreter.GetSynchronous (); 635 636 if (!m_interpreter.GetDebugger().GetSelectedTarget().get()) 637 { 638 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 639 result.SetStatus (eReturnStatusFailed); 640 return false; 641 } 642 643 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 644 if (process == NULL) 645 { 646 result.AppendError ("no process exists. Cannot continue"); 647 result.SetStatus (eReturnStatusFailed); 648 return false; 649 } 650 651 StateType state = process->GetState(); 652 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended)) 653 { 654 const uint32_t num_threads = process->GetThreadList().GetSize(); 655 uint32_t idx; 656 const size_t argc = command.GetArgumentCount(); 657 if (argc > 0) 658 { 659 std::vector<uint32_t> resume_thread_indexes; 660 for (uint32_t i=0; i<argc; ++i) 661 { 662 idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32); 663 if (idx < num_threads) 664 resume_thread_indexes.push_back(idx); 665 else 666 result.AppendWarningWithFormat("Thread index %u out of range.\n", idx); 667 } 668 669 if (resume_thread_indexes.empty()) 670 { 671 result.AppendError ("no valid thread indexes were specified"); 672 result.SetStatus (eReturnStatusFailed); 673 return false; 674 } 675 else 676 { 677 result.AppendMessage ("Resuming thread "); 678 for (idx=0; idx<num_threads; ++idx) 679 { 680 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 681 if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end()) 682 { 683 result.AppendMessageWithFormat ("%u ", idx); 684 thread->SetResumeState (eStateRunning); 685 } 686 else 687 { 688 thread->SetResumeState (eStateSuspended); 689 } 690 } 691 result.AppendMessageWithFormat ("in process %i\n", process->GetID()); 692 } 693 } 694 else 695 { 696 Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); 697 if (current_thread == NULL) 698 { 699 result.AppendError ("the process doesn't have a current thread"); 700 result.SetStatus (eReturnStatusFailed); 701 return false; 702 } 703 // Set the actions that the threads should each take when resuming 704 for (idx=0; idx<num_threads; ++idx) 705 { 706 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 707 if (thread == current_thread) 708 { 709 result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID()); 710 thread->SetResumeState (eStateRunning); 711 } 712 else 713 { 714 thread->SetResumeState (eStateSuspended); 715 } 716 } 717 } 718 719 Error error (process->Resume()); 720 if (error.Success()) 721 { 722 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 723 if (synchronous_execution) 724 { 725 state = process->WaitForProcessToStop (NULL); 726 727 result.SetDidChangeProcessState (true); 728 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 729 result.SetStatus (eReturnStatusSuccessFinishNoResult); 730 } 731 else 732 { 733 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 734 } 735 } 736 else 737 { 738 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString()); 739 result.SetStatus (eReturnStatusFailed); 740 } 741 } 742 else 743 { 744 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 745 StateAsCString(state)); 746 result.SetStatus (eReturnStatusFailed); 747 } 748 749 return result.Succeeded(); 750 } 751 752 }; 753 754 //------------------------------------------------------------------------- 755 // CommandObjectThreadUntil 756 //------------------------------------------------------------------------- 757 758 class CommandObjectThreadUntil : public CommandObject 759 { 760 public: 761 762 class CommandOptions : public Options 763 { 764 public: 765 uint32_t m_thread_idx; 766 uint32_t m_frame_idx; 767 768 CommandOptions (CommandInterpreter &interpreter) : 769 Options (interpreter), 770 m_thread_idx(LLDB_INVALID_THREAD_ID), 771 m_frame_idx(LLDB_INVALID_FRAME_ID) 772 { 773 // Keep default values of all options in one place: OptionParsingStarting () 774 OptionParsingStarting (); 775 } 776 777 virtual 778 ~CommandOptions () 779 { 780 } 781 782 virtual Error 783 SetOptionValue (uint32_t option_idx, const char *option_arg) 784 { 785 Error error; 786 char short_option = (char) m_getopt_table[option_idx].val; 787 788 switch (short_option) 789 { 790 case 't': 791 { 792 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32); 793 if (m_thread_idx == LLDB_INVALID_INDEX32) 794 { 795 error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg); 796 } 797 } 798 break; 799 case 'f': 800 { 801 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID); 802 if (m_frame_idx == LLDB_INVALID_FRAME_ID) 803 { 804 error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg); 805 } 806 } 807 break; 808 case 'm': 809 { 810 bool found_one = false; 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, &found_one); 813 814 if (!found_one) 815 error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option); 816 else 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'.\n", 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().GetThreadAtIndex(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 = true; 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; 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 new_plan->SetOkayToDiscard(false); 1035 } 1036 else 1037 { 1038 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", 1039 m_options.m_frame_idx, 1040 m_options.m_thread_idx); 1041 result.SetStatus (eReturnStatusFailed); 1042 return false; 1043 1044 } 1045 1046 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); 1047 Error error (process->Resume ()); 1048 if (error.Success()) 1049 { 1050 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 1051 if (synchronous_execution) 1052 { 1053 StateType state = process->WaitForProcessToStop (NULL); 1054 1055 result.SetDidChangeProcessState (true); 1056 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 1057 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1058 } 1059 else 1060 { 1061 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 1062 } 1063 } 1064 else 1065 { 1066 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 1067 result.SetStatus (eReturnStatusFailed); 1068 } 1069 1070 } 1071 return result.Succeeded(); 1072 } 1073 protected: 1074 CommandOptions m_options; 1075 1076 }; 1077 1078 OptionDefinition 1079 CommandObjectThreadUntil::CommandOptions::g_option_table[] = 1080 { 1081 { LLDB_OPT_SET_1, false, "frame", 'f', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, 1082 { LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, 1083 { 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"}, 1084 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1085 }; 1086 1087 1088 //------------------------------------------------------------------------- 1089 // CommandObjectThreadSelect 1090 //------------------------------------------------------------------------- 1091 1092 class CommandObjectThreadSelect : public CommandObject 1093 { 1094 public: 1095 1096 CommandObjectThreadSelect (CommandInterpreter &interpreter) : 1097 CommandObject (interpreter, 1098 "thread select", 1099 "Select a thread as the currently active thread.", 1100 NULL, 1101 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1102 { 1103 CommandArgumentEntry arg; 1104 CommandArgumentData thread_idx_arg; 1105 1106 // Define the first (and only) variant of this arg. 1107 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1108 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1109 1110 // There is only one variant this argument could be; put it into the argument entry. 1111 arg.push_back (thread_idx_arg); 1112 1113 // Push the data for the first argument into the m_arguments vector. 1114 m_arguments.push_back (arg); 1115 } 1116 1117 1118 virtual 1119 ~CommandObjectThreadSelect () 1120 { 1121 } 1122 1123 virtual bool 1124 Execute 1125 ( 1126 Args& command, 1127 CommandReturnObject &result 1128 ) 1129 { 1130 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 1131 if (process == NULL) 1132 { 1133 result.AppendError ("no process"); 1134 result.SetStatus (eReturnStatusFailed); 1135 return false; 1136 } 1137 else if (command.GetArgumentCount() != 1) 1138 { 1139 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1140 result.SetStatus (eReturnStatusFailed); 1141 return false; 1142 } 1143 1144 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0); 1145 1146 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); 1147 if (new_thread == NULL) 1148 { 1149 result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0)); 1150 result.SetStatus (eReturnStatusFailed); 1151 return false; 1152 } 1153 1154 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID()); 1155 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1156 1157 const uint32_t start_frame = 0; 1158 const uint32_t num_frames = 1; 1159 const uint32_t num_frames_with_source = 1; 1160 new_thread->GetStatus (result.GetOutputStream(), 1161 start_frame, 1162 num_frames, 1163 num_frames_with_source); 1164 1165 return result.Succeeded(); 1166 } 1167 1168 }; 1169 1170 1171 //------------------------------------------------------------------------- 1172 // CommandObjectThreadList 1173 //------------------------------------------------------------------------- 1174 1175 class CommandObjectThreadList : public CommandObject 1176 { 1177 public: 1178 1179 1180 CommandObjectThreadList (CommandInterpreter &interpreter): 1181 CommandObject (interpreter, 1182 "thread list", 1183 "Show a summary of all current threads in a process.", 1184 "thread list", 1185 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1186 { 1187 } 1188 1189 ~CommandObjectThreadList() 1190 { 1191 } 1192 1193 bool 1194 Execute 1195 ( 1196 Args& command, 1197 CommandReturnObject &result 1198 ) 1199 { 1200 Stream &strm = result.GetOutputStream(); 1201 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1202 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 1203 Process *process = exe_ctx.GetProcessPtr(); 1204 if (process) 1205 { 1206 const bool only_threads_with_stop_reason = false; 1207 const uint32_t start_frame = 0; 1208 const uint32_t num_frames = 0; 1209 const uint32_t num_frames_with_source = 0; 1210 process->GetStatus(strm); 1211 process->GetThreadStatus (strm, 1212 only_threads_with_stop_reason, 1213 start_frame, 1214 num_frames, 1215 num_frames_with_source); 1216 } 1217 else 1218 { 1219 result.AppendError ("no current location or status available"); 1220 result.SetStatus (eReturnStatusFailed); 1221 } 1222 return result.Succeeded(); 1223 } 1224 }; 1225 1226 //------------------------------------------------------------------------- 1227 // CommandObjectMultiwordThread 1228 //------------------------------------------------------------------------- 1229 1230 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : 1231 CommandObjectMultiword (interpreter, 1232 "thread", 1233 "A set of commands for operating on one or more threads within a running process.", 1234 "thread <subcommand> [<subcommand-options>]") 1235 { 1236 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); 1237 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); 1238 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter))); 1239 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); 1240 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); 1241 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1242 interpreter, 1243 "thread step-in", 1244 "Source level single step in specified thread (current thread, if none specified).", 1245 NULL, 1246 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1247 eStepTypeInto, 1248 eStepScopeSource))); 1249 1250 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1251 interpreter, 1252 "thread step-out", 1253 "Finish executing the current function and return to its call site in specified thread (current thread, if none specified).", 1254 NULL, 1255 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1256 eStepTypeOut, 1257 eStepScopeSource))); 1258 1259 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1260 interpreter, 1261 "thread step-over", 1262 "Source level single step in specified thread (current thread, if none specified), stepping over calls.", 1263 NULL, 1264 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1265 eStepTypeOver, 1266 eStepScopeSource))); 1267 1268 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1269 interpreter, 1270 "thread step-inst", 1271 "Single step one instruction in specified thread (current thread, if none specified).", 1272 NULL, 1273 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1274 eStepTypeTrace, 1275 eStepScopeInstruction))); 1276 1277 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1278 interpreter, 1279 "thread step-inst-over", 1280 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", 1281 NULL, 1282 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1283 eStepTypeTraceOver, 1284 eStepScopeInstruction))); 1285 } 1286 1287 CommandObjectMultiwordThread::~CommandObjectMultiwordThread () 1288 { 1289 } 1290 1291 1292