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