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