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