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 controlling plan (User level 530 // Plans should be controlling plans so that they can be interruptible). 531 // Then resume the process. 532 533 if (new_plan_sp) { 534 new_plan_sp->SetIsControllingPlan(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 controlling plans so they can be 1025 // interrupted 1026 // (e.g. by hitting a breakpoint) and other plans executed by the 1027 // user (stepping around the breakpoint) and then a "continue" will 1028 // resume the original plan. 1029 new_plan_sp->SetIsControllingPlan(true); 1030 new_plan_sp->SetOkayToDiscard(false); 1031 } else { 1032 result.SetError(new_plan_status); 1033 return false; 1034 } 1035 } else { 1036 result.AppendErrorWithFormat( 1037 "Frame index %u of thread %u has no debug information.\n", 1038 m_options.m_frame_idx, m_options.m_thread_idx); 1039 return false; 1040 } 1041 1042 process->GetThreadList().SetSelectedThreadByID(m_options.m_thread_idx); 1043 1044 StreamString stream; 1045 Status error; 1046 if (synchronous_execution) 1047 error = process->ResumeSynchronous(&stream); 1048 else 1049 error = process->Resume(); 1050 1051 if (error.Success()) { 1052 result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n", 1053 process->GetID()); 1054 if (synchronous_execution) { 1055 // If any state changed events had anything to say, add that to the 1056 // result 1057 if (stream.GetSize() > 0) 1058 result.AppendMessage(stream.GetString()); 1059 1060 result.SetDidChangeProcessState(true); 1061 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1062 } else { 1063 result.SetStatus(eReturnStatusSuccessContinuingNoResult); 1064 } 1065 } else { 1066 result.AppendErrorWithFormat("Failed to resume process: %s.\n", 1067 error.AsCString()); 1068 } 1069 } 1070 return result.Succeeded(); 1071 } 1072 1073 CommandOptions m_options; 1074 }; 1075 1076 // CommandObjectThreadSelect 1077 1078 class CommandObjectThreadSelect : public CommandObjectParsed { 1079 public: 1080 CommandObjectThreadSelect(CommandInterpreter &interpreter) 1081 : CommandObjectParsed(interpreter, "thread select", 1082 "Change the currently selected thread.", nullptr, 1083 eCommandRequiresProcess | eCommandTryTargetAPILock | 1084 eCommandProcessMustBeLaunched | 1085 eCommandProcessMustBePaused) { 1086 CommandArgumentEntry arg; 1087 CommandArgumentData thread_idx_arg; 1088 1089 // Define the first (and only) variant of this arg. 1090 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1091 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1092 1093 // There is only one variant this argument could be; put it into the 1094 // argument entry. 1095 arg.push_back(thread_idx_arg); 1096 1097 // Push the data for the first argument into the m_arguments vector. 1098 m_arguments.push_back(arg); 1099 } 1100 1101 ~CommandObjectThreadSelect() override = default; 1102 1103 void 1104 HandleArgumentCompletion(CompletionRequest &request, 1105 OptionElementVector &opt_element_vector) override { 1106 if (request.GetCursorIndex()) 1107 return; 1108 1109 CommandCompletions::InvokeCommonCompletionCallbacks( 1110 GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, 1111 request, nullptr); 1112 } 1113 1114 protected: 1115 bool DoExecute(Args &command, CommandReturnObject &result) override { 1116 Process *process = m_exe_ctx.GetProcessPtr(); 1117 if (process == nullptr) { 1118 result.AppendError("no process"); 1119 return false; 1120 } else if (command.GetArgumentCount() != 1) { 1121 result.AppendErrorWithFormat( 1122 "'%s' takes exactly one thread index argument:\nUsage: %s\n", 1123 m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1124 return false; 1125 } 1126 1127 uint32_t index_id; 1128 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) { 1129 result.AppendErrorWithFormat("Invalid thread index '%s'", 1130 command.GetArgumentAtIndex(0)); 1131 return false; 1132 } 1133 1134 Thread *new_thread = 1135 process->GetThreadList().FindThreadByIndexID(index_id).get(); 1136 if (new_thread == nullptr) { 1137 result.AppendErrorWithFormat("invalid thread #%s.\n", 1138 command.GetArgumentAtIndex(0)); 1139 return false; 1140 } 1141 1142 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true); 1143 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1144 1145 return result.Succeeded(); 1146 } 1147 }; 1148 1149 // CommandObjectThreadList 1150 1151 class CommandObjectThreadList : public CommandObjectParsed { 1152 public: 1153 CommandObjectThreadList(CommandInterpreter &interpreter) 1154 : CommandObjectParsed( 1155 interpreter, "thread list", 1156 "Show a summary of each thread in the current target process. " 1157 "Use 'settings set thread-format' to customize the individual " 1158 "thread listings.", 1159 "thread list", 1160 eCommandRequiresProcess | eCommandTryTargetAPILock | 1161 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {} 1162 1163 ~CommandObjectThreadList() override = default; 1164 1165 protected: 1166 bool DoExecute(Args &command, CommandReturnObject &result) override { 1167 Stream &strm = result.GetOutputStream(); 1168 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1169 Process *process = m_exe_ctx.GetProcessPtr(); 1170 const bool only_threads_with_stop_reason = false; 1171 const uint32_t start_frame = 0; 1172 const uint32_t num_frames = 0; 1173 const uint32_t num_frames_with_source = 0; 1174 process->GetStatus(strm); 1175 process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, 1176 num_frames, num_frames_with_source, false); 1177 return result.Succeeded(); 1178 } 1179 }; 1180 1181 // CommandObjectThreadInfo 1182 #define LLDB_OPTIONS_thread_info 1183 #include "CommandOptions.inc" 1184 1185 class CommandObjectThreadInfo : public CommandObjectIterateOverThreads { 1186 public: 1187 class CommandOptions : public Options { 1188 public: 1189 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 1190 1191 ~CommandOptions() override = default; 1192 1193 void OptionParsingStarting(ExecutionContext *execution_context) override { 1194 m_json_thread = false; 1195 m_json_stopinfo = false; 1196 } 1197 1198 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1199 ExecutionContext *execution_context) override { 1200 const int short_option = m_getopt_table[option_idx].val; 1201 Status error; 1202 1203 switch (short_option) { 1204 case 'j': 1205 m_json_thread = true; 1206 break; 1207 1208 case 's': 1209 m_json_stopinfo = true; 1210 break; 1211 1212 default: 1213 llvm_unreachable("Unimplemented option"); 1214 } 1215 return error; 1216 } 1217 1218 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1219 return llvm::makeArrayRef(g_thread_info_options); 1220 } 1221 1222 bool m_json_thread; 1223 bool m_json_stopinfo; 1224 }; 1225 1226 CommandObjectThreadInfo(CommandInterpreter &interpreter) 1227 : CommandObjectIterateOverThreads( 1228 interpreter, "thread info", 1229 "Show an extended summary of one or " 1230 "more threads. Defaults to the " 1231 "current thread.", 1232 "thread info", 1233 eCommandRequiresProcess | eCommandTryTargetAPILock | 1234 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), 1235 m_options() { 1236 m_add_return = false; 1237 } 1238 1239 ~CommandObjectThreadInfo() override = default; 1240 1241 void 1242 HandleArgumentCompletion(CompletionRequest &request, 1243 OptionElementVector &opt_element_vector) override { 1244 CommandCompletions::InvokeCommonCompletionCallbacks( 1245 GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, 1246 request, nullptr); 1247 } 1248 1249 Options *GetOptions() override { return &m_options; } 1250 1251 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { 1252 ThreadSP thread_sp = 1253 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); 1254 if (!thread_sp) { 1255 result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n", 1256 tid); 1257 return false; 1258 } 1259 1260 Thread *thread = thread_sp.get(); 1261 1262 Stream &strm = result.GetOutputStream(); 1263 if (!thread->GetDescription(strm, eDescriptionLevelFull, 1264 m_options.m_json_thread, 1265 m_options.m_json_stopinfo)) { 1266 result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n", 1267 thread->GetIndexID()); 1268 return false; 1269 } 1270 return true; 1271 } 1272 1273 CommandOptions m_options; 1274 }; 1275 1276 // CommandObjectThreadException 1277 1278 class CommandObjectThreadException : public CommandObjectIterateOverThreads { 1279 public: 1280 CommandObjectThreadException(CommandInterpreter &interpreter) 1281 : CommandObjectIterateOverThreads( 1282 interpreter, "thread exception", 1283 "Display the current exception object for a thread. Defaults to " 1284 "the current thread.", 1285 "thread exception", 1286 eCommandRequiresProcess | eCommandTryTargetAPILock | 1287 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {} 1288 1289 ~CommandObjectThreadException() override = default; 1290 1291 void 1292 HandleArgumentCompletion(CompletionRequest &request, 1293 OptionElementVector &opt_element_vector) override { 1294 CommandCompletions::InvokeCommonCompletionCallbacks( 1295 GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, 1296 request, nullptr); 1297 } 1298 1299 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { 1300 ThreadSP thread_sp = 1301 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); 1302 if (!thread_sp) { 1303 result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n", 1304 tid); 1305 return false; 1306 } 1307 1308 Stream &strm = result.GetOutputStream(); 1309 ValueObjectSP exception_object_sp = thread_sp->GetCurrentException(); 1310 if (exception_object_sp) { 1311 exception_object_sp->Dump(strm); 1312 } 1313 1314 ThreadSP exception_thread_sp = thread_sp->GetCurrentExceptionBacktrace(); 1315 if (exception_thread_sp && exception_thread_sp->IsValid()) { 1316 const uint32_t num_frames_with_source = 0; 1317 const bool stop_format = false; 1318 exception_thread_sp->GetStatus(strm, 0, UINT32_MAX, 1319 num_frames_with_source, stop_format); 1320 } 1321 1322 return true; 1323 } 1324 }; 1325 1326 // CommandObjectThreadReturn 1327 #define LLDB_OPTIONS_thread_return 1328 #include "CommandOptions.inc" 1329 1330 class CommandObjectThreadReturn : public CommandObjectRaw { 1331 public: 1332 class CommandOptions : public Options { 1333 public: 1334 CommandOptions() : Options() { 1335 // Keep default values of all options in one place: OptionParsingStarting 1336 // () 1337 OptionParsingStarting(nullptr); 1338 } 1339 1340 ~CommandOptions() override = default; 1341 1342 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1343 ExecutionContext *execution_context) override { 1344 Status error; 1345 const int short_option = m_getopt_table[option_idx].val; 1346 1347 switch (short_option) { 1348 case 'x': { 1349 bool success; 1350 bool tmp_value = 1351 OptionArgParser::ToBoolean(option_arg, false, &success); 1352 if (success) 1353 m_from_expression = tmp_value; 1354 else { 1355 error.SetErrorStringWithFormat( 1356 "invalid boolean value '%s' for 'x' option", 1357 option_arg.str().c_str()); 1358 } 1359 } break; 1360 default: 1361 llvm_unreachable("Unimplemented option"); 1362 } 1363 return error; 1364 } 1365 1366 void OptionParsingStarting(ExecutionContext *execution_context) override { 1367 m_from_expression = false; 1368 } 1369 1370 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1371 return llvm::makeArrayRef(g_thread_return_options); 1372 } 1373 1374 bool m_from_expression = false; 1375 1376 // Instance variables to hold the values for command options. 1377 }; 1378 1379 CommandObjectThreadReturn(CommandInterpreter &interpreter) 1380 : CommandObjectRaw(interpreter, "thread return", 1381 "Prematurely return from a stack frame, " 1382 "short-circuiting execution of newer frames " 1383 "and optionally yielding a specified value. Defaults " 1384 "to the exiting the current stack " 1385 "frame.", 1386 "thread return", 1387 eCommandRequiresFrame | eCommandTryTargetAPILock | 1388 eCommandProcessMustBeLaunched | 1389 eCommandProcessMustBePaused), 1390 m_options() { 1391 CommandArgumentEntry arg; 1392 CommandArgumentData expression_arg; 1393 1394 // Define the first (and only) variant of this arg. 1395 expression_arg.arg_type = eArgTypeExpression; 1396 expression_arg.arg_repetition = eArgRepeatOptional; 1397 1398 // There is only one variant this argument could be; put it into the 1399 // argument entry. 1400 arg.push_back(expression_arg); 1401 1402 // Push the data for the first argument into the m_arguments vector. 1403 m_arguments.push_back(arg); 1404 } 1405 1406 ~CommandObjectThreadReturn() override = default; 1407 1408 Options *GetOptions() override { return &m_options; } 1409 1410 protected: 1411 bool DoExecute(llvm::StringRef command, 1412 CommandReturnObject &result) override { 1413 // I am going to handle this by hand, because I don't want you to have to 1414 // say: 1415 // "thread return -- -5". 1416 if (command.startswith("-x")) { 1417 if (command.size() != 2U) 1418 result.AppendWarning("Return values ignored when returning from user " 1419 "called expressions"); 1420 1421 Thread *thread = m_exe_ctx.GetThreadPtr(); 1422 Status error; 1423 error = thread->UnwindInnermostExpression(); 1424 if (!error.Success()) { 1425 result.AppendErrorWithFormat("Unwinding expression failed - %s.", 1426 error.AsCString()); 1427 } else { 1428 bool success = 1429 thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream()); 1430 if (success) { 1431 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame()); 1432 result.SetStatus(eReturnStatusSuccessFinishResult); 1433 } else { 1434 result.AppendErrorWithFormat( 1435 "Could not select 0th frame after unwinding expression."); 1436 } 1437 } 1438 return result.Succeeded(); 1439 } 1440 1441 ValueObjectSP return_valobj_sp; 1442 1443 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP(); 1444 uint32_t frame_idx = frame_sp->GetFrameIndex(); 1445 1446 if (frame_sp->IsInlined()) { 1447 result.AppendError("Don't know how to return from inlined frames."); 1448 return false; 1449 } 1450 1451 if (!command.empty()) { 1452 Target *target = m_exe_ctx.GetTargetPtr(); 1453 EvaluateExpressionOptions options; 1454 1455 options.SetUnwindOnError(true); 1456 options.SetUseDynamic(eNoDynamicValues); 1457 1458 ExpressionResults exe_results = eExpressionSetupError; 1459 exe_results = target->EvaluateExpression(command, frame_sp.get(), 1460 return_valobj_sp, options); 1461 if (exe_results != eExpressionCompleted) { 1462 if (return_valobj_sp) 1463 result.AppendErrorWithFormat( 1464 "Error evaluating result expression: %s", 1465 return_valobj_sp->GetError().AsCString()); 1466 else 1467 result.AppendErrorWithFormat( 1468 "Unknown error evaluating result expression."); 1469 return false; 1470 } 1471 } 1472 1473 Status error; 1474 ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); 1475 const bool broadcast = true; 1476 error = thread_sp->ReturnFromFrame(frame_sp, return_valobj_sp, broadcast); 1477 if (!error.Success()) { 1478 result.AppendErrorWithFormat( 1479 "Error returning from frame %d of thread %d: %s.", frame_idx, 1480 thread_sp->GetIndexID(), error.AsCString()); 1481 return false; 1482 } 1483 1484 result.SetStatus(eReturnStatusSuccessFinishResult); 1485 return true; 1486 } 1487 1488 CommandOptions m_options; 1489 }; 1490 1491 // CommandObjectThreadJump 1492 #define LLDB_OPTIONS_thread_jump 1493 #include "CommandOptions.inc" 1494 1495 class CommandObjectThreadJump : public CommandObjectParsed { 1496 public: 1497 class CommandOptions : public Options { 1498 public: 1499 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 1500 1501 ~CommandOptions() override = default; 1502 1503 void OptionParsingStarting(ExecutionContext *execution_context) override { 1504 m_filenames.Clear(); 1505 m_line_num = 0; 1506 m_line_offset = 0; 1507 m_load_addr = LLDB_INVALID_ADDRESS; 1508 m_force = false; 1509 } 1510 1511 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1512 ExecutionContext *execution_context) override { 1513 const int short_option = m_getopt_table[option_idx].val; 1514 Status error; 1515 1516 switch (short_option) { 1517 case 'f': 1518 m_filenames.AppendIfUnique(FileSpec(option_arg)); 1519 if (m_filenames.GetSize() > 1) 1520 return Status("only one source file expected."); 1521 break; 1522 case 'l': 1523 if (option_arg.getAsInteger(0, m_line_num)) 1524 return Status("invalid line number: '%s'.", option_arg.str().c_str()); 1525 break; 1526 case 'b': 1527 if (option_arg.getAsInteger(0, m_line_offset)) 1528 return Status("invalid line offset: '%s'.", option_arg.str().c_str()); 1529 break; 1530 case 'a': 1531 m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg, 1532 LLDB_INVALID_ADDRESS, &error); 1533 break; 1534 case 'r': 1535 m_force = true; 1536 break; 1537 default: 1538 llvm_unreachable("Unimplemented option"); 1539 } 1540 return error; 1541 } 1542 1543 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1544 return llvm::makeArrayRef(g_thread_jump_options); 1545 } 1546 1547 FileSpecList m_filenames; 1548 uint32_t m_line_num; 1549 int32_t m_line_offset; 1550 lldb::addr_t m_load_addr; 1551 bool m_force; 1552 }; 1553 1554 CommandObjectThreadJump(CommandInterpreter &interpreter) 1555 : CommandObjectParsed( 1556 interpreter, "thread jump", 1557 "Sets the program counter to a new address.", "thread jump", 1558 eCommandRequiresFrame | eCommandTryTargetAPILock | 1559 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), 1560 m_options() {} 1561 1562 ~CommandObjectThreadJump() override = default; 1563 1564 Options *GetOptions() override { return &m_options; } 1565 1566 protected: 1567 bool DoExecute(Args &args, CommandReturnObject &result) override { 1568 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext(); 1569 StackFrame *frame = m_exe_ctx.GetFramePtr(); 1570 Thread *thread = m_exe_ctx.GetThreadPtr(); 1571 Target *target = m_exe_ctx.GetTargetPtr(); 1572 const SymbolContext &sym_ctx = 1573 frame->GetSymbolContext(eSymbolContextLineEntry); 1574 1575 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) { 1576 // Use this address directly. 1577 Address dest = Address(m_options.m_load_addr); 1578 1579 lldb::addr_t callAddr = dest.GetCallableLoadAddress(target); 1580 if (callAddr == LLDB_INVALID_ADDRESS) { 1581 result.AppendErrorWithFormat("Invalid destination address."); 1582 return false; 1583 } 1584 1585 if (!reg_ctx->SetPC(callAddr)) { 1586 result.AppendErrorWithFormat("Error changing PC value for thread %d.", 1587 thread->GetIndexID()); 1588 return false; 1589 } 1590 } else { 1591 // Pick either the absolute line, or work out a relative one. 1592 int32_t line = (int32_t)m_options.m_line_num; 1593 if (line == 0) 1594 line = sym_ctx.line_entry.line + m_options.m_line_offset; 1595 1596 // Try the current file, but override if asked. 1597 FileSpec file = sym_ctx.line_entry.file; 1598 if (m_options.m_filenames.GetSize() == 1) 1599 file = m_options.m_filenames.GetFileSpecAtIndex(0); 1600 1601 if (!file) { 1602 result.AppendErrorWithFormat( 1603 "No source file available for the current location."); 1604 return false; 1605 } 1606 1607 std::string warnings; 1608 Status err = thread->JumpToLine(file, line, m_options.m_force, &warnings); 1609 1610 if (err.Fail()) { 1611 result.SetError(err); 1612 return false; 1613 } 1614 1615 if (!warnings.empty()) 1616 result.AppendWarning(warnings.c_str()); 1617 } 1618 1619 result.SetStatus(eReturnStatusSuccessFinishResult); 1620 return true; 1621 } 1622 1623 CommandOptions m_options; 1624 }; 1625 1626 // Next are the subcommands of CommandObjectMultiwordThreadPlan 1627 1628 // CommandObjectThreadPlanList 1629 #define LLDB_OPTIONS_thread_plan_list 1630 #include "CommandOptions.inc" 1631 1632 class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads { 1633 public: 1634 class CommandOptions : public Options { 1635 public: 1636 CommandOptions() : Options() { 1637 // Keep default values of all options in one place: OptionParsingStarting 1638 // () 1639 OptionParsingStarting(nullptr); 1640 } 1641 1642 ~CommandOptions() override = default; 1643 1644 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1645 ExecutionContext *execution_context) override { 1646 const int short_option = m_getopt_table[option_idx].val; 1647 1648 switch (short_option) { 1649 case 'i': 1650 m_internal = true; 1651 break; 1652 case 't': 1653 lldb::tid_t tid; 1654 if (option_arg.getAsInteger(0, tid)) 1655 return Status("invalid tid: '%s'.", option_arg.str().c_str()); 1656 m_tids.push_back(tid); 1657 break; 1658 case 'u': 1659 m_unreported = false; 1660 break; 1661 case 'v': 1662 m_verbose = true; 1663 break; 1664 default: 1665 llvm_unreachable("Unimplemented option"); 1666 } 1667 return {}; 1668 } 1669 1670 void OptionParsingStarting(ExecutionContext *execution_context) override { 1671 m_verbose = false; 1672 m_internal = false; 1673 m_unreported = true; // The variable is "skip unreported" and we want to 1674 // skip unreported by default. 1675 m_tids.clear(); 1676 } 1677 1678 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1679 return llvm::makeArrayRef(g_thread_plan_list_options); 1680 } 1681 1682 // Instance variables to hold the values for command options. 1683 bool m_verbose; 1684 bool m_internal; 1685 bool m_unreported; 1686 std::vector<lldb::tid_t> m_tids; 1687 }; 1688 1689 CommandObjectThreadPlanList(CommandInterpreter &interpreter) 1690 : CommandObjectIterateOverThreads( 1691 interpreter, "thread plan list", 1692 "Show thread plans for one or more threads. If no threads are " 1693 "specified, show the " 1694 "current thread. Use the thread-index \"all\" to see all threads.", 1695 nullptr, 1696 eCommandRequiresProcess | eCommandRequiresThread | 1697 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | 1698 eCommandProcessMustBePaused), 1699 m_options() {} 1700 1701 ~CommandObjectThreadPlanList() override = default; 1702 1703 Options *GetOptions() override { return &m_options; } 1704 1705 bool DoExecute(Args &command, CommandReturnObject &result) override { 1706 // If we are reporting all threads, dispatch to the Process to do that: 1707 if (command.GetArgumentCount() == 0 && m_options.m_tids.empty()) { 1708 Stream &strm = result.GetOutputStream(); 1709 DescriptionLevel desc_level = m_options.m_verbose 1710 ? eDescriptionLevelVerbose 1711 : eDescriptionLevelFull; 1712 m_exe_ctx.GetProcessPtr()->DumpThreadPlans( 1713 strm, desc_level, m_options.m_internal, true, m_options.m_unreported); 1714 result.SetStatus(eReturnStatusSuccessFinishResult); 1715 return true; 1716 } else { 1717 // Do any TID's that the user may have specified as TID, then do any 1718 // Thread Indexes... 1719 if (!m_options.m_tids.empty()) { 1720 Process *process = m_exe_ctx.GetProcessPtr(); 1721 StreamString tmp_strm; 1722 for (lldb::tid_t tid : m_options.m_tids) { 1723 bool success = process->DumpThreadPlansForTID( 1724 tmp_strm, tid, eDescriptionLevelFull, m_options.m_internal, 1725 true /* condense_trivial */, m_options.m_unreported); 1726 // If we didn't find a TID, stop here and return an error. 1727 if (!success) { 1728 result.AppendError("Error dumping plans:"); 1729 result.AppendError(tmp_strm.GetString()); 1730 return false; 1731 } 1732 // Otherwise, add our data to the output: 1733 result.GetOutputStream() << tmp_strm.GetString(); 1734 } 1735 } 1736 return CommandObjectIterateOverThreads::DoExecute(command, result); 1737 } 1738 } 1739 1740 protected: 1741 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { 1742 // If we have already handled this from a -t option, skip it here. 1743 if (llvm::is_contained(m_options.m_tids, tid)) 1744 return true; 1745 1746 Process *process = m_exe_ctx.GetProcessPtr(); 1747 1748 Stream &strm = result.GetOutputStream(); 1749 DescriptionLevel desc_level = eDescriptionLevelFull; 1750 if (m_options.m_verbose) 1751 desc_level = eDescriptionLevelVerbose; 1752 1753 process->DumpThreadPlansForTID(strm, tid, desc_level, m_options.m_internal, 1754 true /* condense_trivial */, 1755 m_options.m_unreported); 1756 return true; 1757 } 1758 1759 CommandOptions m_options; 1760 }; 1761 1762 class CommandObjectThreadPlanDiscard : public CommandObjectParsed { 1763 public: 1764 CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter) 1765 : CommandObjectParsed(interpreter, "thread plan discard", 1766 "Discards thread plans up to and including the " 1767 "specified index (see 'thread plan list'.) " 1768 "Only user visible plans can be discarded.", 1769 nullptr, 1770 eCommandRequiresProcess | eCommandRequiresThread | 1771 eCommandTryTargetAPILock | 1772 eCommandProcessMustBeLaunched | 1773 eCommandProcessMustBePaused) { 1774 CommandArgumentEntry arg; 1775 CommandArgumentData plan_index_arg; 1776 1777 // Define the first (and only) variant of this arg. 1778 plan_index_arg.arg_type = eArgTypeUnsignedInteger; 1779 plan_index_arg.arg_repetition = eArgRepeatPlain; 1780 1781 // There is only one variant this argument could be; put it into the 1782 // argument entry. 1783 arg.push_back(plan_index_arg); 1784 1785 // Push the data for the first argument into the m_arguments vector. 1786 m_arguments.push_back(arg); 1787 } 1788 1789 ~CommandObjectThreadPlanDiscard() override = default; 1790 1791 void 1792 HandleArgumentCompletion(CompletionRequest &request, 1793 OptionElementVector &opt_element_vector) override { 1794 if (!m_exe_ctx.HasThreadScope() || request.GetCursorIndex()) 1795 return; 1796 1797 m_exe_ctx.GetThreadPtr()->AutoCompleteThreadPlans(request); 1798 } 1799 1800 bool DoExecute(Args &args, CommandReturnObject &result) override { 1801 Thread *thread = m_exe_ctx.GetThreadPtr(); 1802 if (args.GetArgumentCount() != 1) { 1803 result.AppendErrorWithFormat("Too many arguments, expected one - the " 1804 "thread plan index - but got %zu.", 1805 args.GetArgumentCount()); 1806 return false; 1807 } 1808 1809 uint32_t thread_plan_idx; 1810 if (!llvm::to_integer(args.GetArgumentAtIndex(0), thread_plan_idx)) { 1811 result.AppendErrorWithFormat( 1812 "Invalid thread index: \"%s\" - should be unsigned int.", 1813 args.GetArgumentAtIndex(0)); 1814 return false; 1815 } 1816 1817 if (thread_plan_idx == 0) { 1818 result.AppendErrorWithFormat( 1819 "You wouldn't really want me to discard the base thread plan."); 1820 return false; 1821 } 1822 1823 if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) { 1824 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1825 return true; 1826 } else { 1827 result.AppendErrorWithFormat( 1828 "Could not find User thread plan with index %s.", 1829 args.GetArgumentAtIndex(0)); 1830 return false; 1831 } 1832 } 1833 }; 1834 1835 class CommandObjectThreadPlanPrune : public CommandObjectParsed { 1836 public: 1837 CommandObjectThreadPlanPrune(CommandInterpreter &interpreter) 1838 : CommandObjectParsed(interpreter, "thread plan prune", 1839 "Removes any thread plans associated with " 1840 "currently unreported threads. " 1841 "Specify one or more TID's to remove, or if no " 1842 "TID's are provides, remove threads for all " 1843 "unreported threads", 1844 nullptr, 1845 eCommandRequiresProcess | 1846 eCommandTryTargetAPILock | 1847 eCommandProcessMustBeLaunched | 1848 eCommandProcessMustBePaused) { 1849 CommandArgumentEntry arg; 1850 CommandArgumentData tid_arg; 1851 1852 // Define the first (and only) variant of this arg. 1853 tid_arg.arg_type = eArgTypeThreadID; 1854 tid_arg.arg_repetition = eArgRepeatStar; 1855 1856 // There is only one variant this argument could be; put it into the 1857 // argument entry. 1858 arg.push_back(tid_arg); 1859 1860 // Push the data for the first argument into the m_arguments vector. 1861 m_arguments.push_back(arg); 1862 } 1863 1864 ~CommandObjectThreadPlanPrune() override = default; 1865 1866 bool DoExecute(Args &args, CommandReturnObject &result) override { 1867 Process *process = m_exe_ctx.GetProcessPtr(); 1868 1869 if (args.GetArgumentCount() == 0) { 1870 process->PruneThreadPlans(); 1871 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1872 return true; 1873 } 1874 1875 const size_t num_args = args.GetArgumentCount(); 1876 1877 std::lock_guard<std::recursive_mutex> guard( 1878 process->GetThreadList().GetMutex()); 1879 1880 for (size_t i = 0; i < num_args; i++) { 1881 lldb::tid_t tid; 1882 if (!llvm::to_integer(args.GetArgumentAtIndex(i), tid)) { 1883 result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", 1884 args.GetArgumentAtIndex(i)); 1885 return false; 1886 } 1887 if (!process->PruneThreadPlansForTID(tid)) { 1888 result.AppendErrorWithFormat("Could not find unreported tid: \"%s\"\n", 1889 args.GetArgumentAtIndex(i)); 1890 return false; 1891 } 1892 } 1893 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1894 return true; 1895 } 1896 }; 1897 1898 // CommandObjectMultiwordThreadPlan 1899 1900 class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword { 1901 public: 1902 CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) 1903 : CommandObjectMultiword( 1904 interpreter, "plan", 1905 "Commands for managing thread plans that control execution.", 1906 "thread plan <subcommand> [<subcommand objects]") { 1907 LoadSubCommand( 1908 "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter))); 1909 LoadSubCommand( 1910 "discard", 1911 CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter))); 1912 LoadSubCommand( 1913 "prune", 1914 CommandObjectSP(new CommandObjectThreadPlanPrune(interpreter))); 1915 } 1916 1917 ~CommandObjectMultiwordThreadPlan() override = default; 1918 }; 1919 1920 // Next are the subcommands of CommandObjectMultiwordTrace 1921 1922 // CommandObjectTraceExport 1923 1924 class CommandObjectTraceExport : public CommandObjectMultiword { 1925 public: 1926 CommandObjectTraceExport(CommandInterpreter &interpreter) 1927 : CommandObjectMultiword( 1928 interpreter, "trace thread export", 1929 "Commands for exporting traces of the threads in the current " 1930 "process to different formats.", 1931 "thread trace export <export-plugin> [<subcommand objects>]") { 1932 1933 unsigned i = 0; 1934 for (llvm::StringRef plugin_name = 1935 PluginManager::GetTraceExporterPluginNameAtIndex(i++); 1936 !plugin_name.empty(); 1937 plugin_name = PluginManager::GetTraceExporterPluginNameAtIndex(i++)) { 1938 if (ThreadTraceExportCommandCreator command_creator = 1939 PluginManager::GetThreadTraceExportCommandCreatorAtIndex(i)) { 1940 LoadSubCommand(plugin_name, command_creator(interpreter)); 1941 } 1942 } 1943 } 1944 }; 1945 1946 // CommandObjectTraceStart 1947 1948 class CommandObjectTraceStart : public CommandObjectTraceProxy { 1949 public: 1950 CommandObjectTraceStart(CommandInterpreter &interpreter) 1951 : CommandObjectTraceProxy( 1952 /*live_debug_session_only=*/true, interpreter, "thread trace start", 1953 "Start tracing threads with the corresponding trace " 1954 "plug-in for the current process.", 1955 "thread trace start [<trace-options>]") {} 1956 1957 protected: 1958 lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override { 1959 return trace.GetThreadTraceStartCommand(m_interpreter); 1960 } 1961 }; 1962 1963 // CommandObjectTraceStop 1964 1965 class CommandObjectTraceStop : public CommandObjectMultipleThreads { 1966 public: 1967 CommandObjectTraceStop(CommandInterpreter &interpreter) 1968 : CommandObjectMultipleThreads( 1969 interpreter, "thread trace stop", 1970 "Stop tracing threads, including the ones traced with the " 1971 "\"process trace start\" command." 1972 "Defaults to the current thread. Thread indices can be " 1973 "specified as arguments.\n Use the thread-index \"all\" to stop " 1974 "tracing " 1975 "for all existing threads.", 1976 "thread trace stop [<thread-index> <thread-index> ...]", 1977 eCommandRequiresProcess | eCommandTryTargetAPILock | 1978 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | 1979 eCommandProcessMustBeTraced) {} 1980 1981 ~CommandObjectTraceStop() override = default; 1982 1983 bool DoExecuteOnThreads(Args &command, CommandReturnObject &result, 1984 llvm::ArrayRef<lldb::tid_t> tids) override { 1985 ProcessSP process_sp = m_exe_ctx.GetProcessSP(); 1986 1987 TraceSP trace_sp = process_sp->GetTarget().GetTrace(); 1988 1989 if (llvm::Error err = trace_sp->Stop(tids)) 1990 result.AppendError(toString(std::move(err))); 1991 else 1992 result.SetStatus(eReturnStatusSuccessFinishResult); 1993 1994 return result.Succeeded(); 1995 } 1996 }; 1997 1998 // CommandObjectTraceDumpInstructions 1999 #define LLDB_OPTIONS_thread_trace_dump_instructions 2000 #include "CommandOptions.inc" 2001 2002 class CommandObjectTraceDumpInstructions 2003 : public CommandObjectIterateOverThreads { 2004 public: 2005 class CommandOptions : public Options { 2006 public: 2007 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 2008 2009 ~CommandOptions() override = default; 2010 2011 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2012 ExecutionContext *execution_context) override { 2013 Status error; 2014 const int short_option = m_getopt_table[option_idx].val; 2015 2016 switch (short_option) { 2017 case 'c': { 2018 int32_t count; 2019 if (option_arg.empty() || option_arg.getAsInteger(0, count) || 2020 count < 0) 2021 error.SetErrorStringWithFormat( 2022 "invalid integer value for option '%s'", 2023 option_arg.str().c_str()); 2024 else 2025 m_count = count; 2026 break; 2027 } 2028 case 's': { 2029 int32_t skip; 2030 if (option_arg.empty() || option_arg.getAsInteger(0, skip) || skip < 0) 2031 error.SetErrorStringWithFormat( 2032 "invalid integer value for option '%s'", 2033 option_arg.str().c_str()); 2034 else 2035 m_skip = skip; 2036 break; 2037 } 2038 case 'r': { 2039 m_raw = true; 2040 break; 2041 } 2042 case 'f': { 2043 m_forwards = true; 2044 break; 2045 } 2046 case 't': { 2047 m_show_tsc = true; 2048 break; 2049 } 2050 default: 2051 llvm_unreachable("Unimplemented option"); 2052 } 2053 return error; 2054 } 2055 2056 void OptionParsingStarting(ExecutionContext *execution_context) override { 2057 m_count = kDefaultCount; 2058 m_skip = 0; 2059 m_raw = false; 2060 m_forwards = false; 2061 m_show_tsc = false; 2062 } 2063 2064 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 2065 return llvm::makeArrayRef(g_thread_trace_dump_instructions_options); 2066 } 2067 2068 static const size_t kDefaultCount = 20; 2069 2070 // Instance variables to hold the values for command options. 2071 size_t m_count; 2072 size_t m_skip; 2073 bool m_raw; 2074 bool m_forwards; 2075 bool m_show_tsc; 2076 }; 2077 2078 CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter) 2079 : CommandObjectIterateOverThreads( 2080 interpreter, "thread trace dump instructions", 2081 "Dump the traced instructions for one or more threads. If no " 2082 "threads are specified, show the current thread. Use the " 2083 "thread-index \"all\" to see all threads.", 2084 nullptr, 2085 eCommandRequiresProcess | eCommandTryTargetAPILock | 2086 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | 2087 eCommandProcessMustBeTraced), 2088 m_options(), m_create_repeat_command_just_invoked(false) {} 2089 2090 ~CommandObjectTraceDumpInstructions() override = default; 2091 2092 Options *GetOptions() override { return &m_options; } 2093 2094 const char *GetRepeatCommand(Args ¤t_command_args, 2095 uint32_t index) override { 2096 current_command_args.GetCommandString(m_repeat_command); 2097 m_create_repeat_command_just_invoked = true; 2098 return m_repeat_command.c_str(); 2099 } 2100 2101 protected: 2102 bool DoExecute(Args &args, CommandReturnObject &result) override { 2103 if (!IsRepeatCommand()) 2104 m_dumpers.clear(); 2105 2106 bool status = CommandObjectIterateOverThreads::DoExecute(args, result); 2107 2108 m_create_repeat_command_just_invoked = false; 2109 return status; 2110 } 2111 2112 bool IsRepeatCommand() { 2113 return !m_repeat_command.empty() && !m_create_repeat_command_just_invoked; 2114 } 2115 2116 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { 2117 Stream &s = result.GetOutputStream(); 2118 2119 const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace(); 2120 ThreadSP thread_sp = 2121 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); 2122 2123 if (!m_dumpers.count(thread_sp->GetID())) { 2124 lldb::TraceCursorUP cursor_up = trace_sp->GetCursor(*thread_sp); 2125 // Set up the cursor and return the presentation index of the first 2126 // instruction to dump after skipping instructions. 2127 auto setUpCursor = [&]() { 2128 cursor_up->SetForwards(m_options.m_forwards); 2129 if (m_options.m_forwards) 2130 return cursor_up->Seek(m_options.m_skip, TraceCursor::SeekType::Set); 2131 return -cursor_up->Seek(-m_options.m_skip, TraceCursor::SeekType::End); 2132 }; 2133 2134 int initial_index = setUpCursor(); 2135 2136 auto dumper = std::make_unique<TraceInstructionDumper>( 2137 std::move(cursor_up), initial_index, m_options.m_raw, 2138 m_options.m_show_tsc); 2139 2140 // This happens when the seek value was more than the number of available 2141 // instructions. 2142 if (std::abs(initial_index) < (int)m_options.m_skip) 2143 dumper->SetNoMoreData(); 2144 2145 m_dumpers[thread_sp->GetID()] = std::move(dumper); 2146 } 2147 2148 m_dumpers[thread_sp->GetID()]->DumpInstructions(s, m_options.m_count); 2149 return true; 2150 } 2151 2152 CommandOptions m_options; 2153 2154 // Repeat command helpers 2155 std::string m_repeat_command; 2156 bool m_create_repeat_command_just_invoked; 2157 std::map<lldb::tid_t, std::unique_ptr<TraceInstructionDumper>> m_dumpers; 2158 }; 2159 2160 // CommandObjectTraceDumpInfo 2161 #define LLDB_OPTIONS_thread_trace_dump_info 2162 #include "CommandOptions.inc" 2163 2164 class CommandObjectTraceDumpInfo : public CommandObjectIterateOverThreads { 2165 public: 2166 class CommandOptions : public Options { 2167 public: 2168 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 2169 2170 ~CommandOptions() override = default; 2171 2172 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2173 ExecutionContext *execution_context) override { 2174 Status error; 2175 const int short_option = m_getopt_table[option_idx].val; 2176 2177 switch (short_option) { 2178 case 'v': { 2179 m_verbose = true; 2180 break; 2181 } 2182 default: 2183 llvm_unreachable("Unimplemented option"); 2184 } 2185 return error; 2186 } 2187 2188 void OptionParsingStarting(ExecutionContext *execution_context) override { 2189 m_verbose = false; 2190 } 2191 2192 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 2193 return llvm::makeArrayRef(g_thread_trace_dump_info_options); 2194 } 2195 2196 // Instance variables to hold the values for command options. 2197 bool m_verbose; 2198 }; 2199 2200 bool DoExecute(Args &command, CommandReturnObject &result) override { 2201 Target &target = m_exe_ctx.GetTargetRef(); 2202 result.GetOutputStream().Format("Trace technology: {0}\n", 2203 target.GetTrace()->GetPluginName()); 2204 return CommandObjectIterateOverThreads::DoExecute(command, result); 2205 } 2206 2207 CommandObjectTraceDumpInfo(CommandInterpreter &interpreter) 2208 : CommandObjectIterateOverThreads( 2209 interpreter, "thread trace dump info", 2210 "Dump the traced information for one or more threads. If no " 2211 "threads are specified, show the current thread. Use the " 2212 "thread-index \"all\" to see all threads.", 2213 nullptr, 2214 eCommandRequiresProcess | eCommandTryTargetAPILock | 2215 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | 2216 eCommandProcessMustBeTraced), 2217 m_options() {} 2218 2219 ~CommandObjectTraceDumpInfo() override = default; 2220 2221 Options *GetOptions() override { return &m_options; } 2222 2223 protected: 2224 bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { 2225 const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace(); 2226 ThreadSP thread_sp = 2227 m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); 2228 trace_sp->DumpTraceInfo(*thread_sp, result.GetOutputStream(), 2229 m_options.m_verbose); 2230 return true; 2231 } 2232 2233 CommandOptions m_options; 2234 }; 2235 2236 // CommandObjectMultiwordTraceDump 2237 class CommandObjectMultiwordTraceDump : public CommandObjectMultiword { 2238 public: 2239 CommandObjectMultiwordTraceDump(CommandInterpreter &interpreter) 2240 : CommandObjectMultiword( 2241 interpreter, "dump", 2242 "Commands for displaying trace information of the threads " 2243 "in the current process.", 2244 "thread trace dump <subcommand> [<subcommand objects>]") { 2245 LoadSubCommand( 2246 "instructions", 2247 CommandObjectSP(new CommandObjectTraceDumpInstructions(interpreter))); 2248 LoadSubCommand( 2249 "info", CommandObjectSP(new CommandObjectTraceDumpInfo(interpreter))); 2250 } 2251 ~CommandObjectMultiwordTraceDump() override = default; 2252 }; 2253 2254 // CommandObjectMultiwordTrace 2255 class CommandObjectMultiwordTrace : public CommandObjectMultiword { 2256 public: 2257 CommandObjectMultiwordTrace(CommandInterpreter &interpreter) 2258 : CommandObjectMultiword( 2259 interpreter, "trace", 2260 "Commands for operating on traces of the threads in the current " 2261 "process.", 2262 "thread trace <subcommand> [<subcommand objects>]") { 2263 LoadSubCommand("dump", CommandObjectSP(new CommandObjectMultiwordTraceDump( 2264 interpreter))); 2265 LoadSubCommand("start", 2266 CommandObjectSP(new CommandObjectTraceStart(interpreter))); 2267 LoadSubCommand("stop", 2268 CommandObjectSP(new CommandObjectTraceStop(interpreter))); 2269 LoadSubCommand("export", 2270 CommandObjectSP(new CommandObjectTraceExport(interpreter))); 2271 } 2272 2273 ~CommandObjectMultiwordTrace() override = default; 2274 }; 2275 2276 // CommandObjectMultiwordThread 2277 2278 CommandObjectMultiwordThread::CommandObjectMultiwordThread( 2279 CommandInterpreter &interpreter) 2280 : CommandObjectMultiword(interpreter, "thread", 2281 "Commands for operating on " 2282 "one or more threads in " 2283 "the current process.", 2284 "thread <subcommand> [<subcommand-options>]") { 2285 LoadSubCommand("backtrace", CommandObjectSP(new CommandObjectThreadBacktrace( 2286 interpreter))); 2287 LoadSubCommand("continue", 2288 CommandObjectSP(new CommandObjectThreadContinue(interpreter))); 2289 LoadSubCommand("list", 2290 CommandObjectSP(new CommandObjectThreadList(interpreter))); 2291 LoadSubCommand("return", 2292 CommandObjectSP(new CommandObjectThreadReturn(interpreter))); 2293 LoadSubCommand("jump", 2294 CommandObjectSP(new CommandObjectThreadJump(interpreter))); 2295 LoadSubCommand("select", 2296 CommandObjectSP(new CommandObjectThreadSelect(interpreter))); 2297 LoadSubCommand("until", 2298 CommandObjectSP(new CommandObjectThreadUntil(interpreter))); 2299 LoadSubCommand("info", 2300 CommandObjectSP(new CommandObjectThreadInfo(interpreter))); 2301 LoadSubCommand("exception", CommandObjectSP(new CommandObjectThreadException( 2302 interpreter))); 2303 LoadSubCommand("step-in", 2304 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( 2305 interpreter, "thread step-in", 2306 "Source level single step, stepping into calls. Defaults " 2307 "to current thread unless specified.", 2308 nullptr, eStepTypeInto, eStepScopeSource))); 2309 2310 LoadSubCommand("step-out", 2311 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( 2312 interpreter, "thread step-out", 2313 "Finish executing the current stack frame and stop after " 2314 "returning. Defaults to current thread unless specified.", 2315 nullptr, eStepTypeOut, eStepScopeSource))); 2316 2317 LoadSubCommand("step-over", 2318 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( 2319 interpreter, "thread step-over", 2320 "Source level single step, stepping over calls. Defaults " 2321 "to current thread unless specified.", 2322 nullptr, eStepTypeOver, eStepScopeSource))); 2323 2324 LoadSubCommand("step-inst", 2325 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( 2326 interpreter, "thread step-inst", 2327 "Instruction level single step, stepping into calls. " 2328 "Defaults to current thread unless specified.", 2329 nullptr, eStepTypeTrace, eStepScopeInstruction))); 2330 2331 LoadSubCommand("step-inst-over", 2332 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( 2333 interpreter, "thread step-inst-over", 2334 "Instruction level single step, stepping over calls. " 2335 "Defaults to current thread unless specified.", 2336 nullptr, eStepTypeTraceOver, eStepScopeInstruction))); 2337 2338 LoadSubCommand( 2339 "step-scripted", 2340 CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( 2341 interpreter, "thread step-scripted", 2342 "Step as instructed by the script class passed in the -C option. " 2343 "You can also specify a dictionary of key (-k) and value (-v) pairs " 2344 "that will be used to populate an SBStructuredData Dictionary, which " 2345 "will be passed to the constructor of the class implementing the " 2346 "scripted step. See the Python Reference for more details.", 2347 nullptr, eStepTypeScripted, eStepScopeSource))); 2348 2349 LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan( 2350 interpreter))); 2351 LoadSubCommand("trace", 2352 CommandObjectSP(new CommandObjectMultiwordTrace(interpreter))); 2353 } 2354 2355 CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default; 2356