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 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry); 1003 if (index_ptr == UINT32_MAX) 1004 break; 1005 1006 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); 1007 if (address != LLDB_INVALID_ADDRESS) 1008 { 1009 if (fun_addr_range.ContainsLoadAddress (address, target)) 1010 address_list.push_back (address); 1011 else 1012 all_in_function = false; 1013 } 1014 index_ptr++; 1015 } 1016 1017 if (address_list.size() == 0) 1018 { 1019 if (all_in_function) 1020 result.AppendErrorWithFormat ("No line entries matching until target.\n"); 1021 else 1022 result.AppendErrorWithFormat ("Until target outside of the current function.\n"); 1023 1024 result.SetStatus (eReturnStatusFailed); 1025 return false; 1026 } 1027 1028 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, 1029 &address_list.front(), 1030 address_list.size(), 1031 m_options.m_stop_others, 1032 thread->GetSelectedFrameIndex ()); 1033 new_plan->SetOkayToDiscard(false); 1034 } 1035 else 1036 { 1037 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", 1038 m_options.m_frame_idx, 1039 m_options.m_thread_idx); 1040 result.SetStatus (eReturnStatusFailed); 1041 return false; 1042 1043 } 1044 1045 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); 1046 Error error (process->Resume ()); 1047 if (error.Success()) 1048 { 1049 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 1050 if (synchronous_execution) 1051 { 1052 StateType state = process->WaitForProcessToStop (NULL); 1053 1054 result.SetDidChangeProcessState (true); 1055 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 1056 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1057 } 1058 else 1059 { 1060 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 1061 } 1062 } 1063 else 1064 { 1065 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 1066 result.SetStatus (eReturnStatusFailed); 1067 } 1068 1069 } 1070 return result.Succeeded(); 1071 } 1072 protected: 1073 CommandOptions m_options; 1074 1075 }; 1076 1077 OptionDefinition 1078 CommandObjectThreadUntil::CommandOptions::g_option_table[] = 1079 { 1080 { LLDB_OPT_SET_1, false, "frame", 'f', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, 1081 { LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, 1082 { 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"}, 1083 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1084 }; 1085 1086 1087 //------------------------------------------------------------------------- 1088 // CommandObjectThreadSelect 1089 //------------------------------------------------------------------------- 1090 1091 class CommandObjectThreadSelect : public CommandObject 1092 { 1093 public: 1094 1095 CommandObjectThreadSelect (CommandInterpreter &interpreter) : 1096 CommandObject (interpreter, 1097 "thread select", 1098 "Select a thread as the currently active thread.", 1099 NULL, 1100 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1101 { 1102 CommandArgumentEntry arg; 1103 CommandArgumentData thread_idx_arg; 1104 1105 // Define the first (and only) variant of this arg. 1106 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1107 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1108 1109 // There is only one variant this argument could be; put it into the argument entry. 1110 arg.push_back (thread_idx_arg); 1111 1112 // Push the data for the first argument into the m_arguments vector. 1113 m_arguments.push_back (arg); 1114 } 1115 1116 1117 virtual 1118 ~CommandObjectThreadSelect () 1119 { 1120 } 1121 1122 virtual bool 1123 Execute 1124 ( 1125 Args& command, 1126 CommandReturnObject &result 1127 ) 1128 { 1129 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 1130 if (process == NULL) 1131 { 1132 result.AppendError ("no process"); 1133 result.SetStatus (eReturnStatusFailed); 1134 return false; 1135 } 1136 else if (command.GetArgumentCount() != 1) 1137 { 1138 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1139 result.SetStatus (eReturnStatusFailed); 1140 return false; 1141 } 1142 1143 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0); 1144 1145 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); 1146 if (new_thread == NULL) 1147 { 1148 result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0)); 1149 result.SetStatus (eReturnStatusFailed); 1150 return false; 1151 } 1152 1153 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID()); 1154 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1155 1156 const uint32_t start_frame = 0; 1157 const uint32_t num_frames = 1; 1158 const uint32_t num_frames_with_source = 1; 1159 new_thread->GetStatus (result.GetOutputStream(), 1160 start_frame, 1161 num_frames, 1162 num_frames_with_source); 1163 1164 return result.Succeeded(); 1165 } 1166 1167 }; 1168 1169 1170 //------------------------------------------------------------------------- 1171 // CommandObjectThreadList 1172 //------------------------------------------------------------------------- 1173 1174 class CommandObjectThreadList : public CommandObject 1175 { 1176 public: 1177 1178 1179 CommandObjectThreadList (CommandInterpreter &interpreter): 1180 CommandObject (interpreter, 1181 "thread list", 1182 "Show a summary of all current threads in a process.", 1183 "thread list", 1184 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1185 { 1186 } 1187 1188 ~CommandObjectThreadList() 1189 { 1190 } 1191 1192 bool 1193 Execute 1194 ( 1195 Args& command, 1196 CommandReturnObject &result 1197 ) 1198 { 1199 Stream &strm = result.GetOutputStream(); 1200 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1201 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 1202 Process *process = exe_ctx.GetProcessPtr(); 1203 if (process) 1204 { 1205 const bool only_threads_with_stop_reason = false; 1206 const uint32_t start_frame = 0; 1207 const uint32_t num_frames = 0; 1208 const uint32_t num_frames_with_source = 0; 1209 process->GetStatus(strm); 1210 process->GetThreadStatus (strm, 1211 only_threads_with_stop_reason, 1212 start_frame, 1213 num_frames, 1214 num_frames_with_source); 1215 } 1216 else 1217 { 1218 result.AppendError ("no current location or status available"); 1219 result.SetStatus (eReturnStatusFailed); 1220 } 1221 return result.Succeeded(); 1222 } 1223 }; 1224 1225 //------------------------------------------------------------------------- 1226 // CommandObjectMultiwordThread 1227 //------------------------------------------------------------------------- 1228 1229 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : 1230 CommandObjectMultiword (interpreter, 1231 "thread", 1232 "A set of commands for operating on one or more threads within a running process.", 1233 "thread <subcommand> [<subcommand-options>]") 1234 { 1235 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); 1236 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); 1237 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter))); 1238 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); 1239 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); 1240 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1241 interpreter, 1242 "thread step-in", 1243 "Source level single step in specified thread (current thread, if none specified).", 1244 NULL, 1245 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1246 eStepTypeInto, 1247 eStepScopeSource))); 1248 1249 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1250 interpreter, 1251 "thread step-out", 1252 "Finish executing the current function and return to its call site in specified thread (current thread, if none specified).", 1253 NULL, 1254 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1255 eStepTypeOut, 1256 eStepScopeSource))); 1257 1258 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1259 interpreter, 1260 "thread step-over", 1261 "Source level single step in specified thread (current thread, if none specified), stepping over calls.", 1262 NULL, 1263 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1264 eStepTypeOver, 1265 eStepScopeSource))); 1266 1267 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1268 interpreter, 1269 "thread step-inst", 1270 "Single step one instruction in specified thread (current thread, if none specified).", 1271 NULL, 1272 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1273 eStepTypeTrace, 1274 eStepScopeInstruction))); 1275 1276 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1277 interpreter, 1278 "thread step-inst-over", 1279 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", 1280 NULL, 1281 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1282 eStepTypeTraceOver, 1283 eStepScopeInstruction))); 1284 } 1285 1286 CommandObjectMultiwordThread::~CommandObjectMultiwordThread () 1287 { 1288 } 1289 1290 1291