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