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