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/Core/ValueObject.h" 20 #include "lldb/Host/Host.h" 21 #include "lldb/Host/StringConvert.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/SystemRuntime.h" 32 #include "lldb/Target/Target.h" 33 #include "lldb/Target/Thread.h" 34 #include "lldb/Target/ThreadPlan.h" 35 #include "lldb/Target/ThreadPlanStepInstruction.h" 36 #include "lldb/Target/ThreadPlanStepOut.h" 37 #include "lldb/Target/ThreadPlanStepRange.h" 38 #include "lldb/Target/ThreadPlanStepInRange.h" 39 40 using namespace lldb; 41 using namespace lldb_private; 42 43 //------------------------------------------------------------------------- 44 // CommandObjectThreadBacktrace 45 //------------------------------------------------------------------------- 46 47 class CommandObjectIterateOverThreads : public CommandObjectParsed 48 { 49 public: 50 CommandObjectIterateOverThreads (CommandInterpreter &interpreter, 51 const char *name, 52 const char *help, 53 const char *syntax, 54 uint32_t flags) : 55 CommandObjectParsed (interpreter, name, help, syntax, flags) 56 { 57 } 58 59 ~CommandObjectIterateOverThreads() override = default; 60 61 bool 62 DoExecute (Args& command, CommandReturnObject &result) override 63 { 64 result.SetStatus (m_success_return); 65 66 if (command.GetArgumentCount() == 0) 67 { 68 Thread *thread = m_exe_ctx.GetThreadPtr(); 69 if (!HandleOneThread (thread->GetID(), result)) 70 return false; 71 return result.Succeeded(); 72 } 73 74 // Use tids instead of ThreadSPs to prevent deadlocking problems which result from JIT-ing 75 // code while iterating over the (locked) ThreadSP list. 76 std::vector<lldb::tid_t> tids; 77 78 if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) 79 { 80 Process *process = m_exe_ctx.GetProcessPtr(); 81 82 for (ThreadSP thread_sp : process->Threads()) 83 tids.push_back(thread_sp->GetID()); 84 } 85 else 86 { 87 const size_t num_args = command.GetArgumentCount(); 88 Process *process = m_exe_ctx.GetProcessPtr(); 89 90 Mutex::Locker locker (process->GetThreadList().GetMutex()); 91 92 for (size_t i = 0; i < num_args; i++) 93 { 94 bool success; 95 96 uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success); 97 if (!success) 98 { 99 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); 100 result.SetStatus (eReturnStatusFailed); 101 return false; 102 } 103 104 ThreadSP thread = process->GetThreadList().FindThreadByIndexID(thread_idx); 105 106 if (!thread) 107 { 108 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); 109 result.SetStatus (eReturnStatusFailed); 110 return false; 111 } 112 113 tids.push_back(thread->GetID()); 114 } 115 } 116 117 uint32_t idx = 0; 118 for (const lldb::tid_t &tid : tids) 119 { 120 if (idx != 0 && m_add_return) 121 result.AppendMessage(""); 122 123 if (!HandleOneThread (tid, result)) 124 return false; 125 126 ++idx; 127 } 128 return result.Succeeded(); 129 } 130 131 protected: 132 // Override this to do whatever you need to do for one thread. 133 // 134 // If you return false, the iteration will stop, otherwise it will proceed. 135 // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration, 136 // so you only need to set the return status in HandleOneThread if you want to indicate an error. 137 // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.) 138 139 virtual bool 140 HandleOneThread (lldb::tid_t, CommandReturnObject &result) = 0; 141 142 ReturnStatus m_success_return = eReturnStatusSuccessFinishResult; 143 bool m_add_return = true; 144 }; 145 146 //------------------------------------------------------------------------- 147 // CommandObjectThreadBacktrace 148 //------------------------------------------------------------------------- 149 150 class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads 151 { 152 public: 153 class CommandOptions : public Options 154 { 155 public: 156 CommandOptions (CommandInterpreter &interpreter) : 157 Options(interpreter) 158 { 159 // Keep default values of all options in one place: OptionParsingStarting () 160 OptionParsingStarting (); 161 } 162 163 ~CommandOptions() override = default; 164 165 Error 166 SetOptionValue (uint32_t option_idx, const char *option_arg) override 167 { 168 Error error; 169 const int short_option = m_getopt_table[option_idx].val; 170 171 switch (short_option) 172 { 173 case 'c': 174 { 175 bool success; 176 int32_t input_count = StringConvert::ToSInt32 (option_arg, -1, 0, &success); 177 if (!success) 178 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); 179 if (input_count < -1) 180 m_count = UINT32_MAX; 181 else 182 m_count = input_count; 183 } 184 break; 185 case 's': 186 { 187 bool success; 188 m_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 189 if (!success) 190 error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); 191 } 192 break; 193 case 'e': 194 { 195 bool success; 196 m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success); 197 if (!success) 198 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); 199 } 200 break; 201 default: 202 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 203 break; 204 } 205 return error; 206 } 207 208 void 209 OptionParsingStarting () override 210 { 211 m_count = UINT32_MAX; 212 m_start = 0; 213 m_extended_backtrace = false; 214 } 215 216 const OptionDefinition* 217 GetDefinitions () override 218 { 219 return g_option_table; 220 } 221 222 // Options table: Required for subclasses of Options. 223 224 static OptionDefinition g_option_table[]; 225 226 // Instance variables to hold the values for command options. 227 uint32_t m_count; 228 uint32_t m_start; 229 bool m_extended_backtrace; 230 }; 231 232 CommandObjectThreadBacktrace (CommandInterpreter &interpreter) : 233 CommandObjectIterateOverThreads(interpreter, 234 "thread backtrace", 235 "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.", 236 nullptr, 237 eCommandRequiresProcess | 238 eCommandRequiresThread | 239 eCommandTryTargetAPILock | 240 eCommandProcessMustBeLaunched | 241 eCommandProcessMustBePaused ), 242 m_options(interpreter) 243 { 244 } 245 246 ~CommandObjectThreadBacktrace() override = default; 247 248 Options * 249 GetOptions () override 250 { 251 return &m_options; 252 } 253 254 protected: 255 void 256 DoExtendedBacktrace (Thread *thread, CommandReturnObject &result) 257 { 258 SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime(); 259 if (runtime) 260 { 261 Stream &strm = result.GetOutputStream(); 262 const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes(); 263 for (auto type : types) 264 { 265 ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type); 266 if (ext_thread_sp && ext_thread_sp->IsValid ()) 267 { 268 const uint32_t num_frames_with_source = 0; 269 if (ext_thread_sp->GetStatus (strm, 270 m_options.m_start, 271 m_options.m_count, 272 num_frames_with_source)) 273 { 274 DoExtendedBacktrace (ext_thread_sp.get(), result); 275 } 276 } 277 } 278 } 279 } 280 281 bool 282 HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override 283 { 284 ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); 285 if (!thread_sp) 286 { 287 result.AppendErrorWithFormat ("thread disappeared while computing backtraces: 0x%" PRIx64 "\n", tid); 288 result.SetStatus (eReturnStatusFailed); 289 return false; 290 } 291 292 Thread *thread = thread_sp.get(); 293 294 Stream &strm = result.GetOutputStream(); 295 296 // Don't show source context when doing backtraces. 297 const uint32_t num_frames_with_source = 0; 298 299 if (!thread->GetStatus (strm, 300 m_options.m_start, 301 m_options.m_count, 302 num_frames_with_source)) 303 { 304 result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread->GetIndexID()); 305 result.SetStatus (eReturnStatusFailed); 306 return false; 307 } 308 if (m_options.m_extended_backtrace) 309 { 310 DoExtendedBacktrace (thread, result); 311 } 312 313 return true; 314 } 315 316 CommandOptions m_options; 317 }; 318 319 OptionDefinition 320 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] = 321 { 322 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, 323 { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, 324 { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, 325 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 326 }; 327 328 enum StepScope 329 { 330 eStepScopeSource, 331 eStepScopeInstruction 332 }; 333 334 class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed 335 { 336 public: 337 class CommandOptions : public Options 338 { 339 public: 340 CommandOptions (CommandInterpreter &interpreter) : 341 Options (interpreter) 342 { 343 // Keep default values of all options in one place: OptionParsingStarting () 344 OptionParsingStarting (); 345 } 346 347 ~CommandOptions() override = default; 348 349 Error 350 SetOptionValue (uint32_t option_idx, const char *option_arg) override 351 { 352 Error error; 353 const int short_option = m_getopt_table[option_idx].val; 354 355 switch (short_option) 356 { 357 case 'a': 358 { 359 bool success; 360 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success); 361 if (!success) 362 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); 363 else 364 { 365 m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; 366 } 367 } 368 break; 369 370 case 'A': 371 { 372 bool success; 373 bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success); 374 if (!success) 375 error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); 376 else 377 { 378 m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; 379 } 380 } 381 break; 382 383 case 'c': 384 m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 385 if (m_step_count == UINT32_MAX) 386 error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg); 387 break; 388 389 case 'C': 390 m_class_name.clear(); 391 m_class_name.assign(option_arg); 392 break; 393 394 case 'm': 395 { 396 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 397 m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 398 } 399 break; 400 401 case 'e': 402 { 403 if (strcmp(option_arg, "block") == 0) 404 { 405 m_end_line_is_block_end = 1; 406 break; 407 } 408 uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 409 if (tmp_end_line == UINT32_MAX) 410 error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg); 411 else 412 m_end_line = tmp_end_line; 413 break; 414 } 415 break; 416 417 case 'r': 418 m_avoid_regexp.clear(); 419 m_avoid_regexp.assign(option_arg); 420 break; 421 422 case 't': 423 m_step_in_target.clear(); 424 m_step_in_target.assign(option_arg); 425 break; 426 427 default: 428 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 429 break; 430 } 431 return error; 432 } 433 434 void 435 OptionParsingStarting () override 436 { 437 m_step_in_avoid_no_debug = eLazyBoolCalculate; 438 m_step_out_avoid_no_debug = eLazyBoolCalculate; 439 m_run_mode = eOnlyDuringStepping; 440 441 // Check if we are in Non-Stop mode 442 lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 443 if (target_sp && target_sp->GetNonStopModeEnabled()) 444 m_run_mode = eOnlyThisThread; 445 446 m_avoid_regexp.clear(); 447 m_step_in_target.clear(); 448 m_class_name.clear(); 449 m_step_count = 1; 450 m_end_line = LLDB_INVALID_LINE_NUMBER; 451 m_end_line_is_block_end = false; 452 } 453 454 const OptionDefinition* 455 GetDefinitions () override 456 { 457 return g_option_table; 458 } 459 460 // Options table: Required for subclasses of Options. 461 462 static OptionDefinition g_option_table[]; 463 464 // Instance variables to hold the values for command options. 465 LazyBool m_step_in_avoid_no_debug; 466 LazyBool m_step_out_avoid_no_debug; 467 RunMode m_run_mode; 468 std::string m_avoid_regexp; 469 std::string m_step_in_target; 470 std::string m_class_name; 471 uint32_t m_step_count; 472 uint32_t m_end_line; 473 bool m_end_line_is_block_end; 474 }; 475 476 CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter, 477 const char *name, 478 const char *help, 479 const char *syntax, 480 StepType step_type, 481 StepScope step_scope) : 482 CommandObjectParsed (interpreter, name, help, syntax, 483 eCommandRequiresProcess | 484 eCommandRequiresThread | 485 eCommandTryTargetAPILock | 486 eCommandProcessMustBeLaunched | 487 eCommandProcessMustBePaused ), 488 m_step_type (step_type), 489 m_step_scope (step_scope), 490 m_options (interpreter) 491 { 492 CommandArgumentEntry arg; 493 CommandArgumentData thread_id_arg; 494 495 // Define the first (and only) variant of this arg. 496 thread_id_arg.arg_type = eArgTypeThreadID; 497 thread_id_arg.arg_repetition = eArgRepeatOptional; 498 499 // There is only one variant this argument could be; put it into the argument entry. 500 arg.push_back (thread_id_arg); 501 502 // Push the data for the first argument into the m_arguments vector. 503 m_arguments.push_back (arg); 504 } 505 506 ~CommandObjectThreadStepWithTypeAndScope() override = default; 507 508 Options * 509 GetOptions () override 510 { 511 return &m_options; 512 } 513 514 protected: 515 bool 516 DoExecute (Args& command, CommandReturnObject &result) override 517 { 518 Process *process = m_exe_ctx.GetProcessPtr(); 519 bool synchronous_execution = m_interpreter.GetSynchronous(); 520 521 const uint32_t num_threads = process->GetThreadList().GetSize(); 522 Thread *thread = nullptr; 523 524 if (command.GetArgumentCount() == 0) 525 { 526 thread = GetDefaultThread(); 527 528 if (thread == nullptr) 529 { 530 result.AppendError ("no selected thread in process"); 531 result.SetStatus (eReturnStatusFailed); 532 return false; 533 } 534 } 535 else 536 { 537 const char *thread_idx_cstr = command.GetArgumentAtIndex(0); 538 uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32); 539 if (step_thread_idx == LLDB_INVALID_INDEX32) 540 { 541 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr); 542 result.SetStatus (eReturnStatusFailed); 543 return false; 544 } 545 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get(); 546 if (thread == nullptr) 547 { 548 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 549 step_thread_idx, num_threads); 550 result.SetStatus (eReturnStatusFailed); 551 return false; 552 } 553 } 554 555 if (m_step_type == eStepTypeScripted) 556 { 557 if (m_options.m_class_name.empty()) 558 { 559 result.AppendErrorWithFormat ("empty class name for scripted step."); 560 result.SetStatus(eReturnStatusFailed); 561 return false; 562 } 563 else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str())) 564 { 565 result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str()); 566 result.SetStatus(eReturnStatusFailed); 567 return false; 568 } 569 } 570 571 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER 572 && m_step_type != eStepTypeInto) 573 { 574 result.AppendErrorWithFormat("end line option is only valid for step into"); 575 result.SetStatus(eReturnStatusFailed); 576 return false; 577 } 578 579 const bool abort_other_plans = false; 580 const lldb::RunMode stop_other_threads = m_options.m_run_mode; 581 582 // This is a bit unfortunate, but not all the commands in this command object support 583 // only while stepping, so I use the bool for them. 584 bool bool_stop_other_threads; 585 if (m_options.m_run_mode == eAllThreads) 586 bool_stop_other_threads = false; 587 else if (m_options.m_run_mode == eOnlyDuringStepping) 588 bool_stop_other_threads = (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted); 589 else 590 bool_stop_other_threads = true; 591 592 ThreadPlanSP new_plan_sp; 593 594 if (m_step_type == eStepTypeInto) 595 { 596 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 597 assert(frame != nullptr); 598 599 if (frame->HasDebugInformation ()) 600 { 601 AddressRange range; 602 SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything); 603 if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER) 604 { 605 Error error; 606 if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range, error)) 607 { 608 result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString()); 609 result.SetStatus(eReturnStatusFailed); 610 return false; 611 } 612 } 613 else if (m_options.m_end_line_is_block_end) 614 { 615 Error error; 616 Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; 617 if (!block) 618 { 619 result.AppendErrorWithFormat("Could not find the current block."); 620 result.SetStatus(eReturnStatusFailed); 621 return false; 622 } 623 624 AddressRange block_range; 625 Address pc_address = frame->GetFrameCodeAddress(); 626 block->GetRangeContainingAddress(pc_address, block_range); 627 if (!block_range.GetBaseAddress().IsValid()) 628 { 629 result.AppendErrorWithFormat("Could not find the current block address."); 630 result.SetStatus(eReturnStatusFailed); 631 return false; 632 } 633 lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress(); 634 lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block; 635 range = AddressRange(pc_address, range_length); 636 } 637 else 638 { 639 range = sc.line_entry.range; 640 } 641 642 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 643 range, 644 frame->GetSymbolContext(eSymbolContextEverything), 645 m_options.m_step_in_target.c_str(), 646 stop_other_threads, 647 m_options.m_step_in_avoid_no_debug, 648 m_options.m_step_out_avoid_no_debug); 649 650 if (new_plan_sp && !m_options.m_avoid_regexp.empty()) 651 { 652 ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get()); 653 step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); 654 } 655 } 656 else 657 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 658 } 659 else if (m_step_type == eStepTypeOver) 660 { 661 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 662 663 if (frame->HasDebugInformation()) 664 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 665 frame->GetSymbolContext(eSymbolContextEverything).line_entry, 666 frame->GetSymbolContext(eSymbolContextEverything), 667 stop_other_threads, 668 m_options.m_step_out_avoid_no_debug); 669 else 670 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 671 abort_other_plans, 672 bool_stop_other_threads); 673 } 674 else if (m_step_type == eStepTypeTrace) 675 { 676 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); 677 } 678 else if (m_step_type == eStepTypeTraceOver) 679 { 680 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); 681 } 682 else if (m_step_type == eStepTypeOut) 683 { 684 new_plan_sp = thread->QueueThreadPlanForStepOut(abort_other_plans, 685 nullptr, 686 false, 687 bool_stop_other_threads, 688 eVoteYes, 689 eVoteNoOpinion, 690 thread->GetSelectedFrameIndex(), 691 m_options.m_step_out_avoid_no_debug); 692 } 693 else if (m_step_type == eStepTypeScripted) 694 { 695 new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans, 696 m_options.m_class_name.c_str(), 697 bool_stop_other_threads); 698 } 699 else 700 { 701 result.AppendError ("step type is not supported"); 702 result.SetStatus (eReturnStatusFailed); 703 return false; 704 } 705 706 // If we got a new plan, then set it to be a master plan (User level Plans should be master plans 707 // so that they can be interruptible). Then resume the process. 708 709 if (new_plan_sp) 710 { 711 new_plan_sp->SetIsMasterPlan (true); 712 new_plan_sp->SetOkayToDiscard (false); 713 714 if (m_options.m_step_count > 1) 715 { 716 if (new_plan_sp->SetIterationCount(m_options.m_step_count)) 717 { 718 result.AppendWarning ("step operation does not support iteration count."); 719 } 720 } 721 722 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 723 724 const uint32_t iohandler_id = process->GetIOHandlerID(); 725 726 StreamString stream; 727 Error error; 728 if (synchronous_execution) 729 error = process->ResumeSynchronous (&stream); 730 else 731 error = process->Resume (); 732 733 // There is a race condition where this thread will return up the call stack to the main command handler 734 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has 735 // a chance to call PushProcessIOHandler(). 736 process->SyncIOHandler(iohandler_id, 2000); 737 738 if (synchronous_execution) 739 { 740 // If any state changed events had anything to say, add that to the result 741 if (stream.GetData()) 742 result.AppendMessage(stream.GetData()); 743 744 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 745 result.SetDidChangeProcessState (true); 746 result.SetStatus (eReturnStatusSuccessFinishNoResult); 747 } 748 else 749 { 750 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 751 } 752 } 753 else 754 { 755 result.AppendError ("Couldn't find thread plan to implement step type."); 756 result.SetStatus (eReturnStatusFailed); 757 } 758 return result.Succeeded(); 759 } 760 761 protected: 762 StepType m_step_type; 763 StepScope m_step_scope; 764 CommandOptions m_options; 765 }; 766 767 static OptionEnumValueElement 768 g_tri_running_mode[] = 769 { 770 { eOnlyThisThread, "this-thread", "Run only this thread"}, 771 { eAllThreads, "all-threads", "Run all threads"}, 772 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"}, 773 { 0, nullptr, nullptr } 774 }; 775 776 static OptionEnumValueElement 777 g_duo_running_mode[] = 778 { 779 { eOnlyThisThread, "this-thread", "Run only this thread"}, 780 { eAllThreads, "all-threads", "Run all threads"}, 781 { 0, nullptr, nullptr } 782 }; 783 784 OptionDefinition 785 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = 786 { 787 { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."}, 788 { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."}, 789 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."}, 790 { LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over." 791 " You can also pass the string 'block' to step to the end of the current block." 792 " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."}, 793 { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."}, 794 { LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."}, 795 { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, 796 { LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."}, 797 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 798 }; 799 800 //------------------------------------------------------------------------- 801 // CommandObjectThreadContinue 802 //------------------------------------------------------------------------- 803 804 class CommandObjectThreadContinue : public CommandObjectParsed 805 { 806 public: 807 CommandObjectThreadContinue (CommandInterpreter &interpreter) : 808 CommandObjectParsed(interpreter, 809 "thread continue", 810 "Continue execution of one or more threads in an active process.", 811 nullptr, 812 eCommandRequiresThread | 813 eCommandTryTargetAPILock | 814 eCommandProcessMustBeLaunched | 815 eCommandProcessMustBePaused) 816 { 817 CommandArgumentEntry arg; 818 CommandArgumentData thread_idx_arg; 819 820 // Define the first (and only) variant of this arg. 821 thread_idx_arg.arg_type = eArgTypeThreadIndex; 822 thread_idx_arg.arg_repetition = eArgRepeatPlus; 823 824 // There is only one variant this argument could be; put it into the argument entry. 825 arg.push_back (thread_idx_arg); 826 827 // Push the data for the first argument into the m_arguments vector. 828 m_arguments.push_back (arg); 829 } 830 831 ~CommandObjectThreadContinue() override = default; 832 833 bool 834 DoExecute (Args& command, CommandReturnObject &result) override 835 { 836 bool synchronous_execution = m_interpreter.GetSynchronous (); 837 838 if (!m_interpreter.GetDebugger().GetSelectedTarget()) 839 { 840 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 841 result.SetStatus (eReturnStatusFailed); 842 return false; 843 } 844 845 Process *process = m_exe_ctx.GetProcessPtr(); 846 if (process == nullptr) 847 { 848 result.AppendError ("no process exists. Cannot continue"); 849 result.SetStatus (eReturnStatusFailed); 850 return false; 851 } 852 853 StateType state = process->GetState(); 854 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended)) 855 { 856 const size_t argc = command.GetArgumentCount(); 857 if (argc > 0) 858 { 859 // These two lines appear at the beginning of both blocks in 860 // this if..else, but that is because we need to release the 861 // lock before calling process->Resume below. 862 Mutex::Locker locker (process->GetThreadList().GetMutex()); 863 const uint32_t num_threads = process->GetThreadList().GetSize(); 864 std::vector<Thread *> resume_threads; 865 for (uint32_t i = 0; i < argc; ++i) 866 { 867 bool success; 868 const int base = 0; 869 uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success); 870 if (success) 871 { 872 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get(); 873 874 if (thread) 875 { 876 resume_threads.push_back(thread); 877 } 878 else 879 { 880 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx); 881 result.SetStatus (eReturnStatusFailed); 882 return false; 883 } 884 } 885 else 886 { 887 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i)); 888 result.SetStatus (eReturnStatusFailed); 889 return false; 890 } 891 } 892 893 if (resume_threads.empty()) 894 { 895 result.AppendError ("no valid thread indexes were specified"); 896 result.SetStatus (eReturnStatusFailed); 897 return false; 898 } 899 else 900 { 901 if (resume_threads.size() == 1) 902 result.AppendMessageWithFormat ("Resuming thread: "); 903 else 904 result.AppendMessageWithFormat ("Resuming threads: "); 905 906 for (uint32_t idx = 0; idx < num_threads; ++idx) 907 { 908 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 909 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread); 910 911 if (this_thread_pos != resume_threads.end()) 912 { 913 resume_threads.erase(this_thread_pos); 914 if (!resume_threads.empty()) 915 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID()); 916 else 917 result.AppendMessageWithFormat ("%u ", thread->GetIndexID()); 918 919 const bool override_suspend = true; 920 thread->SetResumeState (eStateRunning, override_suspend); 921 } 922 else 923 { 924 thread->SetResumeState (eStateSuspended); 925 } 926 } 927 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID()); 928 } 929 } 930 else 931 { 932 // These two lines appear at the beginning of both blocks in 933 // this if..else, but that is because we need to release the 934 // lock before calling process->Resume below. 935 Mutex::Locker locker (process->GetThreadList().GetMutex()); 936 const uint32_t num_threads = process->GetThreadList().GetSize(); 937 Thread *current_thread = GetDefaultThread(); 938 if (current_thread == nullptr) 939 { 940 result.AppendError ("the process doesn't have a current thread"); 941 result.SetStatus (eReturnStatusFailed); 942 return false; 943 } 944 // Set the actions that the threads should each take when resuming 945 for (uint32_t idx = 0; idx < num_threads; ++idx) 946 { 947 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 948 if (thread == current_thread) 949 { 950 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID()); 951 const bool override_suspend = true; 952 thread->SetResumeState (eStateRunning, override_suspend); 953 } 954 else 955 { 956 thread->SetResumeState (eStateSuspended); 957 } 958 } 959 } 960 961 StreamString stream; 962 Error error; 963 if (synchronous_execution) 964 error = process->ResumeSynchronous (&stream); 965 else 966 error = process->Resume (); 967 968 // We should not be holding the thread list lock when we do this. 969 if (error.Success()) 970 { 971 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 972 if (synchronous_execution) 973 { 974 // If any state changed events had anything to say, add that to the result 975 if (stream.GetData()) 976 result.AppendMessage(stream.GetData()); 977 978 result.SetDidChangeProcessState (true); 979 result.SetStatus (eReturnStatusSuccessFinishNoResult); 980 } 981 else 982 { 983 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 984 } 985 } 986 else 987 { 988 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString()); 989 result.SetStatus (eReturnStatusFailed); 990 } 991 } 992 else 993 { 994 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 995 StateAsCString(state)); 996 result.SetStatus (eReturnStatusFailed); 997 } 998 999 return result.Succeeded(); 1000 } 1001 }; 1002 1003 //------------------------------------------------------------------------- 1004 // CommandObjectThreadUntil 1005 //------------------------------------------------------------------------- 1006 1007 class CommandObjectThreadUntil : public CommandObjectParsed 1008 { 1009 public: 1010 class CommandOptions : public Options 1011 { 1012 public: 1013 uint32_t m_thread_idx; 1014 uint32_t m_frame_idx; 1015 1016 CommandOptions (CommandInterpreter &interpreter) : 1017 Options (interpreter), 1018 m_thread_idx(LLDB_INVALID_THREAD_ID), 1019 m_frame_idx(LLDB_INVALID_FRAME_ID) 1020 { 1021 // Keep default values of all options in one place: OptionParsingStarting () 1022 OptionParsingStarting (); 1023 } 1024 1025 ~CommandOptions() override = default; 1026 1027 Error 1028 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1029 { 1030 Error error; 1031 const int short_option = m_getopt_table[option_idx].val; 1032 1033 switch (short_option) 1034 { 1035 case 'a': 1036 { 1037 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 1038 lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 1039 if (error.Success()) 1040 m_until_addrs.push_back(tmp_addr); 1041 } 1042 break; 1043 case 't': 1044 m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32); 1045 if (m_thread_idx == LLDB_INVALID_INDEX32) 1046 { 1047 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg); 1048 } 1049 break; 1050 case 'f': 1051 m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID); 1052 if (m_frame_idx == LLDB_INVALID_FRAME_ID) 1053 { 1054 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg); 1055 } 1056 break; 1057 case 'm': 1058 { 1059 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 1060 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 1061 1062 if (error.Success()) 1063 { 1064 if (run_mode == eAllThreads) 1065 m_stop_others = false; 1066 else 1067 m_stop_others = true; 1068 } 1069 } 1070 break; 1071 default: 1072 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1073 break; 1074 } 1075 return error; 1076 } 1077 1078 void 1079 OptionParsingStarting () override 1080 { 1081 m_thread_idx = LLDB_INVALID_THREAD_ID; 1082 m_frame_idx = 0; 1083 m_stop_others = false; 1084 m_until_addrs.clear(); 1085 } 1086 1087 const OptionDefinition* 1088 GetDefinitions () override 1089 { 1090 return g_option_table; 1091 } 1092 1093 uint32_t m_step_thread_idx; 1094 bool m_stop_others; 1095 std::vector<lldb::addr_t> m_until_addrs; 1096 1097 // Options table: Required for subclasses of Options. 1098 1099 static OptionDefinition g_option_table[]; 1100 1101 // Instance variables to hold the values for command options. 1102 }; 1103 1104 CommandObjectThreadUntil (CommandInterpreter &interpreter) : 1105 CommandObjectParsed(interpreter, 1106 "thread until", 1107 "Run the current or specified thread until it reaches a given line number or address or leaves the current function.", 1108 nullptr, 1109 eCommandRequiresThread | 1110 eCommandTryTargetAPILock | 1111 eCommandProcessMustBeLaunched | 1112 eCommandProcessMustBePaused ), 1113 m_options (interpreter) 1114 { 1115 CommandArgumentEntry arg; 1116 CommandArgumentData line_num_arg; 1117 1118 // Define the first (and only) variant of this arg. 1119 line_num_arg.arg_type = eArgTypeLineNum; 1120 line_num_arg.arg_repetition = eArgRepeatPlain; 1121 1122 // There is only one variant this argument could be; put it into the argument entry. 1123 arg.push_back (line_num_arg); 1124 1125 // Push the data for the first argument into the m_arguments vector. 1126 m_arguments.push_back (arg); 1127 } 1128 1129 ~CommandObjectThreadUntil() override = default; 1130 1131 Options * 1132 GetOptions () override 1133 { 1134 return &m_options; 1135 } 1136 1137 protected: 1138 bool 1139 DoExecute (Args& command, CommandReturnObject &result) override 1140 { 1141 bool synchronous_execution = m_interpreter.GetSynchronous (); 1142 1143 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1144 if (target == nullptr) 1145 { 1146 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 1147 result.SetStatus (eReturnStatusFailed); 1148 return false; 1149 } 1150 1151 Process *process = m_exe_ctx.GetProcessPtr(); 1152 if (process == nullptr) 1153 { 1154 result.AppendError ("need a valid process to step"); 1155 result.SetStatus (eReturnStatusFailed); 1156 } 1157 else 1158 { 1159 Thread *thread = nullptr; 1160 std::vector<uint32_t> line_numbers; 1161 1162 if (command.GetArgumentCount() >= 1) 1163 { 1164 size_t num_args = command.GetArgumentCount(); 1165 for (size_t i = 0; i < num_args; i++) 1166 { 1167 uint32_t line_number; 1168 line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); 1169 if (line_number == UINT32_MAX) 1170 { 1171 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); 1172 result.SetStatus (eReturnStatusFailed); 1173 return false; 1174 } 1175 else 1176 line_numbers.push_back(line_number); 1177 } 1178 } 1179 else if (m_options.m_until_addrs.empty()) 1180 { 1181 result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax()); 1182 result.SetStatus (eReturnStatusFailed); 1183 return false; 1184 } 1185 1186 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) 1187 { 1188 thread = GetDefaultThread(); 1189 } 1190 else 1191 { 1192 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get(); 1193 } 1194 1195 if (thread == nullptr) 1196 { 1197 const uint32_t num_threads = process->GetThreadList().GetSize(); 1198 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 1199 m_options.m_thread_idx, 1200 num_threads); 1201 result.SetStatus (eReturnStatusFailed); 1202 return false; 1203 } 1204 1205 const bool abort_other_plans = false; 1206 1207 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get(); 1208 if (frame == nullptr) 1209 { 1210 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", 1211 m_options.m_frame_idx, 1212 m_options.m_thread_idx); 1213 result.SetStatus (eReturnStatusFailed); 1214 return false; 1215 } 1216 1217 ThreadPlanSP new_plan_sp; 1218 1219 if (frame->HasDebugInformation ()) 1220 { 1221 // Finally we got here... Translate the given line number to a bunch of addresses: 1222 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit)); 1223 LineTable *line_table = nullptr; 1224 if (sc.comp_unit) 1225 line_table = sc.comp_unit->GetLineTable(); 1226 1227 if (line_table == nullptr) 1228 { 1229 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n", 1230 m_options.m_frame_idx, m_options.m_thread_idx); 1231 result.SetStatus (eReturnStatusFailed); 1232 return false; 1233 } 1234 1235 LineEntry function_start; 1236 uint32_t index_ptr = 0, end_ptr; 1237 std::vector<addr_t> address_list; 1238 1239 // Find the beginning & end index of the 1240 AddressRange fun_addr_range = sc.function->GetAddressRange(); 1241 Address fun_start_addr = fun_addr_range.GetBaseAddress(); 1242 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr); 1243 1244 Address fun_end_addr(fun_start_addr.GetSection(), 1245 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); 1246 1247 bool all_in_function = true; 1248 1249 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); 1250 1251 for (uint32_t line_number : line_numbers) 1252 { 1253 uint32_t start_idx_ptr = index_ptr; 1254 while (start_idx_ptr <= end_ptr) 1255 { 1256 LineEntry line_entry; 1257 const bool exact = false; 1258 start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry); 1259 if (start_idx_ptr == UINT32_MAX) 1260 break; 1261 1262 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); 1263 if (address != LLDB_INVALID_ADDRESS) 1264 { 1265 if (fun_addr_range.ContainsLoadAddress (address, target)) 1266 address_list.push_back (address); 1267 else 1268 all_in_function = false; 1269 } 1270 start_idx_ptr++; 1271 } 1272 } 1273 1274 for (lldb::addr_t address : m_options.m_until_addrs) 1275 { 1276 if (fun_addr_range.ContainsLoadAddress (address, target)) 1277 address_list.push_back (address); 1278 else 1279 all_in_function = false; 1280 } 1281 1282 if (address_list.empty()) 1283 { 1284 if (all_in_function) 1285 result.AppendErrorWithFormat ("No line entries matching until target.\n"); 1286 else 1287 result.AppendErrorWithFormat ("Until target outside of the current function.\n"); 1288 1289 result.SetStatus (eReturnStatusFailed); 1290 return false; 1291 } 1292 1293 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans, 1294 &address_list.front(), 1295 address_list.size(), 1296 m_options.m_stop_others, 1297 m_options.m_frame_idx); 1298 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint) 1299 // and other plans executed by the user (stepping around the breakpoint) and then a "continue" 1300 // will resume the original plan. 1301 new_plan_sp->SetIsMasterPlan (true); 1302 new_plan_sp->SetOkayToDiscard(false); 1303 } 1304 else 1305 { 1306 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", 1307 m_options.m_frame_idx, 1308 m_options.m_thread_idx); 1309 result.SetStatus (eReturnStatusFailed); 1310 return false; 1311 } 1312 1313 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); 1314 1315 StreamString stream; 1316 Error error; 1317 if (synchronous_execution) 1318 error = process->ResumeSynchronous (&stream); 1319 else 1320 error = process->Resume (); 1321 1322 if (error.Success()) 1323 { 1324 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 1325 if (synchronous_execution) 1326 { 1327 // If any state changed events had anything to say, add that to the result 1328 if (stream.GetData()) 1329 result.AppendMessage(stream.GetData()); 1330 1331 result.SetDidChangeProcessState (true); 1332 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1333 } 1334 else 1335 { 1336 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 1337 } 1338 } 1339 else 1340 { 1341 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 1342 result.SetStatus (eReturnStatusFailed); 1343 } 1344 1345 } 1346 return result.Succeeded(); 1347 } 1348 1349 CommandOptions m_options; 1350 }; 1351 1352 OptionDefinition 1353 CommandObjectThreadUntil::CommandOptions::g_option_table[] = 1354 { 1355 { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, 1356 { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, 1357 { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"}, 1358 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."}, 1359 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 1360 }; 1361 1362 //------------------------------------------------------------------------- 1363 // CommandObjectThreadSelect 1364 //------------------------------------------------------------------------- 1365 1366 class CommandObjectThreadSelect : public CommandObjectParsed 1367 { 1368 public: 1369 CommandObjectThreadSelect (CommandInterpreter &interpreter) : 1370 CommandObjectParsed(interpreter, 1371 "thread select", 1372 "Select a thread as the currently active thread.", 1373 nullptr, 1374 eCommandRequiresProcess | 1375 eCommandTryTargetAPILock | 1376 eCommandProcessMustBeLaunched | 1377 eCommandProcessMustBePaused ) 1378 { 1379 CommandArgumentEntry arg; 1380 CommandArgumentData thread_idx_arg; 1381 1382 // Define the first (and only) variant of this arg. 1383 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1384 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1385 1386 // There is only one variant this argument could be; put it into the argument entry. 1387 arg.push_back (thread_idx_arg); 1388 1389 // Push the data for the first argument into the m_arguments vector. 1390 m_arguments.push_back (arg); 1391 } 1392 1393 ~CommandObjectThreadSelect() override = default; 1394 1395 protected: 1396 bool 1397 DoExecute (Args& command, CommandReturnObject &result) override 1398 { 1399 Process *process = m_exe_ctx.GetProcessPtr(); 1400 if (process == nullptr) 1401 { 1402 result.AppendError ("no process"); 1403 result.SetStatus (eReturnStatusFailed); 1404 return false; 1405 } 1406 else if (command.GetArgumentCount() != 1) 1407 { 1408 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1409 result.SetStatus (eReturnStatusFailed); 1410 return false; 1411 } 1412 1413 uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); 1414 1415 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); 1416 if (new_thread == nullptr) 1417 { 1418 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0)); 1419 result.SetStatus (eReturnStatusFailed); 1420 return false; 1421 } 1422 1423 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true); 1424 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1425 1426 return result.Succeeded(); 1427 } 1428 }; 1429 1430 //------------------------------------------------------------------------- 1431 // CommandObjectThreadList 1432 //------------------------------------------------------------------------- 1433 1434 class CommandObjectThreadList : public CommandObjectParsed 1435 { 1436 public: 1437 CommandObjectThreadList (CommandInterpreter &interpreter): 1438 CommandObjectParsed (interpreter, 1439 "thread list", 1440 "Show a summary of all current threads in a process.", 1441 "thread list", 1442 eCommandRequiresProcess | 1443 eCommandTryTargetAPILock | 1444 eCommandProcessMustBeLaunched | 1445 eCommandProcessMustBePaused ) 1446 { 1447 } 1448 1449 ~CommandObjectThreadList() override = default; 1450 1451 protected: 1452 bool 1453 DoExecute (Args& command, CommandReturnObject &result) override 1454 { 1455 Stream &strm = result.GetOutputStream(); 1456 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1457 Process *process = m_exe_ctx.GetProcessPtr(); 1458 const bool only_threads_with_stop_reason = false; 1459 const uint32_t start_frame = 0; 1460 const uint32_t num_frames = 0; 1461 const uint32_t num_frames_with_source = 0; 1462 process->GetStatus(strm); 1463 process->GetThreadStatus (strm, 1464 only_threads_with_stop_reason, 1465 start_frame, 1466 num_frames, 1467 num_frames_with_source); 1468 return result.Succeeded(); 1469 } 1470 }; 1471 1472 //------------------------------------------------------------------------- 1473 // CommandObjectThreadInfo 1474 //------------------------------------------------------------------------- 1475 1476 class CommandObjectThreadInfo : public CommandObjectIterateOverThreads 1477 { 1478 public: 1479 class CommandOptions : public Options 1480 { 1481 public: 1482 CommandOptions (CommandInterpreter &interpreter) : 1483 Options (interpreter) 1484 { 1485 OptionParsingStarting (); 1486 } 1487 1488 ~CommandOptions() override = default; 1489 1490 void 1491 OptionParsingStarting () override 1492 { 1493 m_json_thread = false; 1494 m_json_stopinfo = false; 1495 } 1496 1497 Error 1498 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1499 { 1500 const int short_option = m_getopt_table[option_idx].val; 1501 Error error; 1502 1503 switch (short_option) 1504 { 1505 case 'j': 1506 m_json_thread = true; 1507 break; 1508 1509 case 's': 1510 m_json_stopinfo = true; 1511 break; 1512 1513 default: 1514 return Error("invalid short option character '%c'", short_option); 1515 } 1516 return error; 1517 } 1518 1519 const OptionDefinition* 1520 GetDefinitions () override 1521 { 1522 return g_option_table; 1523 } 1524 1525 bool m_json_thread; 1526 bool m_json_stopinfo; 1527 1528 static OptionDefinition g_option_table[]; 1529 }; 1530 1531 CommandObjectThreadInfo (CommandInterpreter &interpreter) : 1532 CommandObjectIterateOverThreads (interpreter, 1533 "thread info", 1534 "Show an extended summary of information about thread(s) in a process.", 1535 "thread info", 1536 eCommandRequiresProcess | 1537 eCommandTryTargetAPILock | 1538 eCommandProcessMustBeLaunched | 1539 eCommandProcessMustBePaused), 1540 m_options (interpreter) 1541 { 1542 m_add_return = false; 1543 } 1544 1545 ~CommandObjectThreadInfo() override = default; 1546 1547 Options * 1548 GetOptions () override 1549 { 1550 return &m_options; 1551 } 1552 1553 bool 1554 HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override 1555 { 1556 ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); 1557 if (!thread_sp) 1558 { 1559 result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid); 1560 result.SetStatus (eReturnStatusFailed); 1561 return false; 1562 } 1563 1564 Thread *thread = thread_sp.get(); 1565 1566 Stream &strm = result.GetOutputStream(); 1567 if (!thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo)) 1568 { 1569 result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread->GetIndexID()); 1570 result.SetStatus (eReturnStatusFailed); 1571 return false; 1572 } 1573 return true; 1574 } 1575 1576 CommandOptions m_options; 1577 }; 1578 1579 OptionDefinition 1580 CommandObjectThreadInfo::CommandOptions::g_option_table[] = 1581 { 1582 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format."}, 1583 { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format."}, 1584 1585 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 1586 }; 1587 1588 //------------------------------------------------------------------------- 1589 // CommandObjectThreadReturn 1590 //------------------------------------------------------------------------- 1591 1592 class CommandObjectThreadReturn : public CommandObjectRaw 1593 { 1594 public: 1595 class CommandOptions : public Options 1596 { 1597 public: 1598 CommandOptions (CommandInterpreter &interpreter) : 1599 Options (interpreter), 1600 m_from_expression (false) 1601 { 1602 // Keep default values of all options in one place: OptionParsingStarting () 1603 OptionParsingStarting (); 1604 } 1605 1606 ~CommandOptions() override = default; 1607 1608 Error 1609 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1610 { 1611 Error error; 1612 const int short_option = m_getopt_table[option_idx].val; 1613 1614 switch (short_option) 1615 { 1616 case 'x': 1617 { 1618 bool success; 1619 bool tmp_value = Args::StringToBoolean (option_arg, false, &success); 1620 if (success) 1621 m_from_expression = tmp_value; 1622 else 1623 { 1624 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg); 1625 } 1626 } 1627 break; 1628 default: 1629 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1630 break; 1631 } 1632 return error; 1633 } 1634 1635 void 1636 OptionParsingStarting () override 1637 { 1638 m_from_expression = false; 1639 } 1640 1641 const OptionDefinition* 1642 GetDefinitions () override 1643 { 1644 return g_option_table; 1645 } 1646 1647 bool m_from_expression; 1648 1649 // Options table: Required for subclasses of Options. 1650 1651 static OptionDefinition g_option_table[]; 1652 1653 // Instance variables to hold the values for command options. 1654 }; 1655 1656 CommandObjectThreadReturn (CommandInterpreter &interpreter) : 1657 CommandObjectRaw (interpreter, 1658 "thread return", 1659 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value," 1660 " or with the -x option from the innermost function evaluation.", 1661 "thread return", 1662 eCommandRequiresFrame | 1663 eCommandTryTargetAPILock | 1664 eCommandProcessMustBeLaunched | 1665 eCommandProcessMustBePaused ), 1666 m_options (interpreter) 1667 { 1668 CommandArgumentEntry arg; 1669 CommandArgumentData expression_arg; 1670 1671 // Define the first (and only) variant of this arg. 1672 expression_arg.arg_type = eArgTypeExpression; 1673 expression_arg.arg_repetition = eArgRepeatOptional; 1674 1675 // There is only one variant this argument could be; put it into the argument entry. 1676 arg.push_back (expression_arg); 1677 1678 // Push the data for the first argument into the m_arguments vector. 1679 m_arguments.push_back (arg); 1680 } 1681 1682 ~CommandObjectThreadReturn() override = default; 1683 1684 Options * 1685 GetOptions() override 1686 { 1687 return &m_options; 1688 } 1689 1690 protected: 1691 bool 1692 DoExecute (const char *command, CommandReturnObject &result) override 1693 { 1694 // I am going to handle this by hand, because I don't want you to have to say: 1695 // "thread return -- -5". 1696 if (command[0] == '-' && command[1] == 'x') 1697 { 1698 if (command && command[2] != '\0') 1699 result.AppendWarning("Return values ignored when returning from user called expressions"); 1700 1701 Thread *thread = m_exe_ctx.GetThreadPtr(); 1702 Error error; 1703 error = thread->UnwindInnermostExpression(); 1704 if (!error.Success()) 1705 { 1706 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString()); 1707 result.SetStatus (eReturnStatusFailed); 1708 } 1709 else 1710 { 1711 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream()); 1712 if (success) 1713 { 1714 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ()); 1715 result.SetStatus (eReturnStatusSuccessFinishResult); 1716 } 1717 else 1718 { 1719 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression."); 1720 result.SetStatus (eReturnStatusFailed); 1721 } 1722 } 1723 return result.Succeeded(); 1724 } 1725 1726 ValueObjectSP return_valobj_sp; 1727 1728 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP(); 1729 uint32_t frame_idx = frame_sp->GetFrameIndex(); 1730 1731 if (frame_sp->IsInlined()) 1732 { 1733 result.AppendError("Don't know how to return from inlined frames."); 1734 result.SetStatus (eReturnStatusFailed); 1735 return false; 1736 } 1737 1738 if (command && command[0] != '\0') 1739 { 1740 Target *target = m_exe_ctx.GetTargetPtr(); 1741 EvaluateExpressionOptions options; 1742 1743 options.SetUnwindOnError(true); 1744 options.SetUseDynamic(eNoDynamicValues); 1745 1746 ExpressionResults exe_results = eExpressionSetupError; 1747 exe_results = target->EvaluateExpression (command, 1748 frame_sp.get(), 1749 return_valobj_sp, 1750 options); 1751 if (exe_results != eExpressionCompleted) 1752 { 1753 if (return_valobj_sp) 1754 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString()); 1755 else 1756 result.AppendErrorWithFormat("Unknown error evaluating result expression."); 1757 result.SetStatus (eReturnStatusFailed); 1758 return false; 1759 } 1760 } 1761 1762 Error error; 1763 ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); 1764 const bool broadcast = true; 1765 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast); 1766 if (!error.Success()) 1767 { 1768 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString()); 1769 result.SetStatus (eReturnStatusFailed); 1770 return false; 1771 } 1772 1773 result.SetStatus (eReturnStatusSuccessFinishResult); 1774 return true; 1775 } 1776 1777 CommandOptions m_options; 1778 }; 1779 1780 OptionDefinition 1781 CommandObjectThreadReturn::CommandOptions::g_option_table[] = 1782 { 1783 { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation."}, 1784 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 1785 }; 1786 1787 //------------------------------------------------------------------------- 1788 // CommandObjectThreadJump 1789 //------------------------------------------------------------------------- 1790 1791 class CommandObjectThreadJump : public CommandObjectParsed 1792 { 1793 public: 1794 class CommandOptions : public Options 1795 { 1796 public: 1797 CommandOptions (CommandInterpreter &interpreter) : 1798 Options (interpreter) 1799 { 1800 OptionParsingStarting (); 1801 } 1802 1803 ~CommandOptions() override = default; 1804 1805 void 1806 OptionParsingStarting () override 1807 { 1808 m_filenames.Clear(); 1809 m_line_num = 0; 1810 m_line_offset = 0; 1811 m_load_addr = LLDB_INVALID_ADDRESS; 1812 m_force = false; 1813 } 1814 1815 Error 1816 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1817 { 1818 bool success; 1819 const int short_option = m_getopt_table[option_idx].val; 1820 Error error; 1821 1822 switch (short_option) 1823 { 1824 case 'f': 1825 m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 1826 if (m_filenames.GetSize() > 1) 1827 return Error("only one source file expected."); 1828 break; 1829 case 'l': 1830 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 1831 if (!success || m_line_num == 0) 1832 return Error("invalid line number: '%s'.", option_arg); 1833 break; 1834 case 'b': 1835 m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success); 1836 if (!success) 1837 return Error("invalid line offset: '%s'.", option_arg); 1838 break; 1839 case 'a': 1840 { 1841 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 1842 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 1843 } 1844 break; 1845 case 'r': 1846 m_force = true; 1847 break; 1848 default: 1849 return Error("invalid short option character '%c'", short_option); 1850 } 1851 return error; 1852 } 1853 1854 const OptionDefinition* 1855 GetDefinitions () override 1856 { 1857 return g_option_table; 1858 } 1859 1860 FileSpecList m_filenames; 1861 uint32_t m_line_num; 1862 int32_t m_line_offset; 1863 lldb::addr_t m_load_addr; 1864 bool m_force; 1865 1866 static OptionDefinition g_option_table[]; 1867 }; 1868 1869 CommandObjectThreadJump (CommandInterpreter &interpreter) : 1870 CommandObjectParsed (interpreter, 1871 "thread jump", 1872 "Sets the program counter to a new address.", 1873 "thread jump", 1874 eCommandRequiresFrame | 1875 eCommandTryTargetAPILock | 1876 eCommandProcessMustBeLaunched | 1877 eCommandProcessMustBePaused ), 1878 m_options (interpreter) 1879 { 1880 } 1881 1882 ~CommandObjectThreadJump() override = default; 1883 1884 Options * 1885 GetOptions() override 1886 { 1887 return &m_options; 1888 } 1889 1890 protected: 1891 bool DoExecute (Args& args, CommandReturnObject &result) override 1892 { 1893 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext(); 1894 StackFrame *frame = m_exe_ctx.GetFramePtr(); 1895 Thread *thread = m_exe_ctx.GetThreadPtr(); 1896 Target *target = m_exe_ctx.GetTargetPtr(); 1897 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry); 1898 1899 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 1900 { 1901 // Use this address directly. 1902 Address dest = Address(m_options.m_load_addr); 1903 1904 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target); 1905 if (callAddr == LLDB_INVALID_ADDRESS) 1906 { 1907 result.AppendErrorWithFormat ("Invalid destination address."); 1908 result.SetStatus (eReturnStatusFailed); 1909 return false; 1910 } 1911 1912 if (!reg_ctx->SetPC (callAddr)) 1913 { 1914 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID()); 1915 result.SetStatus (eReturnStatusFailed); 1916 return false; 1917 } 1918 } 1919 else 1920 { 1921 // Pick either the absolute line, or work out a relative one. 1922 int32_t line = (int32_t)m_options.m_line_num; 1923 if (line == 0) 1924 line = sym_ctx.line_entry.line + m_options.m_line_offset; 1925 1926 // Try the current file, but override if asked. 1927 FileSpec file = sym_ctx.line_entry.file; 1928 if (m_options.m_filenames.GetSize() == 1) 1929 file = m_options.m_filenames.GetFileSpecAtIndex(0); 1930 1931 if (!file) 1932 { 1933 result.AppendErrorWithFormat ("No source file available for the current location."); 1934 result.SetStatus (eReturnStatusFailed); 1935 return false; 1936 } 1937 1938 std::string warnings; 1939 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings); 1940 1941 if (err.Fail()) 1942 { 1943 result.SetError (err); 1944 return false; 1945 } 1946 1947 if (!warnings.empty()) 1948 result.AppendWarning (warnings.c_str()); 1949 } 1950 1951 result.SetStatus (eReturnStatusSuccessFinishResult); 1952 return true; 1953 } 1954 1955 CommandOptions m_options; 1956 }; 1957 1958 OptionDefinition 1959 CommandObjectThreadJump::CommandOptions::g_option_table[] = 1960 { 1961 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 1962 "Specifies the source file to jump to."}, 1963 1964 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, 1965 "Specifies the line number to jump to."}, 1966 1967 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, 1968 "Jumps by a relative line offset from the current line."}, 1969 1970 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, 1971 "Jumps to a specific address."}, 1972 1973 { LLDB_OPT_SET_1| 1974 LLDB_OPT_SET_2| 1975 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,"Allows the PC to leave the current function."}, 1976 1977 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 1978 }; 1979 1980 //------------------------------------------------------------------------- 1981 // Next are the subcommands of CommandObjectMultiwordThreadPlan 1982 //------------------------------------------------------------------------- 1983 1984 //------------------------------------------------------------------------- 1985 // CommandObjectThreadPlanList 1986 //------------------------------------------------------------------------- 1987 1988 class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads 1989 { 1990 public: 1991 class CommandOptions : public Options 1992 { 1993 public: 1994 CommandOptions (CommandInterpreter &interpreter) : 1995 Options(interpreter) 1996 { 1997 // Keep default values of all options in one place: OptionParsingStarting () 1998 OptionParsingStarting (); 1999 } 2000 2001 ~CommandOptions() override = default; 2002 2003 Error 2004 SetOptionValue (uint32_t option_idx, const char *option_arg) override 2005 { 2006 Error error; 2007 const int short_option = m_getopt_table[option_idx].val; 2008 2009 switch (short_option) 2010 { 2011 case 'i': 2012 m_internal = true; 2013 break; 2014 case 'v': 2015 m_verbose = true; 2016 break; 2017 default: 2018 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 2019 break; 2020 } 2021 return error; 2022 } 2023 2024 void 2025 OptionParsingStarting () override 2026 { 2027 m_verbose = false; 2028 m_internal = false; 2029 } 2030 2031 const OptionDefinition* 2032 GetDefinitions () override 2033 { 2034 return g_option_table; 2035 } 2036 2037 // Options table: Required for subclasses of Options. 2038 2039 static OptionDefinition g_option_table[]; 2040 2041 // Instance variables to hold the values for command options. 2042 bool m_verbose; 2043 bool m_internal; 2044 }; 2045 2046 CommandObjectThreadPlanList (CommandInterpreter &interpreter) : 2047 CommandObjectIterateOverThreads(interpreter, 2048 "thread plan list", 2049 "Show thread plans for one or more threads. If no threads are specified, show the " 2050 "currently selected thread. Use the thread-index \"all\" to see all threads.", 2051 nullptr, 2052 eCommandRequiresProcess | 2053 eCommandRequiresThread | 2054 eCommandTryTargetAPILock | 2055 eCommandProcessMustBeLaunched | 2056 eCommandProcessMustBePaused ), 2057 m_options(interpreter) 2058 { 2059 } 2060 2061 ~CommandObjectThreadPlanList() override = default; 2062 2063 Options * 2064 GetOptions () override 2065 { 2066 return &m_options; 2067 } 2068 2069 protected: 2070 bool 2071 HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override 2072 { 2073 ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); 2074 if (!thread_sp) 2075 { 2076 result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid); 2077 result.SetStatus (eReturnStatusFailed); 2078 return false; 2079 } 2080 2081 Thread *thread = thread_sp.get(); 2082 2083 Stream &strm = result.GetOutputStream(); 2084 DescriptionLevel desc_level = eDescriptionLevelFull; 2085 if (m_options.m_verbose) 2086 desc_level = eDescriptionLevelVerbose; 2087 2088 thread->DumpThreadPlans (&strm, desc_level, m_options.m_internal, true); 2089 return true; 2090 } 2091 2092 CommandOptions m_options; 2093 }; 2094 2095 OptionDefinition 2096 CommandObjectThreadPlanList::CommandOptions::g_option_table[] = 2097 { 2098 { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans"}, 2099 { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans"}, 2100 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 2101 }; 2102 2103 class CommandObjectThreadPlanDiscard : public CommandObjectParsed 2104 { 2105 public: 2106 CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) : 2107 CommandObjectParsed(interpreter, 2108 "thread plan discard", 2109 "Discards thread plans up to and including the plan passed as the command argument." 2110 "Only user visible plans can be discarded, use the index from \"thread plan list\"" 2111 " without the \"-i\" argument.", 2112 nullptr, 2113 eCommandRequiresProcess | 2114 eCommandRequiresThread | 2115 eCommandTryTargetAPILock | 2116 eCommandProcessMustBeLaunched | 2117 eCommandProcessMustBePaused ) 2118 { 2119 CommandArgumentEntry arg; 2120 CommandArgumentData plan_index_arg; 2121 2122 // Define the first (and only) variant of this arg. 2123 plan_index_arg.arg_type = eArgTypeUnsignedInteger; 2124 plan_index_arg.arg_repetition = eArgRepeatPlain; 2125 2126 // There is only one variant this argument could be; put it into the argument entry. 2127 arg.push_back (plan_index_arg); 2128 2129 // Push the data for the first argument into the m_arguments vector. 2130 m_arguments.push_back (arg); 2131 } 2132 2133 ~CommandObjectThreadPlanDiscard() override = default; 2134 2135 bool 2136 DoExecute (Args& args, CommandReturnObject &result) override 2137 { 2138 Thread *thread = m_exe_ctx.GetThreadPtr(); 2139 if (args.GetArgumentCount() != 1) 2140 { 2141 result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.", 2142 args.GetArgumentCount()); 2143 result.SetStatus (eReturnStatusFailed); 2144 return false; 2145 } 2146 2147 bool success; 2148 uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success); 2149 if (!success) 2150 { 2151 result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.", 2152 args.GetArgumentAtIndex(0)); 2153 result.SetStatus (eReturnStatusFailed); 2154 return false; 2155 } 2156 2157 if (thread_plan_idx == 0) 2158 { 2159 result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan."); 2160 result.SetStatus (eReturnStatusFailed); 2161 return false; 2162 } 2163 2164 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) 2165 { 2166 result.SetStatus(eReturnStatusSuccessFinishNoResult); 2167 return true; 2168 } 2169 else 2170 { 2171 result.AppendErrorWithFormat("Could not find User thread plan with index %s.", 2172 args.GetArgumentAtIndex(0)); 2173 result.SetStatus (eReturnStatusFailed); 2174 return false; 2175 } 2176 } 2177 }; 2178 2179 //------------------------------------------------------------------------- 2180 // CommandObjectMultiwordThreadPlan 2181 //------------------------------------------------------------------------- 2182 2183 class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword 2184 { 2185 public: 2186 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) : 2187 CommandObjectMultiword (interpreter, 2188 "plan", 2189 "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.", 2190 "thread plan <subcommand> [<subcommand objects]") 2191 { 2192 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter))); 2193 LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter))); 2194 } 2195 2196 ~CommandObjectMultiwordThreadPlan() override = default; 2197 }; 2198 2199 //------------------------------------------------------------------------- 2200 // CommandObjectMultiwordThread 2201 //------------------------------------------------------------------------- 2202 2203 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : 2204 CommandObjectMultiword (interpreter, 2205 "thread", 2206 "A set of commands for operating on one or more threads within a running process.", 2207 "thread <subcommand> [<subcommand-options>]") 2208 { 2209 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); 2210 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); 2211 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter))); 2212 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter))); 2213 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter))); 2214 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); 2215 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); 2216 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter))); 2217 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2218 interpreter, 2219 "thread step-in", 2220 "Source level single step in specified thread (current thread, if none specified).", 2221 nullptr, 2222 eStepTypeInto, 2223 eStepScopeSource))); 2224 2225 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2226 interpreter, 2227 "thread step-out", 2228 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).", 2229 nullptr, 2230 eStepTypeOut, 2231 eStepScopeSource))); 2232 2233 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2234 interpreter, 2235 "thread step-over", 2236 "Source level single step in specified thread (current thread, if none specified), stepping over calls.", 2237 nullptr, 2238 eStepTypeOver, 2239 eStepScopeSource))); 2240 2241 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2242 interpreter, 2243 "thread step-inst", 2244 "Single step one instruction in specified thread (current thread, if none specified).", 2245 nullptr, 2246 eStepTypeTrace, 2247 eStepScopeInstruction))); 2248 2249 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2250 interpreter, 2251 "thread step-inst-over", 2252 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", 2253 nullptr, 2254 eStepTypeTraceOver, 2255 eStepScopeInstruction))); 2256 2257 LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2258 interpreter, 2259 "thread step-scripted", 2260 "Step as instructed by the script class passed in the -C option.", 2261 nullptr, 2262 eStepTypeScripted, 2263 eStepScopeSource))); 2264 2265 LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter))); 2266 } 2267 2268 CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default; 2269