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 453 bool_stop_other_threads = true; 454 455 ThreadPlan *new_plan = NULL; 456 457 if (m_step_type == eStepTypeInto) 458 { 459 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 460 461 if (frame->HasDebugInformation ()) 462 { 463 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type, 464 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 465 frame->GetSymbolContext(eSymbolContextEverything), 466 stop_other_threads, 467 m_options.m_avoid_no_debug); 468 if (new_plan && !m_options.m_avoid_regexp.empty()) 469 { 470 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan); 471 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); 472 } 473 } 474 else 475 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 476 477 } 478 else if (m_step_type == eStepTypeOver) 479 { 480 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 481 482 if (frame->HasDebugInformation()) 483 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, 484 m_step_type, 485 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 486 frame->GetSymbolContext(eSymbolContextEverything), 487 stop_other_threads, 488 false); 489 else 490 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, 491 abort_other_plans, 492 bool_stop_other_threads); 493 494 } 495 else if (m_step_type == eStepTypeTrace) 496 { 497 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 498 } 499 else if (m_step_type == eStepTypeTraceOver) 500 { 501 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); 502 } 503 else if (m_step_type == eStepTypeOut) 504 { 505 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, 506 NULL, 507 false, 508 bool_stop_other_threads, 509 eVoteYes, 510 eVoteNoOpinion, 511 thread->GetSelectedFrameIndex()); 512 } 513 else 514 { 515 result.AppendError ("step type is not supported"); 516 result.SetStatus (eReturnStatusFailed); 517 return false; 518 } 519 520 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans 521 // so that they can be interruptible). Then resume the process. 522 523 if (new_plan != NULL) 524 { 525 new_plan->SetIsMasterPlan (true); 526 new_plan->SetOkayToDiscard (false); 527 528 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 529 process->Resume (); 530 531 532 if (synchronous_execution) 533 { 534 StateType state = process->WaitForProcessToStop (NULL); 535 536 //EventSP event_sp; 537 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp); 538 //while (! StateIsStoppedState (state)) 539 // { 540 // state = process->WaitForStateChangedEvents (NULL, event_sp); 541 // } 542 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 543 result.SetDidChangeProcessState (true); 544 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 545 result.SetStatus (eReturnStatusSuccessFinishNoResult); 546 } 547 else 548 { 549 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 550 } 551 } 552 else 553 { 554 result.AppendError ("Couldn't find thread plan to implement step type."); 555 result.SetStatus (eReturnStatusFailed); 556 } 557 } 558 return result.Succeeded(); 559 } 560 561 protected: 562 StepType m_step_type; 563 StepScope m_step_scope; 564 CommandOptions m_options; 565 }; 566 567 static OptionEnumValueElement 568 g_tri_running_mode[] = 569 { 570 { eOnlyThisThread, "this-thread", "Run only this thread"}, 571 { eAllThreads, "all-threads", "Run all threads"}, 572 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"}, 573 { 0, NULL, NULL } 574 }; 575 576 static OptionEnumValueElement 577 g_duo_running_mode[] = 578 { 579 { eOnlyThisThread, "this-thread", "Run only this thread"}, 580 { eAllThreads, "all-threads", "Run all threads"}, 581 { 0, NULL, NULL } 582 }; 583 584 OptionDefinition 585 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = 586 { 587 { 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."}, 588 { 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."}, 589 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."}, 590 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 591 }; 592 593 594 //------------------------------------------------------------------------- 595 // CommandObjectThreadContinue 596 //------------------------------------------------------------------------- 597 598 class CommandObjectThreadContinue : public CommandObjectParsed 599 { 600 public: 601 602 CommandObjectThreadContinue (CommandInterpreter &interpreter) : 603 CommandObjectParsed (interpreter, 604 "thread continue", 605 "Continue execution of one or more threads in an active process.", 606 NULL, 607 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 608 { 609 CommandArgumentEntry arg; 610 CommandArgumentData thread_idx_arg; 611 612 // Define the first (and only) variant of this arg. 613 thread_idx_arg.arg_type = eArgTypeThreadIndex; 614 thread_idx_arg.arg_repetition = eArgRepeatPlus; 615 616 // There is only one variant this argument could be; put it into the argument entry. 617 arg.push_back (thread_idx_arg); 618 619 // Push the data for the first argument into the m_arguments vector. 620 m_arguments.push_back (arg); 621 } 622 623 624 virtual 625 ~CommandObjectThreadContinue () 626 { 627 } 628 629 virtual bool 630 DoExecute (Args& command, CommandReturnObject &result) 631 { 632 bool synchronous_execution = m_interpreter.GetSynchronous (); 633 634 if (!m_interpreter.GetDebugger().GetSelectedTarget().get()) 635 { 636 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 637 result.SetStatus (eReturnStatusFailed); 638 return false; 639 } 640 641 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 642 if (process == NULL) 643 { 644 result.AppendError ("no process exists. Cannot continue"); 645 result.SetStatus (eReturnStatusFailed); 646 return false; 647 } 648 649 StateType state = process->GetState(); 650 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended)) 651 { 652 Mutex::Locker locker (process->GetThreadList().GetMutex()); 653 const uint32_t num_threads = process->GetThreadList().GetSize(); 654 const size_t argc = command.GetArgumentCount(); 655 if (argc > 0) 656 { 657 std::vector<Thread *> resume_threads; 658 for (uint32_t i=0; i<argc; ++i) 659 { 660 bool success; 661 const int base = 0; 662 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success); 663 if (success) 664 { 665 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get(); 666 667 if (thread) 668 { 669 resume_threads.push_back(thread); 670 } 671 else 672 { 673 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx); 674 result.SetStatus (eReturnStatusFailed); 675 return false; 676 } 677 } 678 else 679 { 680 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i)); 681 result.SetStatus (eReturnStatusFailed); 682 return false; 683 } 684 } 685 686 if (resume_threads.empty()) 687 { 688 result.AppendError ("no valid thread indexes were specified"); 689 result.SetStatus (eReturnStatusFailed); 690 return false; 691 } 692 else 693 { 694 if (resume_threads.size() == 1) 695 result.AppendMessageWithFormat ("Resuming thread: "); 696 else 697 result.AppendMessageWithFormat ("Resuming threads: "); 698 699 for (uint32_t idx=0; idx<num_threads; ++idx) 700 { 701 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 702 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread); 703 704 if (this_thread_pos != resume_threads.end()) 705 { 706 resume_threads.erase(this_thread_pos); 707 if (resume_threads.size() > 0) 708 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID()); 709 else 710 result.AppendMessageWithFormat ("%u ", thread->GetIndexID()); 711 712 thread->SetResumeState (eStateRunning); 713 } 714 else 715 { 716 thread->SetResumeState (eStateSuspended); 717 } 718 } 719 result.AppendMessageWithFormat ("in process %llu\n", process->GetID()); 720 } 721 } 722 else 723 { 724 Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); 725 if (current_thread == NULL) 726 { 727 result.AppendError ("the process doesn't have a current thread"); 728 result.SetStatus (eReturnStatusFailed); 729 return false; 730 } 731 // Set the actions that the threads should each take when resuming 732 for (uint32_t idx=0; idx<num_threads; ++idx) 733 { 734 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 735 if (thread == current_thread) 736 { 737 result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID()); 738 thread->SetResumeState (eStateRunning); 739 } 740 else 741 { 742 thread->SetResumeState (eStateSuspended); 743 } 744 } 745 } 746 747 Error error (process->Resume()); 748 if (error.Success()) 749 { 750 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID()); 751 if (synchronous_execution) 752 { 753 state = process->WaitForProcessToStop (NULL); 754 755 result.SetDidChangeProcessState (true); 756 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 757 result.SetStatus (eReturnStatusSuccessFinishNoResult); 758 } 759 else 760 { 761 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 762 } 763 } 764 else 765 { 766 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString()); 767 result.SetStatus (eReturnStatusFailed); 768 } 769 } 770 else 771 { 772 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 773 StateAsCString(state)); 774 result.SetStatus (eReturnStatusFailed); 775 } 776 777 return result.Succeeded(); 778 } 779 780 }; 781 782 //------------------------------------------------------------------------- 783 // CommandObjectThreadUntil 784 //------------------------------------------------------------------------- 785 786 class CommandObjectThreadUntil : public CommandObjectParsed 787 { 788 public: 789 790 class CommandOptions : public Options 791 { 792 public: 793 uint32_t m_thread_idx; 794 uint32_t m_frame_idx; 795 796 CommandOptions (CommandInterpreter &interpreter) : 797 Options (interpreter), 798 m_thread_idx(LLDB_INVALID_THREAD_ID), 799 m_frame_idx(LLDB_INVALID_FRAME_ID) 800 { 801 // Keep default values of all options in one place: OptionParsingStarting () 802 OptionParsingStarting (); 803 } 804 805 virtual 806 ~CommandOptions () 807 { 808 } 809 810 virtual Error 811 SetOptionValue (uint32_t option_idx, const char *option_arg) 812 { 813 Error error; 814 char short_option = (char) m_getopt_table[option_idx].val; 815 816 switch (short_option) 817 { 818 case 't': 819 { 820 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32); 821 if (m_thread_idx == LLDB_INVALID_INDEX32) 822 { 823 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg); 824 } 825 } 826 break; 827 case 'f': 828 { 829 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID); 830 if (m_frame_idx == LLDB_INVALID_FRAME_ID) 831 { 832 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg); 833 } 834 } 835 break; 836 case 'm': 837 { 838 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 839 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 840 841 if (error.Success()) 842 { 843 if (run_mode == eAllThreads) 844 m_stop_others = false; 845 else 846 m_stop_others = true; 847 } 848 } 849 break; 850 default: 851 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 852 break; 853 854 } 855 return error; 856 } 857 858 void 859 OptionParsingStarting () 860 { 861 m_thread_idx = LLDB_INVALID_THREAD_ID; 862 m_frame_idx = 0; 863 m_stop_others = false; 864 } 865 866 const OptionDefinition* 867 GetDefinitions () 868 { 869 return g_option_table; 870 } 871 872 uint32_t m_step_thread_idx; 873 bool m_stop_others; 874 875 // Options table: Required for subclasses of Options. 876 877 static OptionDefinition g_option_table[]; 878 879 // Instance variables to hold the values for command options. 880 }; 881 882 CommandObjectThreadUntil (CommandInterpreter &interpreter) : 883 CommandObjectParsed (interpreter, 884 "thread until", 885 "Run the current or specified thread until it reaches a given line number or leaves the current function.", 886 NULL, 887 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 888 m_options (interpreter) 889 { 890 CommandArgumentEntry arg; 891 CommandArgumentData line_num_arg; 892 893 // Define the first (and only) variant of this arg. 894 line_num_arg.arg_type = eArgTypeLineNum; 895 line_num_arg.arg_repetition = eArgRepeatPlain; 896 897 // There is only one variant this argument could be; put it into the argument entry. 898 arg.push_back (line_num_arg); 899 900 // Push the data for the first argument into the m_arguments vector. 901 m_arguments.push_back (arg); 902 } 903 904 905 virtual 906 ~CommandObjectThreadUntil () 907 { 908 } 909 910 virtual 911 Options * 912 GetOptions () 913 { 914 return &m_options; 915 } 916 917 protected: 918 virtual bool 919 DoExecute (Args& command, CommandReturnObject &result) 920 { 921 bool synchronous_execution = m_interpreter.GetSynchronous (); 922 923 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 924 if (target == NULL) 925 { 926 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 927 result.SetStatus (eReturnStatusFailed); 928 return false; 929 } 930 931 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 932 if (process == NULL) 933 { 934 result.AppendError ("need a valid process to step"); 935 result.SetStatus (eReturnStatusFailed); 936 937 } 938 else 939 { 940 Thread *thread = NULL; 941 uint32_t line_number; 942 943 if (command.GetArgumentCount() != 1) 944 { 945 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax()); 946 result.SetStatus (eReturnStatusFailed); 947 return false; 948 } 949 950 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); 951 if (line_number == UINT32_MAX) 952 { 953 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); 954 result.SetStatus (eReturnStatusFailed); 955 return false; 956 } 957 958 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) 959 { 960 thread = process->GetThreadList().GetSelectedThread().get(); 961 } 962 else 963 { 964 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get(); 965 } 966 967 if (thread == NULL) 968 { 969 const uint32_t num_threads = process->GetThreadList().GetSize(); 970 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 971 m_options.m_thread_idx, 972 num_threads); 973 result.SetStatus (eReturnStatusFailed); 974 return false; 975 } 976 977 const bool abort_other_plans = false; 978 979 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get(); 980 if (frame == NULL) 981 { 982 983 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", 984 m_options.m_frame_idx, 985 m_options.m_thread_idx); 986 result.SetStatus (eReturnStatusFailed); 987 return false; 988 } 989 990 ThreadPlan *new_plan = NULL; 991 992 if (frame->HasDebugInformation ()) 993 { 994 // Finally we got here... Translate the given line number to a bunch of addresses: 995 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit)); 996 LineTable *line_table = NULL; 997 if (sc.comp_unit) 998 line_table = sc.comp_unit->GetLineTable(); 999 1000 if (line_table == NULL) 1001 { 1002 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n", 1003 m_options.m_frame_idx, m_options.m_thread_idx); 1004 result.SetStatus (eReturnStatusFailed); 1005 return false; 1006 } 1007 1008 LineEntry function_start; 1009 uint32_t index_ptr = 0, end_ptr; 1010 std::vector<addr_t> address_list; 1011 1012 // Find the beginning & end index of the 1013 AddressRange fun_addr_range = sc.function->GetAddressRange(); 1014 Address fun_start_addr = fun_addr_range.GetBaseAddress(); 1015 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr); 1016 1017 Address fun_end_addr(fun_start_addr.GetSection(), 1018 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); 1019 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); 1020 1021 bool all_in_function = true; 1022 1023 while (index_ptr <= end_ptr) 1024 { 1025 LineEntry line_entry; 1026 const bool exact = false; 1027 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry); 1028 if (index_ptr == UINT32_MAX) 1029 break; 1030 1031 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); 1032 if (address != LLDB_INVALID_ADDRESS) 1033 { 1034 if (fun_addr_range.ContainsLoadAddress (address, target)) 1035 address_list.push_back (address); 1036 else 1037 all_in_function = false; 1038 } 1039 index_ptr++; 1040 } 1041 1042 if (address_list.size() == 0) 1043 { 1044 if (all_in_function) 1045 result.AppendErrorWithFormat ("No line entries matching until target.\n"); 1046 else 1047 result.AppendErrorWithFormat ("Until target outside of the current function.\n"); 1048 1049 result.SetStatus (eReturnStatusFailed); 1050 return false; 1051 } 1052 1053 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, 1054 &address_list.front(), 1055 address_list.size(), 1056 m_options.m_stop_others, 1057 m_options.m_frame_idx); 1058 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint) 1059 // and other plans executed by the user (stepping around the breakpoint) and then a "continue" 1060 // will resume the original plan. 1061 new_plan->SetIsMasterPlan (true); 1062 new_plan->SetOkayToDiscard(false); 1063 } 1064 else 1065 { 1066 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", 1067 m_options.m_frame_idx, 1068 m_options.m_thread_idx); 1069 result.SetStatus (eReturnStatusFailed); 1070 return false; 1071 1072 } 1073 1074 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); 1075 Error error (process->Resume ()); 1076 if (error.Success()) 1077 { 1078 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID()); 1079 if (synchronous_execution) 1080 { 1081 StateType state = process->WaitForProcessToStop (NULL); 1082 1083 result.SetDidChangeProcessState (true); 1084 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 1085 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1086 } 1087 else 1088 { 1089 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 1090 } 1091 } 1092 else 1093 { 1094 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 1095 result.SetStatus (eReturnStatusFailed); 1096 } 1097 1098 } 1099 return result.Succeeded(); 1100 } 1101 1102 CommandOptions m_options; 1103 1104 }; 1105 1106 OptionDefinition 1107 CommandObjectThreadUntil::CommandOptions::g_option_table[] = 1108 { 1109 { LLDB_OPT_SET_1, false, "frame", 'f', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, 1110 { LLDB_OPT_SET_1, false, "thread", 't', required_argument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, 1111 { 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"}, 1112 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1113 }; 1114 1115 1116 //------------------------------------------------------------------------- 1117 // CommandObjectThreadSelect 1118 //------------------------------------------------------------------------- 1119 1120 class CommandObjectThreadSelect : public CommandObjectParsed 1121 { 1122 public: 1123 1124 CommandObjectThreadSelect (CommandInterpreter &interpreter) : 1125 CommandObjectParsed (interpreter, 1126 "thread select", 1127 "Select a thread as the currently active thread.", 1128 NULL, 1129 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1130 { 1131 CommandArgumentEntry arg; 1132 CommandArgumentData thread_idx_arg; 1133 1134 // Define the first (and only) variant of this arg. 1135 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1136 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1137 1138 // There is only one variant this argument could be; put it into the argument entry. 1139 arg.push_back (thread_idx_arg); 1140 1141 // Push the data for the first argument into the m_arguments vector. 1142 m_arguments.push_back (arg); 1143 } 1144 1145 1146 virtual 1147 ~CommandObjectThreadSelect () 1148 { 1149 } 1150 1151 protected: 1152 virtual bool 1153 DoExecute (Args& command, CommandReturnObject &result) 1154 { 1155 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 1156 if (process == NULL) 1157 { 1158 result.AppendError ("no process"); 1159 result.SetStatus (eReturnStatusFailed); 1160 return false; 1161 } 1162 else if (command.GetArgumentCount() != 1) 1163 { 1164 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1165 result.SetStatus (eReturnStatusFailed); 1166 return false; 1167 } 1168 1169 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0); 1170 1171 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); 1172 if (new_thread == NULL) 1173 { 1174 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0)); 1175 result.SetStatus (eReturnStatusFailed); 1176 return false; 1177 } 1178 1179 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID()); 1180 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1181 1182 const uint32_t start_frame = 0; 1183 const uint32_t num_frames = 1; 1184 const uint32_t num_frames_with_source = 1; 1185 new_thread->GetStatus (result.GetOutputStream(), 1186 start_frame, 1187 num_frames, 1188 num_frames_with_source); 1189 1190 return result.Succeeded(); 1191 } 1192 1193 }; 1194 1195 1196 //------------------------------------------------------------------------- 1197 // CommandObjectThreadList 1198 //------------------------------------------------------------------------- 1199 1200 class CommandObjectThreadList : public CommandObjectParsed 1201 { 1202 public: 1203 1204 1205 CommandObjectThreadList (CommandInterpreter &interpreter): 1206 CommandObjectParsed (interpreter, 1207 "thread list", 1208 "Show a summary of all current threads in a process.", 1209 "thread list", 1210 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1211 { 1212 } 1213 1214 ~CommandObjectThreadList() 1215 { 1216 } 1217 1218 protected: 1219 bool 1220 DoExecute (Args& command, CommandReturnObject &result) 1221 { 1222 Stream &strm = result.GetOutputStream(); 1223 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1224 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 1225 Process *process = exe_ctx.GetProcessPtr(); 1226 if (process) 1227 { 1228 const bool only_threads_with_stop_reason = false; 1229 const uint32_t start_frame = 0; 1230 const uint32_t num_frames = 0; 1231 const uint32_t num_frames_with_source = 0; 1232 process->GetStatus(strm); 1233 process->GetThreadStatus (strm, 1234 only_threads_with_stop_reason, 1235 start_frame, 1236 num_frames, 1237 num_frames_with_source); 1238 } 1239 else 1240 { 1241 result.AppendError ("no current location or status available"); 1242 result.SetStatus (eReturnStatusFailed); 1243 } 1244 return result.Succeeded(); 1245 } 1246 }; 1247 1248 class CommandObjectThreadReturn : public CommandObjectRaw 1249 { 1250 public: 1251 CommandObjectThreadReturn (CommandInterpreter &interpreter) : 1252 CommandObjectRaw (interpreter, 1253 "thread return", 1254 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value.", 1255 "thread return", 1256 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 1257 { 1258 CommandArgumentEntry arg; 1259 CommandArgumentData expression_arg; 1260 1261 // Define the first (and only) variant of this arg. 1262 expression_arg.arg_type = eArgTypeExpression; 1263 expression_arg.arg_repetition = eArgRepeatPlain; 1264 1265 // There is only one variant this argument could be; put it into the argument entry. 1266 arg.push_back (expression_arg); 1267 1268 // Push the data for the first argument into the m_arguments vector. 1269 m_arguments.push_back (arg); 1270 1271 1272 } 1273 1274 ~CommandObjectThreadReturn() 1275 { 1276 } 1277 1278 protected: 1279 1280 bool DoExecute 1281 ( 1282 const char *command, 1283 CommandReturnObject &result 1284 ) 1285 { 1286 // If there is a command string, pass it to the expression parser: 1287 ExecutionContext exe_ctx = m_interpreter.GetExecutionContext(); 1288 if (!(exe_ctx.HasProcessScope() && exe_ctx.HasThreadScope() && exe_ctx.HasFrameScope())) 1289 { 1290 result.AppendError("Must have selected process, thread and frame for thread return."); 1291 result.SetStatus (eReturnStatusFailed); 1292 return false; 1293 } 1294 1295 ValueObjectSP return_valobj_sp; 1296 1297 StackFrameSP frame_sp = exe_ctx.GetFrameSP(); 1298 uint32_t frame_idx = frame_sp->GetFrameIndex(); 1299 1300 if (frame_sp->IsInlined()) 1301 { 1302 result.AppendError("Don't know how to return from inlined frames."); 1303 result.SetStatus (eReturnStatusFailed); 1304 return false; 1305 } 1306 1307 if (command && command[0] != '\0') 1308 { 1309 Target *target = exe_ctx.GetTargetPtr(); 1310 Target::EvaluateExpressionOptions options; 1311 1312 options.SetUnwindOnError(true); 1313 options.SetUseDynamic(eNoDynamicValues); 1314 1315 ExecutionResults exe_results = eExecutionSetupError; 1316 exe_results = target->EvaluateExpression (command, 1317 frame_sp.get(), 1318 return_valobj_sp, 1319 options); 1320 if (exe_results != eExecutionCompleted) 1321 { 1322 if (return_valobj_sp) 1323 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString()); 1324 else 1325 result.AppendErrorWithFormat("Unknown error evaluating result expression."); 1326 result.SetStatus (eReturnStatusFailed); 1327 return false; 1328 1329 } 1330 } 1331 1332 Error error; 1333 ThreadSP thread_sp = exe_ctx.GetThreadSP(); 1334 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp); 1335 if (!error.Success()) 1336 { 1337 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString()); 1338 result.SetStatus (eReturnStatusFailed); 1339 return false; 1340 } 1341 1342 thread_sp->GetStatus(result.GetOutputStream(), 0, 1, 1); 1343 result.SetStatus (eReturnStatusSuccessFinishResult); 1344 return true; 1345 } 1346 1347 }; 1348 1349 //------------------------------------------------------------------------- 1350 // CommandObjectMultiwordThread 1351 //------------------------------------------------------------------------- 1352 1353 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : 1354 CommandObjectMultiword (interpreter, 1355 "thread", 1356 "A set of commands for operating on one or more threads within a running process.", 1357 "thread <subcommand> [<subcommand-options>]") 1358 { 1359 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); 1360 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); 1361 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter))); 1362 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter))); 1363 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); 1364 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); 1365 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1366 interpreter, 1367 "thread step-in", 1368 "Source level single step in specified thread (current thread, if none specified).", 1369 NULL, 1370 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1371 eStepTypeInto, 1372 eStepScopeSource))); 1373 1374 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1375 interpreter, 1376 "thread step-out", 1377 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).", 1378 NULL, 1379 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1380 eStepTypeOut, 1381 eStepScopeSource))); 1382 1383 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1384 interpreter, 1385 "thread step-over", 1386 "Source level single step in specified thread (current thread, if none specified), stepping over calls.", 1387 NULL, 1388 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1389 eStepTypeOver, 1390 eStepScopeSource))); 1391 1392 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1393 interpreter, 1394 "thread step-inst", 1395 "Single step one instruction in specified thread (current thread, if none specified).", 1396 NULL, 1397 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1398 eStepTypeTrace, 1399 eStepScopeInstruction))); 1400 1401 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1402 interpreter, 1403 "thread step-inst-over", 1404 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", 1405 NULL, 1406 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, 1407 eStepTypeTraceOver, 1408 eStepScopeInstruction))); 1409 } 1410 1411 CommandObjectMultiwordThread::~CommandObjectMultiwordThread () 1412 { 1413 } 1414 1415 1416