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