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