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