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