1 //===-- StopInfo.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/Target/StopInfo.h" 11 12 // C Includes 13 // C++ Includes 14 #include <string> 15 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Core/Log.h" 19 #include "lldb/Breakpoint/Breakpoint.h" 20 #include "lldb/Breakpoint/BreakpointLocation.h" 21 #include "lldb/Breakpoint/StoppointCallbackContext.h" 22 #include "lldb/Breakpoint/Watchpoint.h" 23 #include "lldb/Core/Debugger.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Expression/ClangUserExpression.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Target/Thread.h" 28 #include "lldb/Target/ThreadPlan.h" 29 #include "lldb/Target/Process.h" 30 #include "lldb/Target/UnixSignals.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 StopInfo::StopInfo (Thread &thread, uint64_t value) : 36 m_thread (thread), 37 m_stop_id (thread.GetProcess()->GetStopID()), 38 m_resume_id (thread.GetProcess()->GetResumeID()), 39 m_value (value) 40 { 41 } 42 43 bool 44 StopInfo::IsValid () const 45 { 46 return m_thread.GetProcess()->GetStopID() == m_stop_id; 47 } 48 49 void 50 StopInfo::MakeStopInfoValid () 51 { 52 m_stop_id = m_thread.GetProcess()->GetStopID(); 53 m_resume_id = m_thread.GetProcess()->GetResumeID(); 54 } 55 56 bool 57 StopInfo::HasTargetRunSinceMe () 58 { 59 lldb::StateType ret_type = m_thread.GetProcess()->GetPrivateState(); 60 if (ret_type == eStateRunning) 61 { 62 return true; 63 } 64 else if (ret_type == eStateStopped) 65 { 66 // This is a little tricky. We want to count "run and stopped again before you could 67 // ask this question as a "TRUE" answer to HasTargetRunSinceMe. But we don't want to 68 // include any running of the target done for expressions. So we track both resumes, 69 // and resumes caused by expressions, and check if there are any resumes NOT caused 70 // by expressions. 71 72 uint32_t curr_resume_id = m_thread.GetProcess()->GetResumeID(); 73 uint32_t last_user_expression_id = m_thread.GetProcess()->GetLastUserExpressionResumeID (); 74 if (curr_resume_id == m_resume_id) 75 { 76 return false; 77 } 78 else if (curr_resume_id > last_user_expression_id) 79 { 80 return true; 81 } 82 } 83 return false; 84 } 85 86 //---------------------------------------------------------------------- 87 // StopInfoBreakpoint 88 //---------------------------------------------------------------------- 89 90 namespace lldb_private 91 { 92 class StopInfoBreakpoint : public StopInfo 93 { 94 public: 95 96 StopInfoBreakpoint (Thread &thread, break_id_t break_id) : 97 StopInfo (thread, break_id), 98 m_description(), 99 m_should_stop (false), 100 m_should_stop_is_valid (false), 101 m_should_perform_action (true), 102 m_address (LLDB_INVALID_ADDRESS) 103 { 104 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 105 if (bp_site_sp) 106 { 107 m_address = bp_site_sp->GetLoadAddress(); 108 } 109 } 110 111 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) : 112 StopInfo (thread, break_id), 113 m_description(), 114 m_should_stop (should_stop), 115 m_should_stop_is_valid (true), 116 m_should_perform_action (true), 117 m_address (LLDB_INVALID_ADDRESS) 118 { 119 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 120 if (bp_site_sp) 121 { 122 m_address = bp_site_sp->GetLoadAddress(); 123 } 124 } 125 126 virtual ~StopInfoBreakpoint () 127 { 128 } 129 130 virtual StopReason 131 GetStopReason () const 132 { 133 return eStopReasonBreakpoint; 134 } 135 136 virtual bool 137 ShouldStopSynchronous (Event *event_ptr) 138 { 139 if (!m_should_stop_is_valid) 140 { 141 // Only check once if we should stop at a breakpoint 142 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 143 if (bp_site_sp) 144 { 145 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 146 StoppointCallbackContext context (event_ptr, exe_ctx, true); 147 m_should_stop = bp_site_sp->ShouldStop (&context); 148 } 149 else 150 { 151 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 152 153 if (log) 154 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value); 155 156 m_should_stop = true; 157 } 158 m_should_stop_is_valid = true; 159 } 160 return m_should_stop; 161 } 162 163 bool 164 ShouldStop (Event *event_ptr) 165 { 166 // This just reports the work done by PerformAction or the synchronous stop. It should 167 // only ever get called after they have had a chance to run. 168 assert (m_should_stop_is_valid); 169 return m_should_stop; 170 } 171 172 virtual void 173 PerformAction (Event *event_ptr) 174 { 175 if (!m_should_perform_action) 176 return; 177 m_should_perform_action = false; 178 179 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 180 181 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 182 183 if (bp_site_sp) 184 { 185 size_t num_owners = bp_site_sp->GetNumberOfOwners(); 186 187 if (num_owners == 0) 188 { 189 m_should_stop = true; 190 } 191 else 192 { 193 // We go through each location, and test first its condition. If the condition says to stop, 194 // then we run the callback for that location. If that callback says to stop as well, then 195 // we set m_should_stop to true; we are going to stop. 196 // But we still want to give all the breakpoints whose conditions say we are going to stop a 197 // chance to run their callbacks. 198 // Of course if any callback restarts the target by putting "continue" in the callback, then 199 // we're going to restart, without running the rest of the callbacks. And in this case we will 200 // end up not stopping even if another location said we should stop. But that's better than not 201 // running all the callbacks. 202 203 m_should_stop = false; 204 205 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 206 StoppointCallbackContext context (event_ptr, exe_ctx, false); 207 208 for (size_t j = 0; j < num_owners; j++) 209 { 210 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j); 211 212 // First run the condition for the breakpoint. If that says we should stop, then we'll run 213 // the callback for the breakpoint. If the callback says we shouldn't stop that will win. 214 215 bool condition_says_stop = true; 216 if (bp_loc_sp->GetConditionText() != NULL) 217 { 218 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 219 // constructor errors up to the debugger's Async I/O. 220 221 ValueObjectSP result_valobj_sp; 222 223 ExecutionResults result_code; 224 ValueObjectSP result_value_sp; 225 const bool discard_on_error = true; 226 Error error; 227 result_code = ClangUserExpression::EvaluateWithError (exe_ctx, 228 eExecutionPolicyOnlyWhenNeeded, 229 lldb::eLanguageTypeUnknown, 230 ClangUserExpression::eResultTypeAny, 231 discard_on_error, 232 bp_loc_sp->GetConditionText(), 233 NULL, 234 result_value_sp, 235 error); 236 if (result_code == eExecutionCompleted) 237 { 238 if (result_value_sp) 239 { 240 Scalar scalar_value; 241 if (result_value_sp->ResolveValue (scalar_value)) 242 { 243 if (scalar_value.ULongLong(1) == 0) 244 condition_says_stop = false; 245 else 246 condition_says_stop = true; 247 if (log) 248 log->Printf("Condition successfully evaluated, result is %s.\n", 249 m_should_stop ? "true" : "false"); 250 } 251 else 252 { 253 condition_says_stop = true; 254 if (log) 255 log->Printf("Failed to get an integer result from the expression."); 256 } 257 } 258 } 259 else 260 { 261 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 262 StreamSP error_sp = debugger.GetAsyncErrorStream (); 263 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint "); 264 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 265 error_sp->Printf (": \"%s\"", 266 bp_loc_sp->GetConditionText()); 267 error_sp->EOL(); 268 const char *err_str = error.AsCString("<Unknown Error>"); 269 if (log) 270 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 271 272 error_sp->PutCString (err_str); 273 error_sp->EOL(); 274 error_sp->Flush(); 275 // If the condition fails to be parsed or run, we should stop. 276 condition_says_stop = true; 277 } 278 } 279 280 // If this location's condition says we should aren't going to stop, 281 // then don't run the callback for this location. 282 if (!condition_says_stop) 283 continue; 284 285 bool callback_says_stop; 286 287 // FIXME: For now the callbacks have to run in async mode - the first time we restart we need 288 // to get out of there. So set it here. 289 // When we figure out how to nest breakpoint hits then this will change. 290 291 Debugger &debugger = m_thread.CalculateTarget()->GetDebugger(); 292 bool old_async = debugger.GetAsyncExecution(); 293 debugger.SetAsyncExecution (true); 294 295 callback_says_stop = bp_loc_sp->InvokeCallback (&context); 296 297 debugger.SetAsyncExecution (old_async); 298 299 if (callback_says_stop) 300 m_should_stop = true; 301 302 // Also make sure that the callback hasn't continued the target. 303 // If it did, when we'll set m_should_start to false and get out of here. 304 if (HasTargetRunSinceMe ()) 305 { 306 m_should_stop = false; 307 break; 308 } 309 } 310 } 311 // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again. 312 m_should_stop_is_valid = true; 313 314 } 315 else 316 { 317 m_should_stop = true; 318 m_should_stop_is_valid = true; 319 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 320 321 if (log) 322 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value); 323 } 324 if (log) 325 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 326 } 327 328 virtual bool 329 ShouldNotify (Event *event_ptr) 330 { 331 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 332 if (bp_site_sp) 333 { 334 bool all_internal = true; 335 336 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++) 337 { 338 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) 339 { 340 all_internal = false; 341 break; 342 } 343 } 344 return all_internal == false; 345 } 346 return true; 347 } 348 349 virtual const char * 350 GetDescription () 351 { 352 if (m_description.empty()) 353 { 354 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value)); 355 if (bp_site_sp) 356 { 357 StreamString strm; 358 strm.Printf("breakpoint "); 359 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief); 360 m_description.swap (strm.GetString()); 361 } 362 else 363 { 364 StreamString strm; 365 if (m_address == LLDB_INVALID_ADDRESS) 366 strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value); 367 else 368 strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address); 369 m_description.swap (strm.GetString()); 370 } 371 } 372 return m_description.c_str(); 373 } 374 375 private: 376 std::string m_description; 377 bool m_should_stop; 378 bool m_should_stop_is_valid; 379 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions 380 // etc. behind the users backs, we need to make sure we only REALLY perform the action once. 381 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo, 382 // in case somebody deletes it between the time the StopInfo is made and the 383 // description is asked for. 384 }; 385 386 387 //---------------------------------------------------------------------- 388 // StopInfoWatchpoint 389 //---------------------------------------------------------------------- 390 391 class StopInfoWatchpoint : public StopInfo 392 { 393 public: 394 395 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) : 396 StopInfo(thread, watch_id), 397 m_description(), 398 m_should_stop(false), 399 m_should_stop_is_valid(false) 400 { 401 } 402 403 virtual ~StopInfoWatchpoint () 404 { 405 } 406 407 virtual StopReason 408 GetStopReason () const 409 { 410 return eStopReasonWatchpoint; 411 } 412 413 virtual bool 414 ShouldStop (Event *event_ptr) 415 { 416 // ShouldStop() method is idempotent and should not affect hit count. 417 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent() 418 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()-> 419 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()-> 420 // StopInfoWatchpoint::ShouldStop() and 421 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()-> 422 // StopInfoWatchpoint::PerformAction(). 423 if (m_should_stop_is_valid) 424 return m_should_stop; 425 426 WatchpointSP wp_sp = 427 m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue()); 428 if (wp_sp) 429 { 430 // Check if we should stop at a watchpoint. 431 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 432 StoppointCallbackContext context (event_ptr, exe_ctx, true); 433 m_should_stop = wp_sp->ShouldStop (&context); 434 } 435 else 436 { 437 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 438 439 if (log) 440 log->Printf ("Process::%s could not find watchpoint location id: %lld...", 441 __FUNCTION__, GetValue()); 442 443 m_should_stop = true; 444 } 445 m_should_stop_is_valid = true; 446 return m_should_stop; 447 } 448 449 // Perform any action that is associated with this stop. This is done as the 450 // Event is removed from the event queue. 451 virtual void 452 PerformAction (Event *event_ptr) 453 { 454 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 455 // We're going to calculate if we should stop or not in some way during the course of 456 // this code. Also by default we're going to stop, so set that here. 457 m_should_stop = true; 458 459 WatchpointSP wp_sp = 460 m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue()); 461 if (wp_sp) 462 { 463 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0)); 464 { 465 // check if this process is running on an architecture where watchpoints trigger 466 // before the associated instruction runs. if so, disable the WP, single-step and then 467 // re-enable the watchpoint 468 Process* process = exe_ctx.GetProcessPtr(); 469 if (process) 470 { 471 uint32_t num; bool wp_triggers_after; 472 if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success()) 473 { 474 if (!wp_triggers_after) 475 { 476 process->DisableWatchpoint(wp_sp.get()); 477 478 ThreadPlan *new_plan = m_thread.QueueThreadPlanForStepSingleInstruction(false, // step-over 479 false, // abort_other_plans 480 true); // stop_other_threads 481 new_plan->SetIsMasterPlan (true); 482 new_plan->SetOkayToDiscard (false); 483 process->GetThreadList().SetSelectedThreadByID (m_thread.GetID()); 484 process->Resume (); 485 process->WaitForProcessToStop (NULL); 486 process->GetThreadList().SetSelectedThreadByID (m_thread.GetID()); 487 MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above 488 489 process->EnableWatchpoint(wp_sp.get()); 490 } 491 } 492 } 493 } 494 StoppointCallbackContext context (event_ptr, exe_ctx, false); 495 bool stop_requested = wp_sp->InvokeCallback (&context); 496 // Also make sure that the callback hasn't continued the target. 497 // If it did, when we'll set m_should_start to false and get out of here. 498 if (HasTargetRunSinceMe ()) 499 m_should_stop = false; 500 501 if (m_should_stop && !stop_requested) 502 { 503 // We have been vetoed. 504 m_should_stop = false; 505 } 506 507 if (m_should_stop && wp_sp->GetConditionText() != NULL) 508 { 509 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 510 // constructor errors up to the debugger's Async I/O. 511 ExecutionResults result_code; 512 ValueObjectSP result_value_sp; 513 const bool discard_on_error = true; 514 Error error; 515 result_code = ClangUserExpression::EvaluateWithError (exe_ctx, 516 eExecutionPolicyAlways, 517 lldb::eLanguageTypeUnknown, 518 ClangUserExpression::eResultTypeAny, 519 discard_on_error, 520 wp_sp->GetConditionText(), 521 NULL, 522 result_value_sp, 523 error, 524 500000); 525 if (result_code == eExecutionCompleted) 526 { 527 if (result_value_sp) 528 { 529 Scalar scalar_value; 530 if (result_value_sp->ResolveValue (scalar_value)) 531 { 532 if (scalar_value.ULongLong(1) == 0) 533 { 534 // We have been vetoed. This takes precedence over querying 535 // the watchpoint whether it should stop (aka ignore count and 536 // friends). See also StopInfoWatchpoint::ShouldStop() as well 537 // as Process::ProcessEventData::DoOnRemoval(). 538 m_should_stop = false; 539 } 540 else 541 m_should_stop = true; 542 if (log) 543 log->Printf("Condition successfully evaluated, result is %s.\n", 544 m_should_stop ? "true" : "false"); 545 } 546 else 547 { 548 m_should_stop = true; 549 if (log) 550 log->Printf("Failed to get an integer result from the expression."); 551 } 552 } 553 } 554 else 555 { 556 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); 557 StreamSP error_sp = debugger.GetAsyncErrorStream (); 558 error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint "); 559 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief); 560 error_sp->Printf (": \"%s\"", 561 wp_sp->GetConditionText()); 562 error_sp->EOL(); 563 const char *err_str = error.AsCString("<Unknown Error>"); 564 if (log) 565 log->Printf("Error evaluating condition: \"%s\"\n", err_str); 566 567 error_sp->PutCString (err_str); 568 error_sp->EOL(); 569 error_sp->Flush(); 570 // If the condition fails to be parsed or run, we should stop. 571 m_should_stop = true; 572 } 573 } 574 } 575 else 576 { 577 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 578 579 if (log) 580 log->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value); 581 } 582 if (log) 583 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); 584 } 585 586 virtual const char * 587 GetDescription () 588 { 589 if (m_description.empty()) 590 { 591 StreamString strm; 592 strm.Printf("watchpoint %lli", m_value); 593 m_description.swap (strm.GetString()); 594 } 595 return m_description.c_str(); 596 } 597 598 private: 599 std::string m_description; 600 bool m_should_stop; 601 bool m_should_stop_is_valid; 602 }; 603 604 605 606 //---------------------------------------------------------------------- 607 // StopInfoUnixSignal 608 //---------------------------------------------------------------------- 609 610 class StopInfoUnixSignal : public StopInfo 611 { 612 public: 613 614 StopInfoUnixSignal (Thread &thread, int signo) : 615 StopInfo (thread, signo) 616 { 617 } 618 619 virtual ~StopInfoUnixSignal () 620 { 621 } 622 623 624 virtual StopReason 625 GetStopReason () const 626 { 627 return eStopReasonSignal; 628 } 629 630 virtual bool 631 ShouldStop (Event *event_ptr) 632 { 633 return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value); 634 } 635 636 637 // If should stop returns false, check if we should notify of this event 638 virtual bool 639 ShouldNotify (Event *event_ptr) 640 { 641 return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value); 642 } 643 644 645 virtual void 646 WillResume (lldb::StateType resume_state) 647 { 648 if (m_thread.GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false) 649 m_thread.SetResumeSignal(m_value); 650 } 651 652 virtual const char * 653 GetDescription () 654 { 655 if (m_description.empty()) 656 { 657 StreamString strm; 658 const char *signal_name = m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value); 659 if (signal_name) 660 strm.Printf("signal %s", signal_name); 661 else 662 strm.Printf("signal %lli", m_value); 663 m_description.swap (strm.GetString()); 664 } 665 return m_description.c_str(); 666 } 667 }; 668 669 //---------------------------------------------------------------------- 670 // StopInfoTrace 671 //---------------------------------------------------------------------- 672 673 class StopInfoTrace : public StopInfo 674 { 675 public: 676 677 StopInfoTrace (Thread &thread) : 678 StopInfo (thread, LLDB_INVALID_UID) 679 { 680 } 681 682 virtual ~StopInfoTrace () 683 { 684 } 685 686 virtual StopReason 687 GetStopReason () const 688 { 689 return eStopReasonTrace; 690 } 691 692 virtual const char * 693 GetDescription () 694 { 695 if (m_description.empty()) 696 return "trace"; 697 else 698 return m_description.c_str(); 699 } 700 }; 701 702 703 //---------------------------------------------------------------------- 704 // StopInfoException 705 //---------------------------------------------------------------------- 706 707 class StopInfoException : public StopInfo 708 { 709 public: 710 711 StopInfoException (Thread &thread, const char *description) : 712 StopInfo (thread, LLDB_INVALID_UID) 713 { 714 if (description) 715 SetDescription (description); 716 } 717 718 virtual 719 ~StopInfoException () 720 { 721 } 722 723 virtual StopReason 724 GetStopReason () const 725 { 726 return eStopReasonException; 727 } 728 729 virtual const char * 730 GetDescription () 731 { 732 if (m_description.empty()) 733 return "exception"; 734 else 735 return m_description.c_str(); 736 } 737 }; 738 739 740 //---------------------------------------------------------------------- 741 // StopInfoThreadPlan 742 //---------------------------------------------------------------------- 743 744 class StopInfoThreadPlan : public StopInfo 745 { 746 public: 747 748 StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp) : 749 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID), 750 m_plan_sp (plan_sp), 751 m_return_valobj_sp (return_valobj_sp) 752 { 753 } 754 755 virtual ~StopInfoThreadPlan () 756 { 757 } 758 759 virtual StopReason 760 GetStopReason () const 761 { 762 return eStopReasonPlanComplete; 763 } 764 765 virtual const char * 766 GetDescription () 767 { 768 if (m_description.empty()) 769 { 770 StreamString strm; 771 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief); 772 m_description.swap (strm.GetString()); 773 } 774 return m_description.c_str(); 775 } 776 777 ValueObjectSP 778 GetReturnValueObject() 779 { 780 return m_return_valobj_sp; 781 } 782 783 private: 784 ThreadPlanSP m_plan_sp; 785 ValueObjectSP m_return_valobj_sp; 786 }; 787 } // namespace lldb_private 788 789 StopInfoSP 790 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id) 791 { 792 return StopInfoSP (new StopInfoBreakpoint (thread, break_id)); 793 } 794 795 StopInfoSP 796 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop) 797 { 798 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop)); 799 } 800 801 StopInfoSP 802 StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id) 803 { 804 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id)); 805 } 806 807 StopInfoSP 808 StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo) 809 { 810 return StopInfoSP (new StopInfoUnixSignal (thread, signo)); 811 } 812 813 StopInfoSP 814 StopInfo::CreateStopReasonToTrace (Thread &thread) 815 { 816 return StopInfoSP (new StopInfoTrace (thread)); 817 } 818 819 StopInfoSP 820 StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp) 821 { 822 return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp)); 823 } 824 825 StopInfoSP 826 StopInfo::CreateStopReasonWithException (Thread &thread, const char *description) 827 { 828 return StopInfoSP (new StopInfoException (thread, description)); 829 } 830 831 ValueObjectSP 832 StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) 833 { 834 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete) 835 { 836 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get()); 837 return plan_stop_info->GetReturnValueObject(); 838 } 839 else 840 return ValueObjectSP(); 841 } 842