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