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