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