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