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