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, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, 309 { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, 310 { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, 311 { 0, false, NULL, 0, 0, NULL, 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)) 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 // There is a race condition where this thread will return up the call stack to the main command handler 629 // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has 630 // a chance to call PushProcessIOHandler(). 631 process->SyncIOHandler(2000); 632 633 if (synchronous_execution) 634 { 635 StateType state = process->WaitForProcessToStop (NULL); 636 637 //EventSP event_sp; 638 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp); 639 //while (! StateIsStoppedState (state)) 640 // { 641 // state = process->WaitForStateChangedEvents (NULL, event_sp); 642 // } 643 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 644 result.SetDidChangeProcessState (true); 645 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 646 result.SetStatus (eReturnStatusSuccessFinishNoResult); 647 } 648 else 649 { 650 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 651 } 652 } 653 else 654 { 655 result.AppendError ("Couldn't find thread plan to implement step type."); 656 result.SetStatus (eReturnStatusFailed); 657 } 658 return result.Succeeded(); 659 } 660 661 protected: 662 StepType m_step_type; 663 StepScope m_step_scope; 664 CommandOptions m_options; 665 }; 666 667 static OptionEnumValueElement 668 g_tri_running_mode[] = 669 { 670 { eOnlyThisThread, "this-thread", "Run only this thread"}, 671 { eAllThreads, "all-threads", "Run all threads"}, 672 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"}, 673 { 0, NULL, NULL } 674 }; 675 676 static OptionEnumValueElement 677 g_duo_running_mode[] = 678 { 679 { eOnlyThisThread, "this-thread", "Run only this thread"}, 680 { eAllThreads, "all-threads", "Run all threads"}, 681 { 0, NULL, NULL } 682 }; 683 684 OptionDefinition 685 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = 686 { 687 { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."}, 688 { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, 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."}, 689 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."}, 690 { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."}, 691 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."}, 692 { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, 693 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 694 }; 695 696 697 //------------------------------------------------------------------------- 698 // CommandObjectThreadContinue 699 //------------------------------------------------------------------------- 700 701 class CommandObjectThreadContinue : public CommandObjectParsed 702 { 703 public: 704 705 CommandObjectThreadContinue (CommandInterpreter &interpreter) : 706 CommandObjectParsed (interpreter, 707 "thread continue", 708 "Continue execution of one or more threads in an active process.", 709 NULL, 710 eFlagRequiresThread | 711 eFlagTryTargetAPILock | 712 eFlagProcessMustBeLaunched | 713 eFlagProcessMustBePaused) 714 { 715 CommandArgumentEntry arg; 716 CommandArgumentData thread_idx_arg; 717 718 // Define the first (and only) variant of this arg. 719 thread_idx_arg.arg_type = eArgTypeThreadIndex; 720 thread_idx_arg.arg_repetition = eArgRepeatPlus; 721 722 // There is only one variant this argument could be; put it into the argument entry. 723 arg.push_back (thread_idx_arg); 724 725 // Push the data for the first argument into the m_arguments vector. 726 m_arguments.push_back (arg); 727 } 728 729 730 virtual 731 ~CommandObjectThreadContinue () 732 { 733 } 734 735 virtual bool 736 DoExecute (Args& command, CommandReturnObject &result) 737 { 738 bool synchronous_execution = m_interpreter.GetSynchronous (); 739 740 if (!m_interpreter.GetDebugger().GetSelectedTarget().get()) 741 { 742 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 743 result.SetStatus (eReturnStatusFailed); 744 return false; 745 } 746 747 Process *process = m_exe_ctx.GetProcessPtr(); 748 if (process == NULL) 749 { 750 result.AppendError ("no process exists. Cannot continue"); 751 result.SetStatus (eReturnStatusFailed); 752 return false; 753 } 754 755 StateType state = process->GetState(); 756 if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended)) 757 { 758 const size_t argc = command.GetArgumentCount(); 759 if (argc > 0) 760 { 761 // These two lines appear at the beginning of both blocks in 762 // this if..else, but that is because we need to release the 763 // lock before calling process->Resume below. 764 Mutex::Locker locker (process->GetThreadList().GetMutex()); 765 const uint32_t num_threads = process->GetThreadList().GetSize(); 766 std::vector<Thread *> resume_threads; 767 for (uint32_t i=0; i<argc; ++i) 768 { 769 bool success; 770 const int base = 0; 771 uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success); 772 if (success) 773 { 774 Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get(); 775 776 if (thread) 777 { 778 resume_threads.push_back(thread); 779 } 780 else 781 { 782 result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx); 783 result.SetStatus (eReturnStatusFailed); 784 return false; 785 } 786 } 787 else 788 { 789 result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i)); 790 result.SetStatus (eReturnStatusFailed); 791 return false; 792 } 793 } 794 795 if (resume_threads.empty()) 796 { 797 result.AppendError ("no valid thread indexes were specified"); 798 result.SetStatus (eReturnStatusFailed); 799 return false; 800 } 801 else 802 { 803 if (resume_threads.size() == 1) 804 result.AppendMessageWithFormat ("Resuming thread: "); 805 else 806 result.AppendMessageWithFormat ("Resuming threads: "); 807 808 for (uint32_t idx=0; idx<num_threads; ++idx) 809 { 810 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 811 std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread); 812 813 if (this_thread_pos != resume_threads.end()) 814 { 815 resume_threads.erase(this_thread_pos); 816 if (resume_threads.size() > 0) 817 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID()); 818 else 819 result.AppendMessageWithFormat ("%u ", thread->GetIndexID()); 820 821 const bool override_suspend = true; 822 thread->SetResumeState (eStateRunning, override_suspend); 823 } 824 else 825 { 826 thread->SetResumeState (eStateSuspended); 827 } 828 } 829 result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID()); 830 } 831 } 832 else 833 { 834 // These two lines appear at the beginning of both blocks in 835 // this if..else, but that is because we need to release the 836 // lock before calling process->Resume below. 837 Mutex::Locker locker (process->GetThreadList().GetMutex()); 838 const uint32_t num_threads = process->GetThreadList().GetSize(); 839 Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); 840 if (current_thread == NULL) 841 { 842 result.AppendError ("the process doesn't have a current thread"); 843 result.SetStatus (eReturnStatusFailed); 844 return false; 845 } 846 // Set the actions that the threads should each take when resuming 847 for (uint32_t idx=0; idx<num_threads; ++idx) 848 { 849 Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); 850 if (thread == current_thread) 851 { 852 result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID()); 853 const bool override_suspend = true; 854 thread->SetResumeState (eStateRunning, override_suspend); 855 } 856 else 857 { 858 thread->SetResumeState (eStateSuspended); 859 } 860 } 861 } 862 863 // We should not be holding the thread list lock when we do this. 864 Error error (process->Resume()); 865 if (error.Success()) 866 { 867 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 868 if (synchronous_execution) 869 { 870 state = process->WaitForProcessToStop (NULL); 871 872 result.SetDidChangeProcessState (true); 873 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 874 result.SetStatus (eReturnStatusSuccessFinishNoResult); 875 } 876 else 877 { 878 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 879 } 880 } 881 else 882 { 883 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString()); 884 result.SetStatus (eReturnStatusFailed); 885 } 886 } 887 else 888 { 889 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 890 StateAsCString(state)); 891 result.SetStatus (eReturnStatusFailed); 892 } 893 894 return result.Succeeded(); 895 } 896 897 }; 898 899 //------------------------------------------------------------------------- 900 // CommandObjectThreadUntil 901 //------------------------------------------------------------------------- 902 903 class CommandObjectThreadUntil : public CommandObjectParsed 904 { 905 public: 906 907 class CommandOptions : public Options 908 { 909 public: 910 uint32_t m_thread_idx; 911 uint32_t m_frame_idx; 912 913 CommandOptions (CommandInterpreter &interpreter) : 914 Options (interpreter), 915 m_thread_idx(LLDB_INVALID_THREAD_ID), 916 m_frame_idx(LLDB_INVALID_FRAME_ID) 917 { 918 // Keep default values of all options in one place: OptionParsingStarting () 919 OptionParsingStarting (); 920 } 921 922 virtual 923 ~CommandOptions () 924 { 925 } 926 927 virtual Error 928 SetOptionValue (uint32_t option_idx, const char *option_arg) 929 { 930 Error error; 931 const int short_option = m_getopt_table[option_idx].val; 932 933 switch (short_option) 934 { 935 case 't': 936 { 937 m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32); 938 if (m_thread_idx == LLDB_INVALID_INDEX32) 939 { 940 error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg); 941 } 942 } 943 break; 944 case 'f': 945 { 946 m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID); 947 if (m_frame_idx == LLDB_INVALID_FRAME_ID) 948 { 949 error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg); 950 } 951 } 952 break; 953 case 'm': 954 { 955 OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 956 lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error); 957 958 if (error.Success()) 959 { 960 if (run_mode == eAllThreads) 961 m_stop_others = false; 962 else 963 m_stop_others = true; 964 } 965 } 966 break; 967 default: 968 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 969 break; 970 971 } 972 return error; 973 } 974 975 void 976 OptionParsingStarting () 977 { 978 m_thread_idx = LLDB_INVALID_THREAD_ID; 979 m_frame_idx = 0; 980 m_stop_others = false; 981 } 982 983 const OptionDefinition* 984 GetDefinitions () 985 { 986 return g_option_table; 987 } 988 989 uint32_t m_step_thread_idx; 990 bool m_stop_others; 991 992 // Options table: Required for subclasses of Options. 993 994 static OptionDefinition g_option_table[]; 995 996 // Instance variables to hold the values for command options. 997 }; 998 999 CommandObjectThreadUntil (CommandInterpreter &interpreter) : 1000 CommandObjectParsed (interpreter, 1001 "thread until", 1002 "Run the current or specified thread until it reaches a given line number or leaves the current function.", 1003 NULL, 1004 eFlagRequiresThread | 1005 eFlagTryTargetAPILock | 1006 eFlagProcessMustBeLaunched | 1007 eFlagProcessMustBePaused ), 1008 m_options (interpreter) 1009 { 1010 CommandArgumentEntry arg; 1011 CommandArgumentData line_num_arg; 1012 1013 // Define the first (and only) variant of this arg. 1014 line_num_arg.arg_type = eArgTypeLineNum; 1015 line_num_arg.arg_repetition = eArgRepeatPlain; 1016 1017 // There is only one variant this argument could be; put it into the argument entry. 1018 arg.push_back (line_num_arg); 1019 1020 // Push the data for the first argument into the m_arguments vector. 1021 m_arguments.push_back (arg); 1022 } 1023 1024 1025 virtual 1026 ~CommandObjectThreadUntil () 1027 { 1028 } 1029 1030 virtual 1031 Options * 1032 GetOptions () 1033 { 1034 return &m_options; 1035 } 1036 1037 protected: 1038 virtual bool 1039 DoExecute (Args& command, CommandReturnObject &result) 1040 { 1041 bool synchronous_execution = m_interpreter.GetSynchronous (); 1042 1043 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1044 if (target == NULL) 1045 { 1046 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 1047 result.SetStatus (eReturnStatusFailed); 1048 return false; 1049 } 1050 1051 Process *process = m_exe_ctx.GetProcessPtr(); 1052 if (process == NULL) 1053 { 1054 result.AppendError ("need a valid process to step"); 1055 result.SetStatus (eReturnStatusFailed); 1056 1057 } 1058 else 1059 { 1060 Thread *thread = NULL; 1061 uint32_t line_number; 1062 1063 if (command.GetArgumentCount() != 1) 1064 { 1065 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax()); 1066 result.SetStatus (eReturnStatusFailed); 1067 return false; 1068 } 1069 1070 line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); 1071 if (line_number == UINT32_MAX) 1072 { 1073 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); 1074 result.SetStatus (eReturnStatusFailed); 1075 return false; 1076 } 1077 1078 if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) 1079 { 1080 thread = process->GetThreadList().GetSelectedThread().get(); 1081 } 1082 else 1083 { 1084 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get(); 1085 } 1086 1087 if (thread == NULL) 1088 { 1089 const uint32_t num_threads = process->GetThreadList().GetSize(); 1090 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 1091 m_options.m_thread_idx, 1092 num_threads); 1093 result.SetStatus (eReturnStatusFailed); 1094 return false; 1095 } 1096 1097 const bool abort_other_plans = false; 1098 1099 StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get(); 1100 if (frame == NULL) 1101 { 1102 1103 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", 1104 m_options.m_frame_idx, 1105 m_options.m_thread_idx); 1106 result.SetStatus (eReturnStatusFailed); 1107 return false; 1108 } 1109 1110 ThreadPlanSP new_plan_sp; 1111 1112 if (frame->HasDebugInformation ()) 1113 { 1114 // Finally we got here... Translate the given line number to a bunch of addresses: 1115 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit)); 1116 LineTable *line_table = NULL; 1117 if (sc.comp_unit) 1118 line_table = sc.comp_unit->GetLineTable(); 1119 1120 if (line_table == NULL) 1121 { 1122 result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n", 1123 m_options.m_frame_idx, m_options.m_thread_idx); 1124 result.SetStatus (eReturnStatusFailed); 1125 return false; 1126 } 1127 1128 LineEntry function_start; 1129 uint32_t index_ptr = 0, end_ptr; 1130 std::vector<addr_t> address_list; 1131 1132 // Find the beginning & end index of the 1133 AddressRange fun_addr_range = sc.function->GetAddressRange(); 1134 Address fun_start_addr = fun_addr_range.GetBaseAddress(); 1135 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr); 1136 1137 Address fun_end_addr(fun_start_addr.GetSection(), 1138 fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); 1139 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); 1140 1141 bool all_in_function = true; 1142 1143 while (index_ptr <= end_ptr) 1144 { 1145 LineEntry line_entry; 1146 const bool exact = false; 1147 index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry); 1148 if (index_ptr == UINT32_MAX) 1149 break; 1150 1151 addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); 1152 if (address != LLDB_INVALID_ADDRESS) 1153 { 1154 if (fun_addr_range.ContainsLoadAddress (address, target)) 1155 address_list.push_back (address); 1156 else 1157 all_in_function = false; 1158 } 1159 index_ptr++; 1160 } 1161 1162 if (address_list.size() == 0) 1163 { 1164 if (all_in_function) 1165 result.AppendErrorWithFormat ("No line entries matching until target.\n"); 1166 else 1167 result.AppendErrorWithFormat ("Until target outside of the current function.\n"); 1168 1169 result.SetStatus (eReturnStatusFailed); 1170 return false; 1171 } 1172 1173 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans, 1174 &address_list.front(), 1175 address_list.size(), 1176 m_options.m_stop_others, 1177 m_options.m_frame_idx); 1178 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint) 1179 // and other plans executed by the user (stepping around the breakpoint) and then a "continue" 1180 // will resume the original plan. 1181 new_plan_sp->SetIsMasterPlan (true); 1182 new_plan_sp->SetOkayToDiscard(false); 1183 } 1184 else 1185 { 1186 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", 1187 m_options.m_frame_idx, 1188 m_options.m_thread_idx); 1189 result.SetStatus (eReturnStatusFailed); 1190 return false; 1191 1192 } 1193 1194 process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); 1195 Error error (process->Resume ()); 1196 if (error.Success()) 1197 { 1198 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 1199 if (synchronous_execution) 1200 { 1201 StateType state = process->WaitForProcessToStop (NULL); 1202 1203 result.SetDidChangeProcessState (true); 1204 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 1205 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1206 } 1207 else 1208 { 1209 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 1210 } 1211 } 1212 else 1213 { 1214 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 1215 result.SetStatus (eReturnStatusFailed); 1216 } 1217 1218 } 1219 return result.Succeeded(); 1220 } 1221 1222 CommandOptions m_options; 1223 1224 }; 1225 1226 OptionDefinition 1227 CommandObjectThreadUntil::CommandOptions::g_option_table[] = 1228 { 1229 { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, 1230 { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, 1231 { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"}, 1232 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1233 }; 1234 1235 1236 //------------------------------------------------------------------------- 1237 // CommandObjectThreadSelect 1238 //------------------------------------------------------------------------- 1239 1240 class CommandObjectThreadSelect : public CommandObjectParsed 1241 { 1242 public: 1243 1244 CommandObjectThreadSelect (CommandInterpreter &interpreter) : 1245 CommandObjectParsed (interpreter, 1246 "thread select", 1247 "Select a thread as the currently active thread.", 1248 NULL, 1249 eFlagRequiresProcess | 1250 eFlagTryTargetAPILock | 1251 eFlagProcessMustBeLaunched | 1252 eFlagProcessMustBePaused ) 1253 { 1254 CommandArgumentEntry arg; 1255 CommandArgumentData thread_idx_arg; 1256 1257 // Define the first (and only) variant of this arg. 1258 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1259 thread_idx_arg.arg_repetition = eArgRepeatPlain; 1260 1261 // There is only one variant this argument could be; put it into the argument entry. 1262 arg.push_back (thread_idx_arg); 1263 1264 // Push the data for the first argument into the m_arguments vector. 1265 m_arguments.push_back (arg); 1266 } 1267 1268 1269 virtual 1270 ~CommandObjectThreadSelect () 1271 { 1272 } 1273 1274 protected: 1275 virtual bool 1276 DoExecute (Args& command, CommandReturnObject &result) 1277 { 1278 Process *process = m_exe_ctx.GetProcessPtr(); 1279 if (process == NULL) 1280 { 1281 result.AppendError ("no process"); 1282 result.SetStatus (eReturnStatusFailed); 1283 return false; 1284 } 1285 else if (command.GetArgumentCount() != 1) 1286 { 1287 result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1288 result.SetStatus (eReturnStatusFailed); 1289 return false; 1290 } 1291 1292 uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0); 1293 1294 Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); 1295 if (new_thread == NULL) 1296 { 1297 result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0)); 1298 result.SetStatus (eReturnStatusFailed); 1299 return false; 1300 } 1301 1302 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true); 1303 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1304 1305 return result.Succeeded(); 1306 } 1307 1308 }; 1309 1310 1311 //------------------------------------------------------------------------- 1312 // CommandObjectThreadList 1313 //------------------------------------------------------------------------- 1314 1315 class CommandObjectThreadList : public CommandObjectParsed 1316 { 1317 public: 1318 1319 1320 CommandObjectThreadList (CommandInterpreter &interpreter): 1321 CommandObjectParsed (interpreter, 1322 "thread list", 1323 "Show a summary of all current threads in a process.", 1324 "thread list", 1325 eFlagRequiresProcess | 1326 eFlagTryTargetAPILock | 1327 eFlagProcessMustBeLaunched | 1328 eFlagProcessMustBePaused ) 1329 { 1330 } 1331 1332 ~CommandObjectThreadList() 1333 { 1334 } 1335 1336 protected: 1337 bool 1338 DoExecute (Args& command, CommandReturnObject &result) 1339 { 1340 Stream &strm = result.GetOutputStream(); 1341 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1342 Process *process = m_exe_ctx.GetProcessPtr(); 1343 const bool only_threads_with_stop_reason = false; 1344 const uint32_t start_frame = 0; 1345 const uint32_t num_frames = 0; 1346 const uint32_t num_frames_with_source = 0; 1347 process->GetStatus(strm); 1348 process->GetThreadStatus (strm, 1349 only_threads_with_stop_reason, 1350 start_frame, 1351 num_frames, 1352 num_frames_with_source); 1353 return result.Succeeded(); 1354 } 1355 }; 1356 1357 //------------------------------------------------------------------------- 1358 // CommandObjectThreadInfo 1359 //------------------------------------------------------------------------- 1360 1361 class CommandObjectThreadInfo : public CommandObjectParsed 1362 { 1363 public: 1364 1365 CommandObjectThreadInfo (CommandInterpreter &interpreter) : 1366 CommandObjectParsed (interpreter, 1367 "thread info", 1368 "Show an extended summary of information about thread(s) in a process.", 1369 "thread info", 1370 eFlagRequiresProcess | 1371 eFlagTryTargetAPILock | 1372 eFlagProcessMustBeLaunched | 1373 eFlagProcessMustBePaused), 1374 m_options (interpreter) 1375 { 1376 CommandArgumentEntry arg; 1377 CommandArgumentData thread_idx_arg; 1378 1379 thread_idx_arg.arg_type = eArgTypeThreadIndex; 1380 thread_idx_arg.arg_repetition = eArgRepeatStar; 1381 1382 // There is only one variant this argument could be; put it into the argument entry. 1383 arg.push_back (thread_idx_arg); 1384 1385 // Push the data for the first argument into the m_arguments vector. 1386 m_arguments.push_back (arg); 1387 } 1388 1389 class CommandOptions : public Options 1390 { 1391 public: 1392 1393 CommandOptions (CommandInterpreter &interpreter) : 1394 Options (interpreter) 1395 { 1396 OptionParsingStarting (); 1397 } 1398 1399 void 1400 OptionParsingStarting () 1401 { 1402 m_json = false; 1403 } 1404 1405 virtual 1406 ~CommandOptions () 1407 { 1408 } 1409 1410 virtual Error 1411 SetOptionValue (uint32_t option_idx, const char *option_arg) 1412 { 1413 const int short_option = m_getopt_table[option_idx].val; 1414 Error error; 1415 1416 switch (short_option) 1417 { 1418 case 'j': 1419 m_json = true; 1420 break; 1421 1422 default: 1423 return Error("invalid short option character '%c'", short_option); 1424 1425 } 1426 return error; 1427 } 1428 1429 const OptionDefinition* 1430 GetDefinitions () 1431 { 1432 return g_option_table; 1433 } 1434 1435 bool m_json; 1436 1437 static OptionDefinition g_option_table[]; 1438 }; 1439 1440 virtual 1441 Options * 1442 GetOptions () 1443 { 1444 return &m_options; 1445 } 1446 1447 1448 virtual 1449 ~CommandObjectThreadInfo () 1450 { 1451 } 1452 1453 virtual bool 1454 DoExecute (Args& command, CommandReturnObject &result) 1455 { 1456 result.SetStatus (eReturnStatusSuccessFinishResult); 1457 Stream &strm = result.GetOutputStream(); 1458 1459 if (command.GetArgumentCount() == 0) 1460 { 1461 Thread *thread = m_exe_ctx.GetThreadPtr(); 1462 if (thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json)) 1463 { 1464 result.SetStatus (eReturnStatusSuccessFinishResult); 1465 } 1466 } 1467 else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) 1468 { 1469 Process *process = m_exe_ctx.GetProcessPtr(); 1470 uint32_t idx = 0; 1471 for (ThreadSP thread_sp : process->Threads()) 1472 { 1473 if (idx != 0) 1474 result.AppendMessage(""); 1475 if (!thread_sp->GetDescription (strm, eDescriptionLevelFull, m_options.m_json)) 1476 { 1477 result.AppendErrorWithFormat ("error displaying info for thread: \"0x%4.4x\"\n", idx); 1478 result.SetStatus (eReturnStatusFailed); 1479 return false; 1480 } 1481 ++idx; 1482 } 1483 } 1484 else 1485 { 1486 const size_t num_args = command.GetArgumentCount(); 1487 Process *process = m_exe_ctx.GetProcessPtr(); 1488 Mutex::Locker locker (process->GetThreadList().GetMutex()); 1489 std::vector<ThreadSP> thread_sps; 1490 1491 for (size_t i = 0; i < num_args; i++) 1492 { 1493 bool success; 1494 1495 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success); 1496 if (!success) 1497 { 1498 result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); 1499 result.SetStatus (eReturnStatusFailed); 1500 return false; 1501 } 1502 1503 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx)); 1504 1505 if (!thread_sps[i]) 1506 { 1507 result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); 1508 result.SetStatus (eReturnStatusFailed); 1509 return false; 1510 } 1511 1512 } 1513 1514 for (uint32_t i = 0; i < num_args; i++) 1515 { 1516 if (!thread_sps[i]->GetDescription (strm, eDescriptionLevelFull, m_options.m_json)) 1517 { 1518 result.AppendErrorWithFormat ("error displaying info for thread: \"%s\"\n", command.GetArgumentAtIndex(i)); 1519 result.SetStatus (eReturnStatusFailed); 1520 return false; 1521 } 1522 1523 if (i < num_args - 1) 1524 result.AppendMessage(""); 1525 } 1526 1527 } 1528 return result.Succeeded(); 1529 } 1530 1531 CommandOptions m_options; 1532 1533 }; 1534 1535 OptionDefinition 1536 CommandObjectThreadInfo::CommandOptions::g_option_table[] = 1537 { 1538 { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."}, 1539 1540 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1541 }; 1542 1543 1544 //------------------------------------------------------------------------- 1545 // CommandObjectThreadReturn 1546 //------------------------------------------------------------------------- 1547 1548 class CommandObjectThreadReturn : public CommandObjectRaw 1549 { 1550 public: 1551 class CommandOptions : public Options 1552 { 1553 public: 1554 1555 CommandOptions (CommandInterpreter &interpreter) : 1556 Options (interpreter), 1557 m_from_expression (false) 1558 { 1559 // Keep default values of all options in one place: OptionParsingStarting () 1560 OptionParsingStarting (); 1561 } 1562 1563 virtual 1564 ~CommandOptions () 1565 { 1566 } 1567 1568 virtual Error 1569 SetOptionValue (uint32_t option_idx, const char *option_arg) 1570 { 1571 Error error; 1572 const int short_option = m_getopt_table[option_idx].val; 1573 1574 switch (short_option) 1575 { 1576 case 'x': 1577 { 1578 bool success; 1579 bool tmp_value = Args::StringToBoolean (option_arg, false, &success); 1580 if (success) 1581 m_from_expression = tmp_value; 1582 else 1583 { 1584 error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg); 1585 } 1586 } 1587 break; 1588 default: 1589 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1590 break; 1591 1592 } 1593 return error; 1594 } 1595 1596 void 1597 OptionParsingStarting () 1598 { 1599 m_from_expression = false; 1600 } 1601 1602 const OptionDefinition* 1603 GetDefinitions () 1604 { 1605 return g_option_table; 1606 } 1607 1608 bool m_from_expression; 1609 1610 // Options table: Required for subclasses of Options. 1611 1612 static OptionDefinition g_option_table[]; 1613 1614 // Instance variables to hold the values for command options. 1615 }; 1616 1617 virtual 1618 Options * 1619 GetOptions () 1620 { 1621 return &m_options; 1622 } 1623 1624 CommandObjectThreadReturn (CommandInterpreter &interpreter) : 1625 CommandObjectRaw (interpreter, 1626 "thread return", 1627 "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value," 1628 " or with the -x option from the innermost function evaluation.", 1629 "thread return", 1630 eFlagRequiresFrame | 1631 eFlagTryTargetAPILock | 1632 eFlagProcessMustBeLaunched | 1633 eFlagProcessMustBePaused ), 1634 m_options (interpreter) 1635 { 1636 CommandArgumentEntry arg; 1637 CommandArgumentData expression_arg; 1638 1639 // Define the first (and only) variant of this arg. 1640 expression_arg.arg_type = eArgTypeExpression; 1641 expression_arg.arg_repetition = eArgRepeatOptional; 1642 1643 // There is only one variant this argument could be; put it into the argument entry. 1644 arg.push_back (expression_arg); 1645 1646 // Push the data for the first argument into the m_arguments vector. 1647 m_arguments.push_back (arg); 1648 1649 1650 } 1651 1652 ~CommandObjectThreadReturn() 1653 { 1654 } 1655 1656 protected: 1657 1658 bool DoExecute 1659 ( 1660 const char *command, 1661 CommandReturnObject &result 1662 ) 1663 { 1664 // I am going to handle this by hand, because I don't want you to have to say: 1665 // "thread return -- -5". 1666 if (command[0] == '-' && command[1] == 'x') 1667 { 1668 if (command && command[2] != '\0') 1669 result.AppendWarning("Return values ignored when returning from user called expressions"); 1670 1671 Thread *thread = m_exe_ctx.GetThreadPtr(); 1672 Error error; 1673 error = thread->UnwindInnermostExpression(); 1674 if (!error.Success()) 1675 { 1676 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString()); 1677 result.SetStatus (eReturnStatusFailed); 1678 } 1679 else 1680 { 1681 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream()); 1682 if (success) 1683 { 1684 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ()); 1685 result.SetStatus (eReturnStatusSuccessFinishResult); 1686 } 1687 else 1688 { 1689 result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression."); 1690 result.SetStatus (eReturnStatusFailed); 1691 } 1692 } 1693 return result.Succeeded(); 1694 } 1695 1696 ValueObjectSP return_valobj_sp; 1697 1698 StackFrameSP frame_sp = m_exe_ctx.GetFrameSP(); 1699 uint32_t frame_idx = frame_sp->GetFrameIndex(); 1700 1701 if (frame_sp->IsInlined()) 1702 { 1703 result.AppendError("Don't know how to return from inlined frames."); 1704 result.SetStatus (eReturnStatusFailed); 1705 return false; 1706 } 1707 1708 if (command && command[0] != '\0') 1709 { 1710 Target *target = m_exe_ctx.GetTargetPtr(); 1711 EvaluateExpressionOptions options; 1712 1713 options.SetUnwindOnError(true); 1714 options.SetUseDynamic(eNoDynamicValues); 1715 1716 ExpressionResults exe_results = eExpressionSetupError; 1717 exe_results = target->EvaluateExpression (command, 1718 frame_sp.get(), 1719 return_valobj_sp, 1720 options); 1721 if (exe_results != eExpressionCompleted) 1722 { 1723 if (return_valobj_sp) 1724 result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString()); 1725 else 1726 result.AppendErrorWithFormat("Unknown error evaluating result expression."); 1727 result.SetStatus (eReturnStatusFailed); 1728 return false; 1729 1730 } 1731 } 1732 1733 Error error; 1734 ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); 1735 const bool broadcast = true; 1736 error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast); 1737 if (!error.Success()) 1738 { 1739 result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString()); 1740 result.SetStatus (eReturnStatusFailed); 1741 return false; 1742 } 1743 1744 result.SetStatus (eReturnStatusSuccessFinishResult); 1745 return true; 1746 } 1747 1748 CommandOptions m_options; 1749 1750 }; 1751 OptionDefinition 1752 CommandObjectThreadReturn::CommandOptions::g_option_table[] = 1753 { 1754 { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."}, 1755 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1756 }; 1757 1758 //------------------------------------------------------------------------- 1759 // CommandObjectThreadJump 1760 //------------------------------------------------------------------------- 1761 1762 class CommandObjectThreadJump : public CommandObjectParsed 1763 { 1764 public: 1765 class CommandOptions : public Options 1766 { 1767 public: 1768 1769 CommandOptions (CommandInterpreter &interpreter) : 1770 Options (interpreter) 1771 { 1772 OptionParsingStarting (); 1773 } 1774 1775 void 1776 OptionParsingStarting () 1777 { 1778 m_filenames.Clear(); 1779 m_line_num = 0; 1780 m_line_offset = 0; 1781 m_load_addr = LLDB_INVALID_ADDRESS; 1782 m_force = false; 1783 } 1784 1785 virtual 1786 ~CommandOptions () 1787 { 1788 } 1789 1790 virtual Error 1791 SetOptionValue (uint32_t option_idx, const char *option_arg) 1792 { 1793 bool success; 1794 const int short_option = m_getopt_table[option_idx].val; 1795 Error error; 1796 1797 switch (short_option) 1798 { 1799 case 'f': 1800 m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 1801 if (m_filenames.GetSize() > 1) 1802 return Error("only one source file expected."); 1803 break; 1804 case 'l': 1805 m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success); 1806 if (!success || m_line_num == 0) 1807 return Error("invalid line number: '%s'.", option_arg); 1808 break; 1809 case 'b': 1810 m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success); 1811 if (!success) 1812 return Error("invalid line offset: '%s'.", option_arg); 1813 break; 1814 case 'a': 1815 { 1816 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 1817 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 1818 } 1819 break; 1820 case 'r': 1821 m_force = true; 1822 break; 1823 1824 default: 1825 return Error("invalid short option character '%c'", short_option); 1826 1827 } 1828 return error; 1829 } 1830 1831 const OptionDefinition* 1832 GetDefinitions () 1833 { 1834 return g_option_table; 1835 } 1836 1837 FileSpecList m_filenames; 1838 uint32_t m_line_num; 1839 int32_t m_line_offset; 1840 lldb::addr_t m_load_addr; 1841 bool m_force; 1842 1843 static OptionDefinition g_option_table[]; 1844 }; 1845 1846 virtual 1847 Options * 1848 GetOptions () 1849 { 1850 return &m_options; 1851 } 1852 1853 CommandObjectThreadJump (CommandInterpreter &interpreter) : 1854 CommandObjectParsed (interpreter, 1855 "thread jump", 1856 "Sets the program counter to a new address.", 1857 "thread jump", 1858 eFlagRequiresFrame | 1859 eFlagTryTargetAPILock | 1860 eFlagProcessMustBeLaunched | 1861 eFlagProcessMustBePaused ), 1862 m_options (interpreter) 1863 { 1864 } 1865 1866 ~CommandObjectThreadJump() 1867 { 1868 } 1869 1870 protected: 1871 1872 bool DoExecute (Args& args, CommandReturnObject &result) 1873 { 1874 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext(); 1875 StackFrame *frame = m_exe_ctx.GetFramePtr(); 1876 Thread *thread = m_exe_ctx.GetThreadPtr(); 1877 Target *target = m_exe_ctx.GetTargetPtr(); 1878 const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry); 1879 1880 if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 1881 { 1882 // Use this address directly. 1883 Address dest = Address(m_options.m_load_addr); 1884 1885 lldb::addr_t callAddr = dest.GetCallableLoadAddress (target); 1886 if (callAddr == LLDB_INVALID_ADDRESS) 1887 { 1888 result.AppendErrorWithFormat ("Invalid destination address."); 1889 result.SetStatus (eReturnStatusFailed); 1890 return false; 1891 } 1892 1893 if (!reg_ctx->SetPC (callAddr)) 1894 { 1895 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID()); 1896 result.SetStatus (eReturnStatusFailed); 1897 return false; 1898 } 1899 } 1900 else 1901 { 1902 // Pick either the absolute line, or work out a relative one. 1903 int32_t line = (int32_t)m_options.m_line_num; 1904 if (line == 0) 1905 line = sym_ctx.line_entry.line + m_options.m_line_offset; 1906 1907 // Try the current file, but override if asked. 1908 FileSpec file = sym_ctx.line_entry.file; 1909 if (m_options.m_filenames.GetSize() == 1) 1910 file = m_options.m_filenames.GetFileSpecAtIndex(0); 1911 1912 if (!file) 1913 { 1914 result.AppendErrorWithFormat ("No source file available for the current location."); 1915 result.SetStatus (eReturnStatusFailed); 1916 return false; 1917 } 1918 1919 std::string warnings; 1920 Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings); 1921 1922 if (err.Fail()) 1923 { 1924 result.SetError (err); 1925 return false; 1926 } 1927 1928 if (!warnings.empty()) 1929 result.AppendWarning (warnings.c_str()); 1930 } 1931 1932 result.SetStatus (eReturnStatusSuccessFinishResult); 1933 return true; 1934 } 1935 1936 CommandOptions m_options; 1937 }; 1938 OptionDefinition 1939 CommandObjectThreadJump::CommandOptions::g_option_table[] = 1940 { 1941 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 1942 "Specifies the source file to jump to."}, 1943 1944 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 1945 "Specifies the line number to jump to."}, 1946 1947 { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, 1948 "Jumps by a relative line offset from the current line."}, 1949 1950 { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, 1951 "Jumps to a specific address."}, 1952 1953 { LLDB_OPT_SET_1| 1954 LLDB_OPT_SET_2| 1955 LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."}, 1956 1957 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1958 }; 1959 1960 //------------------------------------------------------------------------- 1961 // CommandObjectMultiwordThread 1962 //------------------------------------------------------------------------- 1963 1964 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : 1965 CommandObjectMultiword (interpreter, 1966 "thread", 1967 "A set of commands for operating on one or more threads within a running process.", 1968 "thread <subcommand> [<subcommand-options>]") 1969 { 1970 LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); 1971 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); 1972 LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter))); 1973 LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter))); 1974 LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter))); 1975 LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); 1976 LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); 1977 LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter))); 1978 LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1979 interpreter, 1980 "thread step-in", 1981 "Source level single step in specified thread (current thread, if none specified).", 1982 NULL, 1983 eStepTypeInto, 1984 eStepScopeSource))); 1985 1986 LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1987 interpreter, 1988 "thread step-out", 1989 "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).", 1990 NULL, 1991 eStepTypeOut, 1992 eStepScopeSource))); 1993 1994 LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 1995 interpreter, 1996 "thread step-over", 1997 "Source level single step in specified thread (current thread, if none specified), stepping over calls.", 1998 NULL, 1999 eStepTypeOver, 2000 eStepScopeSource))); 2001 2002 LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2003 interpreter, 2004 "thread step-inst", 2005 "Single step one instruction in specified thread (current thread, if none specified).", 2006 NULL, 2007 eStepTypeTrace, 2008 eStepScopeInstruction))); 2009 2010 LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( 2011 interpreter, 2012 "thread step-inst-over", 2013 "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", 2014 NULL, 2015 eStepTypeTraceOver, 2016 eStepScopeInstruction))); 2017 } 2018 2019 CommandObjectMultiwordThread::~CommandObjectMultiwordThread () 2020 { 2021 } 2022 2023 2024